Skip to content

Commit

Permalink
Added HomeAssistant support
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaluxPL committed Feb 23, 2022
1 parent bdadea7 commit 2b08f03
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 7 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,14 @@ Fix version

### Fixed
1. Reliable messages delivery to MQTT/Domoticz.

## [1.7] - 2022-02-23
HomeAssistant support

### Added
1. Home Assistant support (via MQTT) - curtesy of @pablolite code

### Changed
1. Minor cleanups.

### Fixed
50 changes: 45 additions & 5 deletions InverterData.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python3
# Script gathering solar data from Sofar Solar Inverter (K-TLX) via logger module LSW-3/LSE
# by Michalux (based on DEYE script by jlopez77)
# Version: 1.66
# by Michalux (based on DEYE script by jlopez77, HA initial code by pablolite).
# Version: 1.7
#

import sys
Expand All @@ -11,7 +11,6 @@
import libscrc
import json
import paho.mqtt.client as paho
import paho.mqtt.publish as mqttpublish
import os
import configparser
import datetime
Expand Down Expand Up @@ -84,6 +83,7 @@ def PrepareDomoticzData(DData, idx, svalue):
ifpass=configParser.get('InfluxDB', 'influxdb_password')
ifdb=configParser.get('InfluxDB', 'influxdb_dbname')
DomoticzSupport=configParser.get('Domoticz', 'domoticz_support')
HomeAssistantSupport=configParser.get('HomeAssistant', 'homeassistant_support')
# END CONFIG

timestamp=str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))
Expand All @@ -108,6 +108,7 @@ def PrepareDomoticzData(DData, idx, svalue):
totaltime=0
PMData=[]
DomoticzData=[]
HomeAssistantData=[]

while chunks<2:
if verbose=="1": print("*** Chunk no: ", chunks);
Expand Down Expand Up @@ -210,6 +211,7 @@ def PrepareDomoticzData(DData, idx, svalue):
if prometheus=="1" and graph==1: PMetrics(metric_name, metric_type, label_name, label_value, response);
if influxdb=="1" and graph==1: PrepareInfluxData(InfluxData, metric_name.split('_')[0]+"_"+label_value, response);
if DomoticzSupport=="1" and DomoticzIdx>0: PrepareDomoticzData(DomoticzData, DomoticzIdx, response);
if HomeAssistantSupport=="1": HomeAssistantData.append([title, ratio, unit, metric_type, metric_name, label_name, label_value, response, register]);
if unit!="":
output=output+"\""+ title + " (" + unit + ")" + "\":" + str(response)+","
else:
Expand All @@ -222,6 +224,7 @@ def PrepareDomoticzData(DData, idx, svalue):
if prometheus=="1" and graph==1: PMetrics(metric_name, metric_type, label_name, label_value, (totalpower*1000));
if influxdb=="1" and graph==1: PrepareInfluxData(InfluxData, metric_name.split('_')[0]+"_"+label_value, totalpower);
if DomoticzSupport=="1" and DomoticzIdx>0: PrepareDomoticzData(DomoticzData, DomoticzIdx, response);
if HomeAssistantSupport=="1": HomeAssistantData.append([title, ratio, unit, metric_type, metric_name, label_name, label_value, response, (totalpower*1000)]);
if hexpos=='0x0017': totaltime+=response*ratio*65536;
if hexpos=='0x0018':
totaltime+=response*ratio
Expand All @@ -230,6 +233,7 @@ def PrepareDomoticzData(DData, idx, svalue):
if prometheus=="1" and graph==1: PMetrics(metric_name, metric_type, label_name, label_value, totaltime);
if influxdb=="1" and graph==1: PrepareInfluxData(InfluxData, metric_name.split('_')[0]+"_"+label_value, totaltime);
if DomoticzSupport=="1" and DomoticzIdx>0: PrepareDomoticzData(DomoticzData, DomoticzIdx, response);
if HomeAssistantSupport=="1": HomeAssistantData.append([title, ratio, unit, metric_type, metric_name, label_name, label_value, response, totaltime]);
a+=1
if chunks==0:
pini=reg_start2
Expand All @@ -250,7 +254,7 @@ def PrepareDomoticzData(DData, idx, svalue):
Write2InfluxDB(InfluxData)
if verbose=="1": print("Influx data: ",InfluxData);

