|
@ -1,4 +1,4 @@ |
|
|
#!/usr/bin/env python3 |
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
|
|
|
from __future__ import absolute_import, print_function |
|
|
from __future__ import absolute_import, print_function |
|
|
|
|
|
|
|
@ -17,30 +17,33 @@ base_topic="house" |
|
|
|
|
|
|
|
|
coil_topic = "coil" |
|
|
coil_topic = "coil" |
|
|
light_topic = "light" |
|
|
light_topic = "light" |
|
|
|
|
|
switch_topic = "switch" |
|
|
|
|
|
|
|
|
coil_map = { |
|
|
coil_map = { |
|
|
'EZ': [ 0x03, 0x01 ], |
|
|
# tag, node, address, affinity |
|
|
'K': [ 0x03, 0x02 ], |
|
|
# tag: (L)ight, (E)G, (O)G, (F)lur, (S)chlaf, (A)ussen |
|
|
'WZ1': [ 0x02, 0x01 ], |
|
|
'EZ': [ "LE", 0x03, 0x01 ], |
|
|
'WZ2': [ 0x02, 0x02 ], |
|
|
'K': [ "LE", 0x03, 0x02 ], |
|
|
'TER': [ 0x03, 0x03 ], |
|
|
'WZ1': [ "LE", 0x02, 0x01 ], |
|
|
'FE': [ 0x03, 0x07 ], |
|
|
'WZ2': [ "LE", 0x02, 0x02 ], |
|
|
'TRE': [ 0x02, 0x03 ], |
|
|
'TER': [ "LEA", 0x03, 0x03 ], |
|
|
'FO': [ 0x01, 0x03 ], |
|
|
'FE': [ "LFE", 0x03, 0x07 ], |
|
|
'TRO': [ 0x01, 0x07 ], |
|
|
'TRE': [ "LFE", 0x02, 0x03 ], |
|
|
'KI1': [ 0x01, 0x06 ], |
|
|
'FO': [ "LFO", 0x01, 0x03 ], |
|
|
'KI2': [ 0x01, 0x04 ], |
|
|
'TRO': [ "LFO", 0x01, 0x07 ], |
|
|
'SCH': [ 0x01, 0x08 ], |
|
|
'KI1': [ "LSO", 0x01, 0x06 ], |
|
|
'B1': [ 0x01, 0x01 ], |
|
|
'KI2': [ "LSO", 0x01, 0x04 ], |
|
|
'B2': [ 0x01, 0x02 ], |
|
|
'SCH': [ "LSO", 0x01, 0x08 ], |
|
|
'ROL_EZ_G_DOWN': [0x03, 0x05, -1], |
|
|
'B1': [ "LO", 0x01, 0x01 ], |
|
|
'ROL_EZ_G_UP': [0x03,0x04, -1], |
|
|
'B2': [ "LO", 0x01, 0x02 ], |
|
|
'ROL_EZ_N_DOWN': [0x03, 0x06, -2], |
|
|
'ROL_EZ_G_DOWN': [ "", 0x03, 0x05, -1], |
|
|
'ROL_EZ_N_UP': [0x03,0x08, -2], |
|
|
'ROL_EZ_G_UP': [ "", 0x03, 0x04, -1], |
|
|
'EG1': [ 0x02, 0x09 ], |
|
|
'ROL_EZ_N_DOWN': [ "", 0x03, 0x06, -2], |
|
|
'EG2': [ 0x03, 0x09 ], |
|
|
'ROL_EZ_N_UP': [ "", 0x03, 0x08, -2], |
|
|
'OG': [ 0x01, 0x09 ], |
|
|
# 'EG1': [ 0, 0x02, 0x09 ], |
|
|
'ALL': [ 0xFF, 0x09 ], |
|
|
# 'EG2': [ 0, 0x03, 0x09 ], |
|
|
|
|
|
# 'OG': [ 0, 0x01, 0x09 ], |
|
|
|
|
|
'ALL': [ "", 0xFF, 0x09 ], |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cmd_map = { |
|
|
cmd_map = { |
|
@ -51,7 +54,7 @@ cmd_map = { |
|
|
'value': 2, |
|
|
'value': 2, |
|
|
'toggle': 3 |
|
|
'toggle': 3 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def decon(msg_id): |
|
|
def decon(msg_id): |
|
|
msg_prio=msg_id>>26 |
|
|
msg_prio=msg_id>>26 |
|
@ -71,53 +74,56 @@ def con(msg_dst,msg_cmd,msg_prio=3,msg_type=0,msg_src=11, ): |
|
|
print("Constructed ID: "+hex(msg_id)) |
|
|
print("Constructed ID: "+hex(msg_id)) |
|
|
return msg_id |
|
|
return msg_id |
|
|
|
|
|
|
|
|
def coil_action(sub_topic, payload, bus) |
|
|
def coil_action(coil, payload, bus, tag=0 ): |
|
|
msg_cmd=cmd_map[m_decode] |
|
|
try: |
|
|
sub=msg.topic[len(base_topic)+len(coil_topic)+2:] |
|
|
cmd=cmd_map[payload] |
|
|
coil=sub |
|
|
except BaseException as e: |
|
|
print("substring: "+coil) |
|
|
logging.error("Error finding command {%s}: %s" % (payload, e)) |
|
|
|
|
|
print("Coil: ",coil,"cmd:", payload) |
|
|
try: |
|
|
try: |
|
|
addr = coil_map[coil] |
|
|
addr = coil_map[coil] |
|
|
|
|
|
|
|
|
print("Addr:", addr) |
|
|
print("Addr:", addr) |
|
|
if msg_cmd == 2: |
|
|
if cmd == 2: |
|
|
msg_data.append(value) |
|
|
print("TBD") |
|
|
print("msg_cmd",msg_cmd, len(addr)) |
|
|
# msg_data.append(value) |
|
|
if msg_cmd is not 0 and len(addr) is 3: |
|
|
print("cmd", cmd,"length: ", len(addr)) |
|
|
|
|
|
if tag is not 0: |
|
|
|
|
|
if tag not in addr[0]: |
|
|
|
|
|
print("not tagged with: ",tag) |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
if cmd is not 0 and len(addr) is 4: |
|
|
|
|
|
print("Applying affinity") |
|
|
for key, value in coil_map.items(): |
|
|
for key, value in coil_map.items(): |
|
|
print("checking: ", key) |
|
|
print("checking: ", key) |
|
|
if len(value) is 3: |
|
|
if len(value) is 4: |
|
|
print("value_2 is", value[2], "Addr: ", addr[2]) |
|
|
print("value_2 is", value[3], "Addr: ", addr[3]) |
|
|
if value[2] is addr[2]: |
|
|
if value[3] is addr[3]: |
|
|
msg_id=con(msg_dst=value[0],msg_cmd=0) |
|
|
msg_id=con(msg_dst=value[1],msg_cmd=0) |
|
|
msg_data=[value[1]] |
|
|
msg_data=[value[2]] |
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
data=msg_data, |
|
|
data=msg_data, |
|
|
extended_id=True) |
|
|
extended_id=True) |
|
|
try: |
|
|
try: |
|
|
local_bus.send(m) |
|
|
bus.send(m) |
|
|
|
|
|
print("data sent to CAN",m) |
|
|
except BaseException as e: |
|
|
except BaseException as e: |
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
print("data sent to CAN",m) |
|
|
|
|
|
|
|
|
msg_id=con(msg_dst=addr[1],msg_cmd=cmd) |
|
|
msg_id=con(msg_dst=addr[0],msg_cmd=msg_cmd) |
|
|
msg_data=[addr[2]] |
|
|
msg_data=[addr[1]] |
|
|
print(msg_id) |
|
|
|
|
|
|
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
data=msg_data, |
|
|
data=msg_data, |
|
|
extended_id=True) |
|
|
extended_id=True) |
|
|
try: |
|
|
try: |
|
|
bus.send(m) |
|
|
bus.send(m) |
|
|
|
|
|
print("data sent to CAN",m) |
|
|
except BaseException as e: |
|
|
except BaseException as e: |
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
print("data sent to CAN",m) |
|
|
|
|
|
except BaseException as e: |
|
|
|
|
|
logging.error("Error finding coil %s" % (coil)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def on_subscribe(self, mqttc, obj, mid, granted_qos): |
|
|
except BaseException as e: |
|
|
print("Subscribed: "+str(mid)+" "+str(granted_qos)) |
|
|
logging.error("Error finding coil %s" % (coil)) |
|
|
|
|
|
|
|
|
def on_connect(mcp_mqtt, userdata, flags, rc): |
|
|
def on_connect(mcp_mqtt, userdata, flags, rc): |
|
|
print("Connected with result code "+str(rc)) |
|
|
print("Connected with result code "+str(rc)) |
|
@ -125,56 +131,23 @@ def on_connect(mcp_mqtt, userdata, flags, rc): |
|
|
# Subscribing in on_connect() means that if we lose the connection and |
|
|
# Subscribing in on_connect() means that if we lose the connection and |
|
|
# reconnect then subscriptions will be renewed. |
|
|
# reconnect then subscriptions will be renewed. |
|
|
mcp_mqtt.subscribe(base_topic+"/#", 0) |
|
|
mcp_mqtt.subscribe(base_topic+"/#", 0) |
|
|
print("Subscribed to: "+base_topic+"/+") |
|
|
print("Subscribed to: "+base_topic+"/#") |
|
|
|
|
|
|
|
|
def on_message_coil(mcp_mqtt, bus, msg): |
|
|
def on_message_coil(mcp_mqtt, bus, msg): |
|
|
print("data Received topic: ", msg.topic) |
|
|
print("data Received topic: ", msg.topic) |
|
|
m_decode=str(msg.payload.decode("utf-8","ignore")) |
|
|
m_decode=str(msg.payload.decode("utf-8","ignore")) |
|
|
print("data Received",m_decode) |
|
|
print("data Received",m_decode) |
|
|
msg_cmd=cmd_map[m_decode] |
|
|
|
|
|
sub=msg.topic[len(base_topic)+len(coil_topic)+2:] |
|
|
sub=msg.topic[len(base_topic)+len(coil_topic)+2:] |
|
|
coil=sub |
|
|
coil_action(sub, m_decode, bus) |
|
|
print("substring: "+coil) |
|
|
|
|
|
try: |
|
|
|
|
|
addr = coil_map[coil] |
|
|
def on_message_light(mcp_mqtt, bus, msg): |
|
|
|
|
|
print("data Received topic: ", msg.topic) |
|
|
|
|
|
m_decode=str(msg.payload.decode("utf-8","ignore")) |
|
|
|
|
|
print("data Received",m_decode) |
|
|
|
|
|
sub=msg.topic[len(base_topic)+len(light_topic)+2:] |
|
|
|
|
|
coil_action(sub, m_decode, bus, "L") |
|
|
|
|
|
|
|
|
print("Addr:", addr) |
|
|
|
|
|
if msg_cmd == 2: |
|
|
|
|
|
msg_data.append(value) |
|
|
|
|
|
print("msg_cmd",msg_cmd, len(addr)) |
|
|
|
|
|
if msg_cmd is not 0 and len(addr) is 3: |
|
|
|
|
|
for key, value in coil_map.items(): |
|
|
|
|
|
print("checking: ", key) |
|
|
|
|
|
if len(value) is 3: |
|
|
|
|
|
print("value_2 is", value[2], "Addr: ", addr[2]) |
|
|
|
|
|
if value[2] is addr[2]: |
|
|
|
|
|
msg_id=con(msg_dst=value[0],msg_cmd=0) |
|
|
|
|
|
msg_data=[value[1]] |
|
|
|
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
|
|
|
data=msg_data, |
|
|
|
|
|
extended_id=True) |
|
|
|
|
|
try: |
|
|
|
|
|
local_bus.send(m) |
|
|
|
|
|
except BaseException as e: |
|
|
|
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
|
|
|
print("data sent to CAN",m) |
|
|
|
|
|
|
|
|
|
|
|
msg_id=con(msg_dst=addr[0],msg_cmd=msg_cmd) |
|
|
|
|
|
msg_data=[addr[1]] |
|
|
|
|
|
|
|
|
|
|
|
m = can.Message(arbitration_id=msg_id, |
|
|
|
|
|
data=msg_data, |
|
|
|
|
|
extended_id=True) |
|
|
|
|
|
try: |
|
|
|
|
|
bus.send(m) |
|
|
|
|
|
except BaseException as e: |
|
|
|
|
|
logging.error("Error sending can message {%s}: %s" % (m, e)) |
|
|
|
|
|
print("data sent to CAN",m) |
|
|
|
|
|
except BaseException as e: |
|
|
|
|
|
logging.error("Error finding coil %s" % (coil)) |
|
|
|
|
|
|
|
|
|
|
|
def on_message_light(mcp_mqtt, obj, msg): |
|
|
|
|
|
print("TBD",m) |
|
|
|
|
|
|
|
|
|
|
|
def on_message(mcp_mqtt, obj, msg): |
|
|
def on_message(mcp_mqtt, obj, msg): |
|
|
# This callback will be called for messages that we receive that do not |
|
|
# This callback will be called for messages that we receive that do not |
|
@ -222,9 +195,16 @@ def main(): |
|
|
print("received state: ", hex(de[3]), hex(msg.data[0]), hex(msg.data[1])) |
|
|
print("received state: ", hex(de[3]), hex(msg.data[0]), hex(msg.data[1])) |
|
|
for key in coil_map: |
|
|
for key in coil_map: |
|
|
address=coil_map[key] |
|
|
address=coil_map[key] |
|
|
if address[0] == de[3] and address[1] == msg.data[0]+1: |
|
|
if address[1] == de[3] and address[2] == msg.data[0]+1: |
|
|
print("coil/"+key+" changed to "+str(msg.data[1])) |
|
|
print("coil/"+key+" changed to "+str(msg.data[1])) |
|
|
mcp_mqtt.publish(base_topic+"/"+coil_topic+"/"+key+"/state", msg.data[1] , retain=1) |
|
|
mcp_mqtt.publish(base_topic+"/"+coil_topic+"/"+key+"/state", msg.data[1] , retain=1) |
|
|
|
|
|
if "L" in address[0]: |
|
|
|
|
|
print("light/"+key+" changed to "+str(msg.data[1])) |
|
|
|
|
|
mcp_mqtt.publish(base_topic+"/"+light_topic+"/"+key+"/state", msg.data[1] , retain=1) |
|
|
|
|
|
elif de[2]==0 and de[4] == 5: |
|
|
|
|
|
print("received state: ", de[3], msg.data[0], bin(msg.data[1])) |
|
|
|
|
|
mcp_mqtt.publish(base_topic+"/"+switch_topic+"/"+str(de[3])+"-"+str(msg.data[0]), bin(msg.data[1]) , retain=1) |
|
|
|
|
|
|
|
|
except KeyboardInterrupt: |
|
|
except KeyboardInterrupt: |
|
|
pass |
|
|
pass |
|
|
finally: |
|
|
finally: |
|
|