You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

light2can.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/usr/bin/env python3
  2. from __future__ import absolute_import, print_function
  3. import sys
  4. import argparse
  5. import socket
  6. from datetime import datetime
  7. import can
  8. from can import Bus, BusState, Logger
  9. import paho.mqtt.client as mqtt
  10. sub_topic = "light"
  11. aliases = {
  12. 'Esszimmer': 'EZ',
  13. 'Esszimmer oben': 'EZ',
  14. 'Küche': 'K',
  15. 'Wohnzimmer1': 'WZ1',
  16. 'Wohnzimmer2': 'WZ2',
  17. 'Wohnzimmer Nord': 'WZ1',
  18. 'Wohnzimmer Süd': 'WZ2',
  19. 'Wohnzimmer Tür': 'WZ1',
  20. 'Wohnzimmer TV': 'WZ2',
  21. 'Wohnzimmer Fernseher': 'WZ2',
  22. 'Bad Decke': 'B1',
  23. 'Bad Spiegel': 'B2',
  24. 'Bjarne': 'K1',
  25. 'Inka': 'K2',
  26. 'Schlafzimmer': 'SCH',
  27. 'Flur EG': 'FE',
  28. 'Flur unten': 'FE',
  29. 'Flur OG': 'FO',
  30. 'Flur oben': 'FO',
  31. 'Treppe EG': 'TRE',
  32. 'Treppe unten': 'TRE',
  33. 'Treppe OG': 'TRO',
  34. 'Treppe oben': 'TRO'
  35. }
  36. light_map = {
  37. 'EZ': [ 0x03, 0x01 ],
  38. 'K': [ 0x03, 0x02 ],
  39. 'WZ1': [ 0x02, 0x01 ],
  40. 'WZ2': [ 0x02, 0x02 ],
  41. 'TER': [ 0x03, 0x03 ],
  42. 'FE': [ 0x03, 0x07 ],
  43. 'TRE': [ 0x02, 0x03 ],
  44. 'FO': [ 0x01, 0x03 ],
  45. 'TRO': [ 0x01, 0x07 ],
  46. 'KI1': [ 0x01, 0x06 ],
  47. 'KI2': [ 0x01, 0x04 ],
  48. 'SCH': [ 0x01, 0x08 ],
  49. 'B1': [ 0x01, 0x01 ],
  50. 'B2': [ 0x01, 0x02 ],
  51. 'ROL_EZ_DOWN': [0x03,0x05],
  52. 'ROL_EZ_UP': [0x03,0x04],
  53. 'EG1': [ 0x02, 0x09 ],
  54. 'EG2': [ 0x03, 0x09 ],
  55. 'OG': [ 0x01, 0x09 ],
  56. 'ALL': [ 0xFF, 0x09 ],
  57. }
  58. cmd_map = {
  59. 'off': 0,
  60. 'on': 1,
  61. 'value': 2,
  62. 'toggle': 3
  63. }
  64. def decon(msg_id):
  65. msg_prio=msg_id>>26
  66. msg_type=(msg_id>>24) & 0x03
  67. msg_dst=(msg_id>>16) & 0xFF
  68. msg_src=(msg_id>>8) & 0xFF
  69. msg_cmd=msg_id & 0xFF
  70. # print("msg_id: ", hex(msg_id), "prio: ", hex(msg_prio),"type: ", hex(msg_type)," dst: ", hex(msg_dst)," src: ", hex(msg_src)," cmd: ",hex(msg_cmd))
  71. return [msg_prio, msg_type, msg_dst, msg_src, msg_cmd]
  72. def con(msg_dst,msg_cmd,msg_prio=3,msg_type=0,msg_src=11, ):
  73. msg_id=(msg_prio<<26) + \
  74. ((msg_type&0x03)<<24) +\
  75. ((msg_dst&0xFF)<<16) +\
  76. ((msg_src&0xFF)<<8) +\
  77. (msg_cmd&0xFF)
  78. print("Constructed ID: "+hex(msg_id))
  79. return msg_id
  80. def on_connect(mcp_mqtt, userdata, flags, rc):
  81. print("Connected with result code "+str(rc))
  82. # Subscribing in on_connect() means that if we lose the connection and
  83. # reconnect then subscriptions will be renewed.
  84. mcp_mqtt.subscribe(sub_topic+"/+")
  85. print("Subscribed to:"+sub_topic+"/+")
  86. def on_message(mcp_mqtt, userdata, msg):
  87. local_bus=userdata
  88. print("data Received topic: ", msg.topic)
  89. m_decode=str(msg.payload.decode("utf-8","ignore"))
  90. print("data Received",m_decode)
  91. msg_cmd=2
  92. try:
  93. value=int(m_decode)
  94. except ValueError:
  95. msg_cmd=cmd_map[m_decode]
  96. sub=msg.topic[len(sub_topic)+1:]
  97. light=aliases.get(sub,None)
  98. if light is None:
  99. light=sub
  100. print("substring: "+light)
  101. addr = light_map[light]
  102. msg_id=con(msg_dst=addr[0],msg_cmd=msg_cmd)
  103. msg_data=[addr[1]]
  104. print(msg_data)
  105. if msg_cmd == 2:
  106. msg_data.append(value)
  107. print(msg_data)
  108. m = can.Message(arbitration_id=msg_id,
  109. data=msg_data,
  110. extended_id=True)
  111. print("going to sent to CAN",m)
  112. try:
  113. local_bus.send(m)
  114. except BaseException as e:
  115. logging.error("Error sending can message {%s}: %s" % (m, e))
  116. print("data sent to CAN",m)
  117. def main():
  118. verbosity = 2
  119. logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
  120. can.set_logging_level(logging_level_name)
  121. can_filters = []
  122. config = {"can_filters": can_filters, "single_handle": True}
  123. config["interface"] = "socketcan"
  124. config["bitrate"] = 125000
  125. bus = Bus("can1", **config)
  126. print('Connected to {}: {}'.format(bus.__class__.__name__, bus.channel_info))
  127. print('Can Logger (Started on {})\n'.format(datetime.now()))
  128. mcp_mqtt = mqtt.Client()
  129. mcp_mqtt.on_connect = on_connect
  130. mcp_mqtt.on_message = on_message
  131. mcp_mqtt.user_data_set(bus)
  132. mcp_mqtt.connect("mcp", 1883, 60)
  133. try:
  134. while True:
  135. mcp_mqtt.loop_start()
  136. msg = bus.recv(1)
  137. if msg is not None:
  138. de=decon(msg.arbitration_id)
  139. m= { "prio": hex(de[0]), "type": hex(de[1]), "dst": hex(de[2]), "src": hex(de[3]), "cmd": hex(de[4]), "action": hex(msg.data[0]) }
  140. if de[2]==0 and de[4] == 6:
  141. print("received state: ", hex(de[3]), hex(msg.data[0]), hex(msg.data[1]))
  142. for key in light_map:
  143. address=light_map[key]
  144. if address[0] == de[3] and address[1] == msg.data[0]+1:
  145. print("light/"+key+" changed to "+str(msg.data[1]))
  146. mcp_mqtt.publish("light/"+key+"/state", msg.data[1] , retain=1)
  147. except KeyboardInterrupt:
  148. pass
  149. finally:
  150. bus.shutdown()
  151. if __name__ == "__main__":
  152. main()