# MQTT and Domoticz integration
# MQTT integration (Domoticz, HA, pure MQTT)
if mqtt==1 and invstatus==1:
# Initialise MQTT connection
client=paho.Client("inverter")
Expand All @@ -273,9 +277,45 @@ def PrepareDomoticzData(DData, idx, svalue):
result=client.publish(mqtt_topic+"/attributes",output)
result.wait_for_publish()
if result.is_published:
print("*** Data has been succesfully published to MQTT with topic: "+mqtt_topic+"/attributes")
if verbose==1: print("*** Data has been succesfully published to MQTT with topic: "+mqtt_topic+"/attributes")
else:
print("Error publishing data to MQTT")
if HomeAssistantSupport=="1":
if verbose=="1": print("*** MQTT messages for HomeAssistant:");
# Send messages in case of unexpected disconnection
client.will_set("Sofar/Logger/"+str(inverter_sn)+"/state/connected","false")
# Send status of device: enabled = true
result=client.publish("Sofar/Logger/"+str(inverter_sn)+"/enabled","true")
result.wait_for_publish()
if not result.is_published:
print("Error publishing device status for HomeAssistant to MQTT")
# Send state of device: connected = true
result=client.publish("Sofar/Logger/"+str(inverter_sn)+"/state/connected","true")
result.wait_for_publish()
if not result.is_published:
print("Error publishing device state for HomeAssistant to MQTT")
HAcount=0
for mqtt_data in HomeAssistantData:
# Sensors for ENERGY module with kWh, Wh, W
#if mqtt_data[2]=="kWh" or mqtt_data[2]=="Wh" or mqtt_data[2]=="W":
if mqtt_data[2] in ['kWh', 'Wh', 'W']:
# Send auto-discover device sensor template
result=client.publish("homeassistant/sensor/SofarLogger/"+str(inverter_sn)+"_"+str(HAcount)+"/config","{\"avty\":{\"topic\":\"Sofar/Logger/"+str(inverter_sn)+"/state/connected\",\"payload_available\":\"true\",\"payload_not_available\":\"false\"},\"~\":\"Sofar/Logger/"+str(inverter_sn)+"/\",\"device\":{\"ids\":\""+str(inverter_sn)+"\",\"mf\":\"Sofar\",\"name\":\"WLS-3\",\"sw\":\"x.x.x\"},\"name\":\""+(mqtt_data[0])+" ["+(mqtt_data[2])+"]\",\"uniq_id\":\""+str(inverter_sn)+"_"+str(HAcount)+"\",\"qos\":0,\"unit_of_meas\":\""+(mqtt_data[2])+"\",\"stat_t\":\"~state/"+(mqtt_data[4])+(mqtt_data[6])+"\",\"val_tpl\":\"{{ value | round(5) }}\",\"dev_cla\":\"energy\",\"state_class\":\"total_increasing\"}")
# Rest of the sensors
else:
# Send auto-discover device sensor template
result=client.publish("homeassistant/sensor/SofarLogger/"+str(inverter_sn)+"_"+str(HAcount)+"/config","{\"avty\":{\"topic\":\"Sofar/Logger/"+str(inverter_sn)+"/state/connected\",\"payload_available\":\"true\",\"payload_not_available\":\"false\"},\"~\":\"Sofar/Logger/"+str(inverter_sn)+"/\",\"device\":{\"ids\":\""+str(inverter_sn)+"\",\"mf\":\"Sofar\",\"name\":\"WLS-3\",\"sw\":\"x.x.x\"},\"name\":\""+(mqtt_data[0])+" ["+(mqtt_data[2])+"]\",\"uniq_id\":\""+str(inverter_sn)+"_"+str(HAcount)+"\",\"qos\":0,\"unit_of_meas\":\""+(mqtt_data[2])+"\",\"stat_t\":\"~state/"+(mqtt_data[4])+(mqtt_data[6])+"\",\"val_tpl\":\"{{ value | round(5) }}\",\"dev_cla\":\"current\",\"state_class\":\"measurement\"}")
result.wait_for_publish()
if not result.is_published:
print("[",str(HAcount),"]", "Error publishing data for HomeAssistant to MQTT")
else:
if verbose=="1": print("[",str(HAcount),"]", mqtt_data[0], ": ", mqtt_data[7]);
# Send sensor values data
result=client.publish("Sofar/Logger/"+str(inverter_sn)+"/state/"+(mqtt_data[4])+(mqtt_data[6]), (mqtt_data[7]))
result.wait_for_publish()
if not result.is_published:
print("[",str(HAcount),"]","Error publishing data for HomeAssistant to MQTT")
HAcount+=1
client.loop_stop()
client.disconnect()
print("*** JSON output:")
Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ REMARK: To make it work with other inverter brand/model connected via LSW-3/LSE
the register's addresses in the .xml files accordingly and change register start/end numbers in config.cfg

