How can i integrate this device. It has jsons and modbus over tcp or rtu.
In my case i will use tcp.
here is the technical information side for this smartmeter
How can i integrate this device. It has jsons and modbus over tcp or rtu.
In my case i will use tcp.
here is the technical information side for this smartmeter
I found a solution for this.
You dont need Modbus or anything. You can just read the values over the API.
have you been able to build the integration? As I am looking for a solution as well … found this on another forum: https://www.photovoltaikforum.com/thread/128382-skript-zum-auslesen-des-b-control-energy-manager-em300/
perhaps it helps
I made a Flow in Node Red for now:
[
{
"id": "e53ffbf84b82e84f",
"type": "tab",
"label": "E300",
"disabled": false,
"info": "",
"env": []
},
{
"id": "d4bf36382884eb90",
"type": "inject",
"z": "e53ffbf84b82e84f",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 120,
"wires": [
[
"11b3881fbed7f9d0"
]
]
},
{
"id": "ce47f736cae31425",
"type": "function",
"z": "e53ffbf84b82e84f",
"name": "Get Cookie and set Password",
"func": "msg.payload = \"login=serialnumber&password=password\"\nmsg.headers = {};\nmsg.headers['Content-Type'] = 'application/x-www-form-urlencoded';\nmsg.headers['Cookie'] = 'PHPSESSID=' + msg.responseCookies.PHPSESSID.value;\nflow.set(\"cookie\", 'PHPSESSID=' + msg.responseCookies.PHPSESSID.value)\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 750,
"y": 100,
"wires": [
[
"87d1d0364f2106b9"
]
]
},
{
"id": "87d1d0364f2106b9",
"type": "http request",
"z": "e53ffbf84b82e84f",
"name": "",
"method": "POST",
"ret": "obj",
"paytoqs": "body",
"url": "http://192.168.251.23/start.php",
"tls": "",
"persist": true,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [
{
"keyType": "other",
"keyValue": "",
"valueType": "other",
"valueValue": ""
}
],
"x": 1010,
"y": 100,
"wires": [
[
"8069e70967110ac7",
"a85f2328603badb5"
]
]
},
{
"id": "394b6cca83f615a2",
"type": "http request",
"z": "e53ffbf84b82e84f",
"name": "",
"method": "POST",
"ret": "obj",
"paytoqs": "body",
"url": "http://192.168.251.23/start.php",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 490,
"y": 100,
"wires": [
[
"ce47f736cae31425"
]
]
},
{
"id": "11b3881fbed7f9d0",
"type": "switch",
"z": "e53ffbf84b82e84f",
"name": "",
"property": "cookie",
"propertyType": "flow",
"rules": [
{
"t": "istype",
"v": "undefined",
"vt": "undefined"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 310,
"y": 120,
"wires": [
[
"394b6cca83f615a2"
],
[
"2f048fbcc722d823"
]
]
},
{
"id": "8069e70967110ac7",
"type": "switch",
"z": "e53ffbf84b82e84f",
"name": "",
"property": "payload.authentication",
"propertyType": "msg",
"rules": [
{
"t": "true"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 1210,
"y": 160,
"wires": [
[
"11b3881fbed7f9d0"
],
[
"0581a67f211e0906"
]
]
},
{
"id": "0581a67f211e0906",
"type": "function",
"z": "e53ffbf84b82e84f",
"name": "function 1",
"func": "flow.set(\"cookie\", undefined)",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1360,
"y": 180,
"wires": [
[]
]
},
{
"id": "9e14ccccf92b9fc9",
"type": "http request",
"z": "e53ffbf84b82e84f",
"name": "",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "http://192.168.251.23/mum-webservice/data.php",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 790,
"y": 360,
"wires": [
[
"f06e8d2e7e113051",
"b07be4493e54fb89",
"e6467da9a12d0e39",
"7e7118bb762f0ffd",
"0675dcfc8c235226"
]
]
},
{
"id": "2f048fbcc722d823",
"type": "function",
"z": "e53ffbf84b82e84f",
"name": "Set Cookie",
"func": "msg.headers = {};\nmsg.headers['Cookie'] = flow.get(\"cookie\")\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 530,
"y": 360,
"wires": [
[
"9e14ccccf92b9fc9"
]
]
},
{
"id": "f06e8d2e7e113051",
"type": "debug",
"z": "e53ffbf84b82e84f",
"name": "debug 3",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1080,
"y": 240,
"wires": []
},
{
"id": "b07be4493e54fb89",
"type": "ha-sensor",
"z": "e53ffbf84b82e84f",
"name": "ActivePorwer+",
"entityConfig": "a9f7149c8d1f846d",
"version": 0,
"state": "payload['1-0:1.4.0*255']",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1100,
"y": 300,
"wires": [
[]
]
},
{
"id": "e6467da9a12d0e39",
"type": "ha-sensor",
"z": "e53ffbf84b82e84f",
"name": "Activeengery+",
"entityConfig": "7f5b702d206bc348",
"version": 0,
"state": "payload['1-0:1.8.0*255']",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1100,
"y": 360,
"wires": [
[]
]
},
{
"id": "7e7118bb762f0ffd",
"type": "ha-sensor",
"z": "e53ffbf84b82e84f",
"name": "Active power-",
"entityConfig": "fd242424a9f14424",
"version": 0,
"state": "payload['1-0:2.4.0*255']",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1100,
"y": 420,
"wires": [
[]
]
},
{
"id": "0675dcfc8c235226",
"type": "ha-sensor",
"z": "e53ffbf84b82e84f",
"name": "Active energy- ",
"entityConfig": "2cd09c220eca3787",
"version": 0,
"state": "payload['1-0:2.8.0*255']",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1100,
"y": 480,
"wires": [
[]
]
},
{
"id": "a85f2328603badb5",
"type": "debug",
"z": "e53ffbf84b82e84f",
"name": "debug 12",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1240,
"y": 60,
"wires": []
},
{
"id": "a9209550ade6dd83",
"type": "inject",
"z": "e53ffbf84b82e84f",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 260,
"y": 60,
"wires": [
[
"394b6cca83f615a2"
]
]
},
{
"id": "a9f7149c8d1f846d",
"type": "ha-entity-config",
"server": "8039551f.ccc59",
"deviceConfig": "677ce7620c63f57b",
"name": "Activepower+ ",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Wirkleistung Bezug"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": "power"
},
{
"property": "unit_of_measurement",
"value": "W"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false
},
{
"id": "7f5b702d206bc348",
"type": "ha-entity-config",
"server": "8039551f.ccc59",
"deviceConfig": "677ce7620c63f57b",
"name": "Activeenergy+",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Wirkenergie Bezug"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "total"
}
],
"resend": true
},
{
"id": "fd242424a9f14424",
"type": "ha-entity-config",
"server": "8039551f.ccc59",
"deviceConfig": "677ce7620c63f57b",
"name": "Active power-",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Wirkleistung Einspeisung"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": "power"
},
{
"property": "unit_of_measurement",
"value": "W"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false
},
{
"id": "2cd09c220eca3787",
"type": "ha-entity-config",
"server": "8039551f.ccc59",
"deviceConfig": "677ce7620c63f57b",
"name": "Active energy- ",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Wirkenergie Einspeisung"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "total"
}
],
"resend": true
},
{
"id": "8039551f.ccc59",
"type": "server",
"name": "Home Assistant",
"version": 5,
"addon": false,
"rejectUnauthorizedCerts": true,
"ha_boolean": "y|yes|true|on|home|open",
"connectionDelay": true,
"cacheJson": true,
"heartbeat": true,
"heartbeatInterval": "30",
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": "at: ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "h23",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": true
},
{
"id": "677ce7620c63f57b",
"type": "ha-device-config",
"name": "E300",
"hwVersion": "",
"manufacturer": "tq-group",
"model": "B-Control",
"swVersion": "2.04"
}
]
thanks for this … trying to use the script out of the link forwarded. but struggeling on how to make the mqtt call working.
#
# Copyright: Kilian Knoll, 15.12.2018
# Update: Feb 12 2020: Publish to MQTT
# Utility to parse EnergyManager EM300LR using the JSON API
#
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# Please note that any incorrect or careless usage of this module as well as errors in the implementation can damage your Energy Manager!
# Therefore, the author does not provide any guarantee or warranty concerning to correctness, functionality or performance and does not accept any liability for damage caused by this module, examples or mentioned information.
# Thus, use it at your own risk!
#
#
# Purpose:
# Returns:
# Returnvalue: 0 (Everything all right)
# Returnvalue: -1 (Crap happened)
# em300data: (Empty list in case Returnvalue =-1)
# em300data: (Full list of key-value pairs in case Returnvalue = 0)
#
# Tested with:
# python 3.5, 3,7
# B-control Energy Manager EM300, Firmware Version 2.04
# Based on: https://www.tq-automation.com/Service-Support/Downloads/Downloads-Energiemanagement
# Using the JSON Documentation: https://www.tq-automation.com/content/download/10996/file/TQ%20Energy%20Manager%20-%20JSON-API.0104.pdf
#
# Please change the following values to reflect your environment:
Em_IP_Adress = "192.168.178.27"
EM_Serialumber= "72130555" #Serial Number can be found accessing the Energy Manager´s Web Page under Settings - Serial number
EM_Password= "YourPassword" #This is the password you have specified on the Energy Manager´s Web Page (without quotes)
MQTTBroker_IPaddress="192.168.178.39" #You need to have an MQTT broker set up & running
# End Configurable Parameters
#
import requests
import time
import json
import time
import datetime
import logging
#from loggerdate import loggerdate
from pprint import pprint
import paho.mqtt.client as mqtt
myparams= {'login': EM_Serialumber, 'password': EM_Password, 'save_login': '1'}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; "
}
mySession = requests.Session()
def changeobiskeys(myjsoninput):
myjsoninput["Active power_incoming"] = myjsoninput.pop("1-0:1.4.0*255")
myjsoninput["Active energy_incoming"] = myjsoninput.pop("1-0:1.8.0*255")
myjsoninput["Apparent power-"] = myjsoninput.pop("1-0:10.4.0*255")
myjsoninput["Apparent energy-"] = myjsoninput.pop("1-0:10.8.0*255")
myjsoninput["Power factor"] = myjsoninput.pop("1-0:13.4.0*255")
myjsoninput["Supply frequency"] = myjsoninput.pop("1-0:14.4.0*255")
myjsoninput["Active power- "] = myjsoninput.pop("1-0:2.4.0*255")
myjsoninput["Active energy-"] = myjsoninput.pop("1-0:2.8.0*255")
myjsoninput["Active power_incoming L1"] = myjsoninput.pop("1-0:21.4.0*255")
myjsoninput["Active energy_incoming L1"] = myjsoninput.pop("1-0:21.8.0*255")
myjsoninput["Active power- L1"] = myjsoninput.pop("1-0:22.4.0*255")
myjsoninput["Active energy- L1"] = myjsoninput.pop("1-0:22.8.0*255")
myjsoninput["Reactive power_incoming L1"] = myjsoninput.pop("1-0:23.4.0*255")
myjsoninput["Reactive energy_incoming L1"] = myjsoninput.pop("1-0:23.8.0*255")
myjsoninput["Reactive power- L1"] = myjsoninput.pop("1-0:24.4.0*255")
myjsoninput["Reactive energy- L1"] = myjsoninput.pop("1-0:24.8.0*255")
myjsoninput["Apparent power_incoming L1"] = myjsoninput.pop("1-0:29.4.0*255")
myjsoninput["Apparent energy_incoming L1"] = myjsoninput.pop("1-0:29.8.0*255")
myjsoninput["Reactive power_incoming"] = myjsoninput.pop("1-0:3.4.0*255")
myjsoninput["Reactive energy_incoming"] = myjsoninput.pop("1-0:3.8.0*255")
myjsoninput["Apparent power- L1"] = myjsoninput.pop("1-0:30.4.0*255")
myjsoninput["Apparent energy- L1"] = myjsoninput.pop("1-0:30.8.0*255")
myjsoninput["Current L1"] = myjsoninput.pop("1-0:31.4.0*255")
myjsoninput["Voltage L1"] = myjsoninput.pop("1-0:32.4.0*255")
myjsoninput["Power factor L1"] = myjsoninput.pop("1-0:33.4.0*255")
myjsoninput["Reactive power-"] = myjsoninput.pop("1-0:4.4.0*255")
myjsoninput["Reactive energy-"] = myjsoninput.pop("1-0:4.8.0*255")
myjsoninput["Active power_incoming L2"] = myjsoninput.pop("1-0:41.4.0*255")
myjsoninput["Active energy_incoming L2"] = myjsoninput.pop("1-0:41.8.0*255")
myjsoninput["Active power- L2"] = myjsoninput.pop("1-0:42.4.0*255")
myjsoninput["Active energy- L2"] = myjsoninput.pop("1-0:42.8.0*255")
myjsoninput["Reactive power_incoming L2"] = myjsoninput.pop("1-0:43.4.0*255")
myjsoninput["Reactive energy_incoming L2"] = myjsoninput.pop("1-0:43.8.0*255")
myjsoninput["Reactive power- L2"] = myjsoninput.pop("1-0:44.4.0*255")
myjsoninput["Reactive energy- L2"] = myjsoninput.pop("1-0:44.8.0*255")
myjsoninput["Apparent power_incoming L2"] = myjsoninput.pop("1-0:49.4.0*255")
myjsoninput["Apparent energy_incoming L2"] = myjsoninput.pop("1-0:49.8.0*255")
myjsoninput["Apparent power- L2"] = myjsoninput.pop("1-0:50.4.0*255")
myjsoninput["Apparent energy- L2"] = myjsoninput.pop("1-0:50.8.0*255")
myjsoninput["Current L2"] = myjsoninput.pop("1-0:51.4.0*255")
myjsoninput["Voltage L2"] = myjsoninput.pop("1-0:52.4.0*255")
myjsoninput["Power factor L2"] = myjsoninput.pop("1-0:53.4.0*255")
myjsoninput["Active power_incoming L3"] = myjsoninput.pop("1-0:61.4.0*255")
myjsoninput["Active energy_incoming L3"] = myjsoninput.pop("1-0:61.8.0*255")
myjsoninput["Active power- L3"] = myjsoninput.pop("1-0:62.4.0*255")
myjsoninput["Active energy- L3"] = myjsoninput.pop("1-0:62.8.0*255")
myjsoninput["Reactive power_incoming L3"] = myjsoninput.pop("1-0:63.4.0*255")
myjsoninput["Reactive energy_incoming L3"] = myjsoninput.pop("1-0:63.8.0*255")
myjsoninput["Reactive power- L3"] = myjsoninput.pop("1-0:64.4.0*255")
myjsoninput["Reactive energy- L3"] = myjsoninput.pop("1-0:64.8.0*255")
myjsoninput["Apparent power_incoming L3"] = myjsoninput.pop("1-0:69.4.0*255")
myjsoninput["Apparent energy_incoming L3"] = myjsoninput.pop("1-0:69.8.0*255")
myjsoninput["Apparent power- L3"] = myjsoninput.pop("1-0:70.4.0*255")
myjsoninput["Apparent energy- L3"] = myjsoninput.pop("1-0:70.8.0*255")
myjsoninput["Current L3"] = myjsoninput.pop("1-0:71.4.0*255")
myjsoninput["Voltage L3"] = myjsoninput.pop("1-0:72.4.0*255")
myjsoninput["Power factor L3"] = myjsoninput.pop("1-0:73.4.0*255")
myjsoninput["Apparent power_incoming"] = myjsoninput.pop("1-0:9.4.0*255")
myjsoninput["Apparent energy_incoming"] = myjsoninput.pop("1-0:9.8.0*255")
#serial
#status
return myjsoninput
def readenergymanager():
try:
#------------------------------------------------------------
#Start Connection to Energymanager
#------------------------------------------------------------
# Initial handshake
print ("starting initial handshake - start step 1 ...")
r1 = mySession.get('http://'+ Em_IP_Adress + '/start.php', headers=headers)
if (r1.status_code == requests.codes.ok):
pass
else:
Error_Connecting = r1.status_code
print ("Unable to connect :", Error_Connecting)
except Exception as Error_ConnecttoEnergymanager:
print ("Error accessing Energy Manager step1 :", Error_ConnecttoEnergymanager)
time.sleep(0.25)
#------------------------------------------------------------
# Authenticate with credentials
try:
print ("trying to authenticate -start step 2 ...")
r2 = mySession.post('http://'+ Em_IP_Adress + '/start.php',myparams, headers=headers)
if (r2.status_code == requests.codes.ok):
pass
else:
Error_Connecting = r2.status_code
print ("Unable to Authenticate :", Error_Connecting)
except Exception as Error_ConnecttoEnergymanager:
print ("Error accessing Energy Manager step2 :", Error_ConnecttoEnergymanager)
#------------------------------------------------------------
# Get Data from EnergyManager
try:
print ("trying to get data - start step 3 ...")
r3 = mySession.get('http://'+ Em_IP_Adress +'/mum-webservice/data.php', headers=headers)
if (r3.status_code == requests.codes.ok):
pass
else:
Error_Connecting = r3.status_code
print ("Unable to Get data :", Error_Connecting)
em300data=json.loads(r3.text)
Error_Connecting = 0
except Exception as Error_ConnecttoEnergymanager:
print ("Error accessing Energy Manager step3 :", Error_ConnecttoEnergymanager)
#logging.error("%s %s %s", loggerdate(), ",readenergymanager: Ran into exception querying the energymanager : ", Error_ConnecttoEnergymanager)
Error_Connecting=Error_ConnecttoEnergymanager
#
# End Connection to EnergyManager
#_______________________________________________________________
#
#--------------------------------------------------------------
# Processing data
Returnvalue = -1
if (Error_Connecting == 0):
if (len(em300data) >1): # We have something in the list
if (em300data["status"] == 0): # We got valid data from Energymanager
("before calling changeobiskeys")
em300data =changeobiskeys(em300data)
Returnvalue =0
else: # We ran into trouble and allocate an empty list
em300data={}
print ("Issue getting data from EnergyManager ", Error_Connecting)
return (Returnvalue, em300data)
if __name__ == "__main__":
emclient = mqtt.Client("emclient") #create new instance
emclient.connect(MQTTBroker_IPaddress)
print ("Start querying Energy Manager....")
try:
Myreturnvalue, Mydata = readenergymanager();
if (Myreturnvalue == 0):
print ("Returnvalue -should be zero if successful : ", Myreturnvalue)
print ("----------------Start Values from Energy Manager ----------------")
pprint (Mydata)
print ("----------------End - Values from Energy Manager ----------------")
print ("Two Specific values from array....")
print ("Energy to Grid (Obis code: 1-0:2.8.0)", Mydata['Active energy-'])
print ("Energy from Grid (Obis code: 1-0:1.8.0)", Mydata['Active energy_incoming'])
print ("----------------End - Two Specific values from array ------------")
params = Mydata.keys()
print ("----------------Publishing to MQTT ------------")
for p in sorted(params):
print("PublishtoMQTT:","{:{width}}: {}".format(p, Mydata[p], width=len(max(params, key=len))))
TOPIC = ("Energymanager/"+p)
emclient.publish(TOPIC,Mydata[p])
print ("----------------END Publishing to MQTT --------")
else:
print ("I was unable to query the Energy Manager")
except Exception as ex:
print ("Issues querying EnergyManager :", ex)
After a long time, I finally created a simple python module. It spits out all values and does the authentication. Now I try to create an integration
Are you running the script inside Home Assistant (pyscript)? So far, I’ve been running a script on a different Raspberry Pi, but I want to eliminate the need for that extra hardware. I’d be interested in learning about your solution.
Regards.
Im using Node Red right now. But I created a Python Module to get the data. Next step is to push it to pypi and build an Home Assistant integration.
Lets see if when I get it done.
You dont need extra Hwardware