Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Framer option #23

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revert "My ideal HomeAssistant integration"
  • Loading branch information
dudasekk authored Apr 2, 2023
commit 548a505c9b9ba578007c5a9cd7370cbf802ab651
13 changes: 4 additions & 9 deletions example.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"type","topic","col2","col3","col4","col5","col6","state_class","device_class","unit_of_measurement","name"
"type","topic","col2","col3","col4","col5","col6"
# DO NOT REMOVE THE FIRST LINE!
# Example register definition file.
#
Expand All @@ -8,7 +8,7 @@
#################################################################################
# Poller-object
# Columns:
# type, topic, slaveid, reference, size, functioncode, rate, , , , description
# type, topic, slaveid, reference, size, functioncode, rate
#
# Possible values for columns:
# type: poll
Expand All @@ -20,7 +20,6 @@
# size: integer 0 to 65535 (No. of registers to poll, value must not exceed the limits of Modbus of course)
# functionscode: coil, input_status, holding_register, input_register
# rate: float 0.0 to some really big number
# name: visible name to the end user
#
# functionscode equivalents: coil, input_status, holding_register, input_register
# 1 2 3 4
Expand All @@ -39,10 +38,6 @@
# rw: r, w or rw
# data type (registers only): uint16, float32BE, float32LE, uint32BE, uint32LE, string (defaults to uint16)
# scaling factor (registers only): a factor by which the read value is multiplied before publishing to mqtt. At the moment this only works when reading from Modbus.
# state_class: https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes
# device_class: https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
# unit_of_measurement: https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
# name: visible name to the end user
#
# Example reference-object:
# ref,light0,2,rw
Expand All @@ -53,8 +48,8 @@
#
#################################################################################
# Columns:
# type, topic, slaveid, reference, size, functioncode, rate, , , , name
# type, topic, reference, rw, data type, state_class, device_class, unit_of_measurement, name
# type, topic, slaveid, reference, size, functioncode, rate
# type, topic, reference, rw, data type,
#
poll,kitchen,7,0,4,coil,0.002
ref,light0,0,rw
Expand Down
83 changes: 24 additions & 59 deletions modbus2mqtt/addToHomeAssistant.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,41 @@
import json

class HassConnector:
def __init__(self, mqc, globaltopic, verbosity):
self.mqc = mqc
self.globaltopic = globaltopic
self.verbosity = verbosity

def addAll(self, referenceList):
def __init__(self,mqc,globaltopic,verbosity):
self.mqc=mqc
self.globaltopic=globaltopic
self.verbosity=verbosity
def addAll(self,referenceList):
if(self.verbosity):
self.removeAll(referenceList)
print("Adding all references to Home Assistant")
for r in referenceList:
meta = self.addHAMeta(r)

if "r" in r.rw and not "w" in r.rw:
if r.poller.dataType == "bool":
self.addBinarySensor(r, meta)
self.addBinarySensor(r)
if r.poller.dataType == "int16":
self.addSensor(r, meta)
self.addSensor(r)
if "w" in r.rw and "r" in r.rw:
if r.poller.dataType == "bool":
self.addSwitch(r, meta)
self.addSwitch(r)
if r.poller.dataType == "int16": #currently I have no idea what entity type to use here..
self.addSensor(r, meta)

def addHAMeta(self, ref):
config = {}
if ref.state_class:
config["state_class"] = ref.state_class

if ref.device_class:
config["device_class"] = ref.device_class

if ref.unit_of_measurement:
config["unit_of_measurement"] = ref.unit_of_measurement

if ref.name:
config["name"] = f"{ref.device.description} {ref.name}"

return config

def addBinarySensor(self, ref, meta):
self.addSensor(r)

def addBinarySensor(self,ref):
if(self.verbosity):
print(f"Adding binary sensor {ref.topic} to HASS")

object_id = f"{ref.device.name}_{ref.topic}"
config = {"name": object_id, "object_id": object_id, "state_topic": f"{self.globaltopic}{ref.device.name}/state/{ref.topic}", "payload_on": True, "payload_off": False}
config.update(meta)
print("Adding binary sensor "+ref.topic+" to HASS")
self.mqc.publish("homeassistant/binary_sensor/"+self.globaltopic[0:-1]+"_"+ref.device.name+"_"+ref.topic+"/config","{\"name\": \""+ref.device.name+"_"+ref.topic+"\", \"state_topic\": \""+self.globaltopic+ref.device.name+"/state/"+ref.topic+"\", \"payload_on\": \"True\", \"payload_off\": \"False\"}",qos=0,retain=True)

self.mqc.publish(f"homeassistant/binary_sensor/{self.globaltopic[0:-1]}_{ref.device.name}_{ref.topic}/config", json.dumps(config), qos=0, retain=True)

def addSensor(self, ref, meta):
def addSensor(self,ref):
if(self.verbosity):
print(f"Adding sensor {ref.topic} to HASS")

object_id = f"{ref.device.name}_{ref.topic}"
config = {"name": object_id, "object_id": object_id, "state_topic": f"{self.globaltopic}{ref.device.name}/state/{ref.topic}"}
config.update(meta)
print("Adding sensor "+ref.topic+" to HASS")
self.mqc.publish("homeassistant/sensor/"+self.globaltopic[0:-1]+"_"+ref.device.name+"_"+ref.topic+"/config","{\"name\": \""+ref.device.name+"_"+ref.topic+"\", \"state_topic\": \""+self.globaltopic+ref.device.name+"/state/"+ref.topic+"\"}",qos=0,retain=True)

