Open georgewahba opened 7 months ago
Hi!
This is work in progress, I try to catch up of this next week.
cool, will it work immidiatly after running berry and connecting to mqtt, or wil I have to do some different configuration
My target is that it will publish values like any other sensor in Tasmota and the values are also visible on the main page
cool, exactly what I want, I just want to publish it trough mqtt as well
I continued working and expanding on your code, this is what I got so far. I was able to solve all the errors it was giving like the one I had before, but I am not able to show any data on the homescreen nor sending anything over mqtt, this is the code as I have it now: `` import string import mqtt
class ESMR
var serialport
def init()
# gpio_rx:4 gpio_tx:5
self.serialport = serial(4, 5, 115200, serial.SERIAL_8N1)
mqtt.subscribe("your_subscribe_topic_here", self.process_esmr)
print("ESMR initialized")
end
def process_esmr(topic, idx, payload_s, payload_b)
print("Received MQTT message")
var serline = payload_s
var electricity_kw_using, electricity_kw_providing
var electricity_kwh_used_1, electricity_kwh_used_2
var electricity_kwh_provided_1, electricity_kwh_provided_2
var electricity_voltage_l1, electricity_voltage_l2, electricity_voltage_l3
var electricity_current_l1, electricity_current_l2, electricity_current_l3
var electricity_kw_using_l1, electricity_kw_using_l2, electricity_kw_using_l3
var electricity_kw_providing_l1, electricity_kw_providing_l2, electricity_kw_providing_l3
var gas_m3, gas_datetime
var value = string.split(serline,"(")[1]
value = string.split(value,")")[0]
value = string.split(value,"*")[0]
var value2 = string.split(serline,"(")[2]
value2 = string.split(value2,"*")[0]
print("Parsing values from received message")
if (string.count(serline, "1-0:1.8.1") == 1) electricity_kwh_used_1 = number(value)
if (string.count(serline, "1-0:2.8.1") == 1) electricity_kwh_provided_1 = number(value)
if (string.count(serline, "1-0:1.8.2") == 1) electricity_kwh_used_2 = number(value)
if (string.count(serline, "1-0:2.8.1") == 1) electricity_kwh_provided_1 = number(value)
if (string.count(serline, "1-0:2.8.2") == 1) electricity_kwh_provided_2 = number(value)
if (string.count(serline, "1-0:1.7.0") == 1) electricity_kw_using = number(value)
if (string.count(serline, "1-0:2.7.0") == 1) electricity_kw_providing = number(value)
if (string.count(serline, "1-0:21.7.0") == 1) electricity_kw_using_l1 = number(value)
if (string.count(serline, "1-0:41.7.0") == 1) electricity_kw_using_l2 = number(value)
if (string.count(serline, "1-0:61.7.0") == 1) electricity_kw_using_l3 = number(value)
if (string.count(serline, "1-0:22.7.0") == 1) electricity_kw_providing_l1 = number(value)
if (string.count(serline, "1-0:42.7.0") == 1) electricity_kw_providing_l2 = number(value)
if (string.count(serline, "1-0:62.7.0") == 1) electricity_kw_providing_l3 = number(value)
if (string.count(serline, "1-0:32.7.0") == 1) electricity_voltage_l1 = number(value)
if (string.count(serline, "1-0:52.7.0") == 1) electricity_voltage_l2 = number(value)
if (string.count(serline, "1-0:72.7.0") == 1) electricity_voltage_l3 = number(value)
if (string.count(serline, "1-0:31.7.0") == 1) electricity_current_l1 = number(value)
if (string.count(serline, "1-0:51.7.0") == 1) electricity_current_l2 = number(value)
if (string.count(serline, "1-0:71.7.0") == 1) electricity_current_l3 = number(value)
if (string.count(serline, "0-1:24.2.1") == 1) gas_datetime = value
if (string.count(serline, "0-1:24.2.1") == 1) gas_m3 = number(value2)
# Publish the parsed data through MQTT
print("Publishing parsed data through MQTT")
mqtt.publish("test", generate_output_msg(electricity_kwh_used_1, electricity_kwh_used_2, electricity_kwh_provided_1, electricity_kwh_provided_2, electricity_kw_using, electricity_kw_using_l1, electricity_kw_using_l2, electricity_kw_using_l3, electricity_kw_providing, electricity_kw_providing_l1, electricity_kw_providing_l2, electricity_kw_providing_l3, electricity_voltage_l1, electricity_voltage_l2, electricity_voltage_l3, electricity_current_l1, electricity_current_l2, electricity_current_l3, gas_m3, gas_datetime))
end
def generate_output_msg(electricity_kwh_used_1, electricity_kwh_used_2, electricity_kwh_provided_1, electricity_kwh_provided_2, electricity_kw_using, electricity_kw_using_l1, electricity_kw_using_l2, electricity_kw_using_l3, electricity_kw_providing, electricity_kw_providing_l1, electricity_kw_providing_l2, electricity_kw_providing_l3, electricity_voltage_l1, electricity_voltage_l2, electricity_voltage_l3, electricity_current_l1, electricity_current_l2, electricity_current_l3, gas_m3, gas_datetime)
return string.format(
"{s}electricity used 1{m}%.3f kWh{e}"..
"{s}electricity used 2{m}%.3f kWh{e}"..
"{s}electricity provided 1{m}%.3f kWh{e}"..
"{s}electricity provided 2{m}%.3f kWh{e}"..
"{s}electricity using{m}%.3f kW{e}"..
"{s}electricity using L1{m}%.3f kW{e}"..
"{s}electricity using L2{m}%.3f kW{e}"..
"{s}electricity using L3{m}%.3f kW{e}"..
"{s}electricity providing{m}%.3f kW{e}"..
"{s}electricity providing L1{m}%.3f kW{e}"..
"{s}electricity providing L2{m}%.3f kW{e}"..
"{s}electricity providing L3{m}%.3f kW{e}"..
"{s}electricity voltage L1{m}%.3f V{e}"..
"{s}electricity voltage L2{m}%.3f V{e}"..
"{s}electricity voltage L3{m}%.3f V{e}"..
"{s}electricity current L1{m}%.3f A{e}"..
"{s}electricity current L2{m}%.3f A{e}"..
"{s}electricity current L3{m}%.3f A{e}"..
"{s}gas{m}%.3f m3{e}"..
"{s}gas datetime{m}%s{e}",
electricity_kwh_used_1, electricity_kwh_used_2,
electricity_kwh_provided_1, electricity_kwh_provided_2,
electricity_kw_using, electricity_kw_using_l1, electricity_kw_using_l2, electricity_kw_using_l3,
electricity_kw_providing, electricity_kw_providing_l1, electricity_kw_providing_l2, electricity_kw_providing_l3,
electricity_voltage_l1, electricity_voltage_l2, electricity_voltage_l3,
electricity_current_l1, electricity_current_l2, electricity_current_l3,
gas_m3, gas_datetime)
end
def read_esmr()
var sermsg, serline
if (self.serialport.available() > 0)
sermsg += self.serialport.read().asstring()
var lastlineendpos = 0
var serialline = ""
for i:0..size(sermsg)-1
if ((sermsg[i] == 10) || (sermsg[i] == 13))
if (serialline != "")
print("Processing received line")
self.process_esmr("data", 0, serialline, bytes())
serialline = ""
lastlineendpos = i
else
serialline += sermsg[i]
end
if (i > 0)
sermsg = string.split(sermsg, i)[1]
end
end
end
#- trigger a read every second -#
def every_50ms()
read_esmr()
end
end
var esmr = ESMR()
tasmota.add_driver(esmr)
print("ESMR driver added")
``
when loading the very script is also down print anything so I don't know where it goes wrong
You can try debugging with adding print commands.
I also miss the tasmota.web_send_decimal command in your script for adding the values to the main webpage.
tasmota.web_send_decimal (message:string) -> nil
Adds an HTML fragment to the Web output, similar to web_send but converts decimal dot . to the locale decimal separator.
Can be called only in web_sensor() method of a registered driver (see cookbook). It is called at each main page refresh.
https://tasmota.github.io/docs/Berry/#tasmota-object
https://tasmota.github.io/docs/Berry-Cookbook/#step-by-step-approach (step 6)
There are several missing end
commands in the read_esmr function.
Imo this function is not working at all, also after adding the missing end commands.
Additional there are some missing self.
e.g. the read_esmr()
call inside the every_50ms function should be self.read_esmr()
.
I build something similar for a heater, based on this code, which works for me:
#-
- Read serial data from hargassner heater and report some data to a MQTT broker
-#
class hargassner
var serialport
var serialmsg
var kessel_ist, kessel_soll
var vorlauf_ist, vorlauf_soll
var aussen_mittel, aussen_gemessen
var rauchgas
var co2
var boiler
def init()
self.kessel_ist = 0
self.kessel_soll = 0
self.vorlauf_ist = 0
self.vorlauf_soll = 0
self.aussen_mittel = 0
self.aussen_gemessen = 0
self.rauchgas = 0
self.boiler = 0
self.co2 = 0
# gpio_rx:20 gpio_tx:21
self.serialport = serial(20, 21, 19200, serial.SERIAL_8N1)
self.serialmsg = ""
end
def process_esmr(line)
import string
print("Processing ...")
print(line)
if string.count(line, "pm", 0, 2) == 1
print("Found Datapackage")
print(line)
var dataList = string.split(string.split(line, "pm ")[1], " ")
print(str(dataList))
self.kessel_ist = number(dataList[2])
self.kessel_soll = number(dataList[13])
self.vorlauf_ist = number(dataList[6])
self.vorlauf_ist = number(dataList[8])
self.aussen_mittel = number(dataList[4])
self.aussen_gemessen = number(dataList[5])
self.rauchgas = number(dataList[3])
self.boiler = number(dataList[10])
self.co2 = number(dataList[1])
end
end
def read_esmr()
print("Function read_esmr called")
import string
if (self.serialport.available() > 0)
var lastlineendpos = 0
var serialline = ""
self.serialmsg += self.serialport.read().asstring()
for i:0..size(self.serialmsg)-1
if ((self.serialmsg[i] == string.char(10)) || (self.serialmsg[i] == string.char(13)))
if (serialline != "")
self.process_esmr(serialline)
end
serialline = ""
lastlineendpos = i
else
serialline += self.serialmsg[i]
end
end
if (lastlineendpos > 0)
self.serialmsg = string.split(self.serialmsg, lastlineendpos)[1]
end
end
end
#- trigger a read every second -#
def every_second()
self.read_esmr()
end
#- display sensor value in the web UI -#
def web_sensor()
import string
tasmota.web_send_decimal(string.format(
"{s}Kesseltemperatur (ist){m}%.2f°C{e}"..
"{s}Kesseltemperatur (soll) {m}%.2f°C{e}"..
"{s}Vorlauftemperatur (ist){m}%.2f°C{e}"..
"{s}Vorlauftemperatur (soll){m}%.2f°C{e}"..
"{s}Aussentemperatur (mittel){m}%.2f°C{e}"..
"{s}Aussentemperatur (gemessen){m}%.2f°C{e}"..
"{s}Rauchgastemperatur {m}%.2f°C{e}"..
"{s}Boilertemperatur {m}%.2f°C{e}"..
"{s}CO2{m}%.2f{e}",
self.kessel_ist, self.kessel_soll, self.vorlauf_ist, self.vorlauf_soll, self.aussen_mittel, self.aussen_gemessen, self.rauchgas, self.boiler, self.co2)
)
end
#- add sensor value to teleperiod -#
def json_append()
import string
tasmota.response_append(string.format(
",\"HARGASSNER\":{\"KesselIst\":%.2f,\"KesselSoll\":%.2f,\"VorlaufIst\":%.2f,"..
"\"VorlaufSoll\":%.2f,\"AussenMittel\":%.2f,\"AussenGemessen\":%.2f,\"Rauchgas\":%.2f,"..
"\"Boiler\":%.2f,\"CO2\":%.2f}",
self.kessel_ist, self.kessel_soll, self.vorlauf_ist, self.vorlauf_soll, self.aussen_mittel, self.aussen_gemessen, self.rauchgas, self.boiler, self.co2)
)
end
end
var hargassner_sm = hargassner()
tasmota.add_driver(hargassner_sm)
The MQTT message sending is currently not working in my setup, but this will be the next step.
ik heb deze informatie gekregen van de maker van de p1 meter, kan eventueel helpen:
I got it almost to work with this code, it prints out on the web ui and it sends trough mqtt only thing not working yet is that it doesn't display any values
class ESMR
var serialport
var electricity_kw_using, electricity_kw_providing
var electricity_kwh_used_1, electricity_kwh_used_2
var electricity_kwh_provided_1, electricity_kwh_provided_2
var electricity_voltage_l1, electricity_voltage_l2, electricity_voltage_l3
var electricity_current_l1, electricity_current_l2, electricity_current_l3
var electricity_kw_using_l1, electricity_kw_using_l2, electricity_kw_using_l3
var electricity_kw_providing_l1, electricity_kw_providing_l2, electricity_kw_providing_l3
var gas_m3, gas_datetime
var serialmsg
def init()
# Initialize the serial port with gpio_rx:10 gpio_tx:-1/21
self.serialport = serial(10, -1, 115200, serial.SERIAL_8N1)
self.serialmsg = ""
end
def process_emsr(serline)
# Extracting values from the serial line
import string
var parts = string.split(serline, "(")
if size(parts) < 2
return
end
var value = string.split(parts[1], ")")[0]
value = string.split(value, "*")[0]
var value2 = ""
if size(parts) > 2
value2 = string.split(parts[2], "*")[0]
end
# Parsing different types of values based on identifiers
if string.count(serline, "1-0:1.8.1") == 1
self.electricity_kwh_used_1 = number(value)
end
if string.count(serline, "1-0:1.8.2") == 1
self.electricity_kwh_used_2 = number(value)
end
if string.count(serline, "1-0:2.8.1") == 1
self.electricity_kwh_provided_1 = number(value)
end
if string.count(serline, "1-0:2.8.2") == 1
self.electricity_kwh_provided_2 = number(value)
end
if string.count(serline, "1-0:1.7.0") == 1
self.electricity_kw_using = number(value)
end
if string.count(serline, "1-0:2.7.0") == 1
self.electricity_kw_providing = number(value)
end
if string.count(serline, "1-0:21.7.0") == 1
self.electricity_kw_using_l1 = number(value)
end
if string.count(serline, "1-0:41.7.0") == 1
self.electricity_kw_using_l2 = number(value)
end
if string.count(serline, "1-0:61.7.0") == 1
self.electricity_kw_using_l3 = number(value)
end
if string.count(serline, "1-0:22.7.0") == 1
self.electricity_kw_providing_l1 = number(value)
end
if string.count(serline, "1-0:42.7.0") == 1
self.electricity_kw_providing_l2 = number(value)
end
if string.count(serline, "1-0:62.7.0") == 1
self.electricity_kw_providing_l3 = number(value)
end
if string.count(serline, "1-0:32.7.0") == 1
self.electricity_voltage_l1 = number(value)
end
if string.count(serline, "1-0:52.7.0") == 1
self.electricity_voltage_l2 = number(value)
end
if string.count(serline, "1-0:72.7.0") == 1
self.electricity_voltage_l3 = number(value)
end
if string.count(serline, "1-0:31.7.0") == 1
self.electricity_current_l1 = number(value)
end
if string.count(serline, "1-0:51.7.0") == 1
self.electricity_current_l2 = number(value)
end
if string.count(serline, "1-0:71.7.0") == 1
self.electricity_current_l3 = number(value)
end
if string.count(serline, "0-1:24.2.1") == 1
self.gas_datetime = value
self.gas_m3 = number(value2)
end
end
def read_esmr()
import string
var sermsg = self.serialmsg
if self.serialport.available() > 0
sermsg += self.serialport.read().asstring()
var lastlineendpos = 0
var serialline = ""
var i = 0
while i < size(sermsg)
if sermsg[i] == 10 || sermsg[i] == 13
if serialline != ""
print("Processing received line")
self.process_emsr(serialline)
end
serialline = ""
lastlineendpos = i
else
serialline += sermsg[i]
end
i += 1
end
if lastlineendpos > 0
self.serialmsg = string.split(sermsg, lastlineendpos + 1)[1]
end
end
end
# Trigger a read every 50ms
def every_50ms()
self.read_esmr()
end
# Display sensor value in the web UI
def web_sensor()
import string
var msg = string.format(
"{s}electricity used 1{m}%.3f kWh{e}"..
"{s}electricity used 2{m}%.3f kWh{e}"..
"{s}electricity provided 1{m}%.3f kWh{e}"..
"{s}electricity provided 2{m}%.3f kWh{e}"..
"{s}electricity using{m}%.3f kW{e}"..
"{s}electricity using L1{m}%.3f kW{e}"..
"{s}electricity using L2{m}%.3f kW{e}"..
"{s}electricity using L3{m}%.3f kW{e}"..
"{s}electricity providing{m}%.3f kW{e}"..
"{s}electricity providing L1{m}%.3f kW{e}"..
"{s}electricity providing L2{m}%.3f kW{e}"..
"{s}electricity providing L3{m}%.3f kW{e}"..
"{s}electricity voltage L1{m}%.3f V{e}"..
"{s}electricity voltage L2{m}%.3f V{e}"..
"{s}electricity voltage L3{m}%.3f V{e}"..
"{s}electricity current L1{m}%.3f A{e}"..
"{s}electricity current L2{m}%.3f A{e}"..
"{s}electricity current L3{m}%.3f A{e}"..
"{s}gas{m}%.3f m3{e}"..
"{s}gas datetime{m}%s{e}",
self.electricity_kwh_used_1, self.electricity_kwh_used_2,
self.electricity_kwh_provided_1, self.electricity_kwh_provided_2,
self.electricity_kw_using, self.electricity_kw_using_l1, self.electricity_kw_using_l2, self.electricity_kw_using_l3,
self.electricity_kw_providing, self.electricity_kw_providing_l1, self.electricity_kw_providing_l2, self.electricity_kw_providing_l3,
self.electricity_voltage_l1, self.electricity_voltage_l2, self.electricity_voltage_l3,
self.electricity_current_l1, self.electricity_current_l2, self.electricity_current_l3,
self.gas_m3, self.gas_datetime)
tasmota.web_send_decimal(msg)
end
# Add sensor value to teleperiod
def json_append()
import string
var msg = string.format(
",\"ESMR\":{\"EU1\":%.3f,\"EU2\":%.3f,\"EP1\":%.3f,\"EP2\":%.3f,"..
"\"EU\":%.3f,\"EUL1\":%.3f,\"EUL2\":%.3f,\"EUL3\":%.3f,"..
"\"EP\":%.3f,\"EPL1\":%.3f,\"EPL2\":%.3f,\"EPL3\":%.3f,"..
"\"EVL1\":%.3f,\"EVL2\":%.3f,\"EVL3\":%.3f,"..
"\"ECL1\":%.3f,\"ECL2\":%.3f,\"ECL3\":%.3f,"..
"\"G\":%.3f,\"GDT\":\"%s\"}",
self.electricity_kwh_used_1, self.electricity_kwh_used_2,
self.electricity_kwh_provided_1, self.electricity_kwh_provided_2,
self.electricity_kw_using, self.electricity_kw_using_l1, self.electricity_kw_using_l2, self.electricity_kw_using_l3,
self.electricity_kw_providing, self.electricity_kw_providing_l1, self.electricity_kw_providing_l2, self.electricity_kw_providing_l3,
self.electricity_voltage_l1, self.electricity_voltage_l2, self.electricity_voltage_l3,
self.electricity_current_l1, self.electricity_current_l2, self.electricity_current_l3,
self.gas_m3, self.gas_datetime)
tasmota.response_append(msg)
end
end
var esmr = ESMR()
tasmota.add_driver(esmr)
Thank you for all the work you did already. At the moment I have very little spare time to help out, but as soon you have things working, I will test your code and create a new commit.
I think you have to add self. web_sensor() and self.json_append() in the if statement of gas (because afaik that's the last dsmr value received):
if string.count(serline, "0-1:24.2.1") == 1
self.gas_datetime = value
self.gas_m3 = number(value2)
self.web_sensor();
self.json_append();
end
@georgewahba is this code working?
https://github.com/jeroenst/tasmota_scripts/issues/1#issuecomment-2124039391
If it works okay, I wil replace my code with it.
hello, I have the same smart stuff dongle as you and I am trying to use it with Tasmota, when I add the berry scrips as you it gives me an error, are you able to help me make my p1 meter to work