*Thanks to @jlopez77 https://github.com/jlopez77 for logger/MODBUS protocol code.*
*Thanks to @pablolite for HomeAssistant initial code.*

# Required python modules
To run, script requires following python modules:
Expand Down Expand Up @@ -61,6 +62,9 @@ mqtt_cacert= # CA certificate path/filename
[Domoticz]
domoticz_support=0 # 0: disabled, 1: enabled
[HomeAssistant]
homeassistant_support=0 # 0: disabled, 1: enabled
Files SOFARMap.xml and SOFARHWMap.xml contain MODBUS inverter's registers mapping for Sofar Solar K-TLX product line
and Prometheus/InfluxDB metrics configuration.
Edit i.e. to get captions in a different language, change Prometheus/InfluxDB metrics names or
Expand Down Expand Up @@ -161,10 +165,10 @@ You tell me :)
Feel free to suggest :)
If You want to rewrite or/add change anything - please fork Your own project.

# MQTT Support (Domoticz compatible)
# Domoticz/MQTT Support
```
1. JSON_attributes_topic (unless Domoticz support enabled !): "mqtt_topic/attributes"
2. For TLS support You'll need at least CA Certificate and TLS enabled MQTT
2. For MQTT TLS support You'll need at least CA Certificate and TLS enabled MQTT
To enable TLS for Mosquitto look i.e here: http://www.steves-internet-guide.com/mosquitto-tls/
3. To turn Domoticz support on:
a) enable it in config.cfg
Expand All @@ -175,6 +179,16 @@ If You want to rewrite or/add change anything - please fork Your own project.
WARNING: When enabled, Domoticz support disables normal MQTT message delivery (all values in one message).
3. Tested with Mosquitto MQTT server (both with and without TLS) and Domoticz 2021.1
```
# HomeAssistant (via MQTT) Support (prepared/tested by @pablolite, optimized by Michalux)
```
1. For MQTT/TLS support You'll need at least CA Certificate and TLS enabled MQTT
To enable TLS for Mosquitto look i.e here: http://www.steves-internet-guide.com/mosquitto-tls/
2. To turn HomeAssistant support on, enable it in config.cfg
3. Hardcoded MQTT topic names:
a) Auto-discovery: homeassistant/sensor/SofarLogger/{Inverter's SN}_ID/config
b) Values: Sofar/Logger/{Inverter's SN}/state/{Param name}
c) Inverter's status: Sofar/Logger/{Inverter's SN}/enabled
```
# Prometheus+Grafana support
```
Steps to run Prometheus+Grafana support:
Expand Down
3 changes: 3 additions & 0 deletions config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ mqtt_cacert=

[Domoticz]
domoticz_support=0

[HomeAssistant]
homeassistant_support=0

0 comments on commit 2b08f03

Please sign in to comment.