self.mqc.publish(f"homeassistant/sensor/{self.globaltopic[0:-1]}_{ref.device.name}_{ref.topic}/config", json.dumps(config), qos=0, retain=True)

def addSwitch(self, ref, meta):
def addSwitch(self,ref):
if(self.verbosity):
print(f"Adding switch {ref.topic} to HASS")

object_id = f"{ref.device.name}_{ref.topic}"
config = {"name": object_id, "object_id": object_id, "state_topic": f"{self.globaltopic}{ref.device.name}/set/{ref.topic}", "payload_on": True, "payload_off": False}
config.update(meta)

self.mqc.publish(f"homeassistant/switch/{self.globaltopic[0:-1]}_{ref.device.name}_{ref.topic}/config", json.dumps(config), qos=0, retain=True)
print("Adding switch "+ref.topic+" to HASS")
self.mqc.publish("homeassistant/switch/"+self.globaltopic[0:-1]+"_"+ref.device.name+"_"+ref.topic+"/config","{\"name\": \""+ref.device.name+"_"+ref.topic+"\", \"state_topic\": \""+self.globaltopic+ref.device.name+"/state/"+ref.topic+"\", \"state_on\": \"True\", \"state_off\": \"False\", \"command_topic\": \""+self.globaltopic+ref.device.name+"/set/"+ref.topic+"\", \"payload_on\": \"True\", \"payload_off\": \"False\"}",qos=0,retain=True)

def removeAll(self,referenceList):
for ref in referenceList:
self.mqc.publish(f"{self.globaltopic}{ref.device.name}/state/{ref.topic}","",qos=0)
# def removeAll(self,referenceList):
# for ref in referenceList:
# print("blah")
# self.mqc.publish(self.globaltopic+ref.device.name+"/"+ref.topic,"",qos=0)

22 changes: 6 additions & 16 deletions modbus2mqtt/modbus2mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,14 @@ def signal_handler(signal, frame):
control.stopLoop()

class Device:
def __init__(self,name,slaveid,description=None):
def __init__(self,name,slaveid):
self.name=name
self.description=name
self.occupiedTopics=[]
self.writableReferences=[]
self.slaveid=slaveid
self.errorCount=0
self.pollCount=0
self.next_due=time.clock_gettime(0)+args.diagnostics_rate

if description:
self.description=description
if verbosity>=2:
print('Added new device \"'+self.name+'\"')

Expand All @@ -115,7 +111,7 @@ def publishDiagnostics(self):
self.errorCount=0

class Poller:
def __init__(self,topic,rate,slaveid,functioncode,reference,size,dataType,name=None):
def __init__(self,topic,rate,slaveid,functioncode,reference,size,dataType):
self.topic=topic
self.rate=float(rate)
self.slaveid=int(slaveid)
Expand All @@ -130,14 +126,13 @@ def __init__(self,topic,rate,slaveid,functioncode,reference,size,dataType,name=N
self.disabled=False
self.failcounter=0
self.connected=False
self.name=name

for myDev in deviceList:
if myDev.name == self.topic:
self.device=myDev
break
if self.device == None:
device = Device(self.topic,slaveid,self.name)
device = Device(self.topic,slaveid)
deviceList.append(device)
self.device=device
if verbosity>=2:
Expand Down Expand Up @@ -514,17 +509,13 @@ def combinefloat32BE(self,val):
return out

class Reference:
def __init__(self,topic,reference,dtype,rw,poller,scaling,state_class="measurement",device_class=None,unit_of_measurement=None,name=None):
def __init__(self,topic,reference,dtype,rw,poller,scaling):
self.topic=topic
self.reference=int(reference)
self.lastval=None
self.scale=None
self.regAmount=None
self.stringLength=None
self.state_class=state_class
self.device_class=device_class
self.unit_of_measurement=unit_of_measurement
self.name=name

if scaling:
try:
Expand Down Expand Up @@ -789,12 +780,12 @@ def main():
print("Unknown function code ("+row["col5"]+" ignoring poller "+row["topic"]+".")
currentPoller=None
continue
currentPoller = Poller(row["topic"],rate,slaveid,functioncode,reference,size,dataType,row["name"])
currentPoller = Poller(row["topic"],rate,slaveid,functioncode,reference,size,dataType)
pollers.append(currentPoller)
continue
elif row["type"]=="reference" or row["type"]=="ref":
if currentPoller is not None:
currentPoller.addReference(Reference(row["topic"],row["col2"],row["col4"],row["col3"],currentPoller,row["col5"],row["state_class"],row["device_class"],row["unit_of_measurement"],row["name"]))
currentPoller.addReference(Reference(row["topic"],row["col2"],row["col4"],row["col3"],currentPoller,row["col5"]))
else:
print("No poller for reference "+row["topic"]+".")

Expand Down Expand Up @@ -907,7 +898,6 @@ def main():
if verbosity >= 1:
print("MQTT Loop started")
except:
raise
if verbosity>=1:
print("Socket Error connecting to MQTT broker: " + args.mqtt_host + ":" + str(mqtt_port) + ", check LAN/Internet connection, trying again...")

Expand Down