simdev.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. import os
  4. import sys
  5. import time
  6. import json
  7. import logging
  8. import datetime
  9. import threading
  10. import daiquiri
  11. #: current_dir - 2
  12. PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
  13. sys.path.insert(0, PROJECT_ROOT)
  14. from common import *
  15. from apps.web.core.mqtt_client import MqttClient
  16. daiquiri.setup(
  17. level=logging.DEBUG,
  18. outputs=(
  19. daiquiri.output.Stream(sys.stdout),
  20. daiquiri.output.File('simdev-errors.log', level=logging.ERROR),
  21. daiquiri.output.TimedRotatingFile('simdev-everything.log',
  22. level=logging.DEBUG,
  23. interval=datetime.timedelta(days=1))
  24. )
  25. )
  26. logger = logging.getLogger(__name__)
  27. SMART_BOX_PARA = {
  28. 'ip_addr': "120.27.251.159",
  29. 'port': 1883,
  30. 'mny1': 1,
  31. 'tm1': 6,
  32. 'mny2': 2,
  33. 'tm2': 20,
  34. 'mny3': 3,
  35. 'tm3': 35,
  36. 'mny4': 4,
  37. 'tm4': 45,
  38. 'pulse_width': 50,
  39. 'pulse_inter': 500,
  40. 'pulse_idle': 1,
  41. 'coin': 0,
  42. 'coin_yed': 0,
  43. 'total_coin': 0,
  44. 'pay_cnt': 0,
  45. 'cycle': 300,
  46. 'report_set': 1,
  47. 'max_coin': 4,
  48. 'current_date': 100,
  49. 'imei': "1234567890",
  50. #: CSQ Values: Received Signal Strength Indication (<rssi>)
  51. 'csq': 30,
  52. 'status': 0
  53. }
  54. def from_lua_to_py(text):
  55. result = {}
  56. for line in text.strip('{}').split(','):
  57. key, value = line.strip().split('=')
  58. result[key.strip()] = value.strip()
  59. return result
  60. # payload
  61. def handshake_payload(imei):
  62. return json.dumps(
  63. {
  64. 'cmd': 200,
  65. #: seq 为遗留版本废弃值, 其余都省略
  66. 'seq': 23,
  67. 'IMEI': imei,
  68. 'mf': "rf-sensing",
  69. 'soft_ver': "v1.5",
  70. 'hw_ver': "v2.0",
  71. 'cycle': SMART_BOX_PARA['cycle'],
  72. 'coin': SMART_BOX_PARA['coin'],
  73. 'coin_yed': SMART_BOX_PARA['coin_yed'],
  74. 'total_coin': SMART_BOX_PARA['total_coin'],
  75. 'pay_cnt': SMART_BOX_PARA['pay_cnt'],
  76. 'status': SMART_BOX_PARA['status'],
  77. 'signal': 22,
  78. 'max_coin': SMART_BOX_PARA['max_coin'],
  79. 'pwm_wid': SMART_BOX_PARA['pulse_width'],
  80. 'pwm_inter': SMART_BOX_PARA['pulse_inter'],
  81. 'pwm_idle': SMART_BOX_PARA['pulse_idle'],
  82. 'ip1': SMART_BOX_PARA['ip_addr'],
  83. 'port1': SMART_BOX_PARA['port'],
  84. 'mny1': SMART_BOX_PARA['mny1'],
  85. 'tm1': SMART_BOX_PARA['tm1'],
  86. 'mny2': SMART_BOX_PARA['mny2'],
  87. 'tm2': SMART_BOX_PARA['tm2'],
  88. 'mny3': SMART_BOX_PARA['mny3'],
  89. 'tm3': SMART_BOX_PARA['tm3'],
  90. 'mny4': SMART_BOX_PARA['mny4'],
  91. 'tm4': SMART_BOX_PARA['tm4']
  92. }
  93. )
  94. def get_info_payload(imei):
  95. return json.dumps(
  96. {
  97. 'cmd': 201,
  98. 'rst': 0,
  99. 'IMEI': imei,
  100. 'coin': SMART_BOX_PARA['coin'],
  101. 'coin_yed': SMART_BOX_PARA['coin_yed'],
  102. 'cycle': SMART_BOX_PARA['cycle'],
  103. 'hw_ver': 'v2.0',
  104. 'ip1': SMART_BOX_PARA['ip_addr'],
  105. 'max_coin': SMART_BOX_PARA['max_coin'],
  106. 'mf': 'rf-sensing',
  107. 'mny1': SMART_BOX_PARA['mny1'],
  108. 'mny2': SMART_BOX_PARA['mny2'],
  109. 'mny3': SMART_BOX_PARA['mny3'],
  110. 'mny4': SMART_BOX_PARA['mny4'],
  111. 'pay_cnt': SMART_BOX_PARA['pay_cnt'],
  112. 'port1': SMART_BOX_PARA['port'],
  113. 'pwm_idle': SMART_BOX_PARA['pulse_idle'],
  114. 'pwm_inter': SMART_BOX_PARA['pulse_inter'],
  115. 'pwm_wid': SMART_BOX_PARA['pulse_width'],
  116. 'signal': SMART_BOX_PARA['csq'],
  117. 'soft_ver': 'fw_ver',
  118. 'status': SMART_BOX_PARA['status'],
  119. 'tm1': SMART_BOX_PARA['tm1'],
  120. 'tm2': SMART_BOX_PARA['tm2'],
  121. 'tm3': SMART_BOX_PARA['tm3'],
  122. 'tm4': SMART_BOX_PARA['tm4'],
  123. 'total_coin': SMART_BOX_PARA['total_coin']
  124. }
  125. )
  126. def mobile_pay_init_payload(imei):
  127. return json.dumps(
  128. {
  129. 'cmd': 203,
  130. 'IMEI': imei,
  131. 'rst': 0
  132. }
  133. )
  134. def mobile_pay_finish_payload(imei, pay):
  135. return json.dumps(
  136. {
  137. 'cmd': 204,
  138. 'IMEI': imei,
  139. 'app_pay': pay,
  140. 'status': 1
  141. }
  142. )
  143. def put_coin_payload(imei):
  144. return json.dumps(
  145. {
  146. 'cmd': 205,
  147. 'IMEI': SMART_BOX_PARA['imei'],
  148. 'coin': 1,
  149. 'status': 1,
  150. 'today_coin': SMART_BOX_PARA['coin'],
  151. 'total_coin': SMART_BOX_PARA['total_coin']
  152. }
  153. )
  154. def heartbeat_payload(imei):
  155. return json.dumps(
  156. {
  157. 'cmd': 207,
  158. 'IMEI': imei,
  159. 'coin': 0,
  160. 'total_coin': 0,
  161. 'pay_cnt': 0,
  162. 'status': 0,
  163. 'signal': 20
  164. }
  165. )
  166. def offline_payload(imei):
  167. return json.dumps(
  168. {
  169. 'cmd': 208,
  170. 'IMEI': imei,
  171. 'offline': 1
  172. }
  173. )
  174. ## handlers
  175. class DeviceProtocolHandler(BaseProtocolHandler):
  176. def __init__(self, client):
  177. self._client = client # type: MqttClient
  178. def handle_200(self, payload):
  179. # type: (dict)->None
  180. pass
  181. def handle_201(self, payload):
  182. # type: (dict)->None
  183. self._client.publish(
  184. topic=get_server_topic(imei=payload['IMEI'], cmd=CMD.GET_INFO),
  185. payload=get_info_payload(imei=payload['IMEI'])
  186. )
  187. def handle_202(self, payload):
  188. # type: (dict)->None
  189. pass
  190. def handle_203(self, payload):
  191. # type: (dict)->None
  192. self._client.publish(
  193. topic=get_server_topic(imei=payload['IMEI'], cmd=CMD.MOBILE_PAY_INIT),
  194. payload=mobile_pay_init_payload(imei=payload['IMEI'])
  195. )
  196. def handle_204(self, payload):
  197. # type: (dict)->None
  198. pass
  199. def handle_205(self, payload):
  200. # type: (dict)->None
  201. pass
  202. def handle_206(self, payload):
  203. # type: (dict)->None
  204. pass
  205. def handle_207(self, payload):
  206. # type: (dict)->None
  207. pass
  208. def handle_208(self, request):
  209. # type: (dict)->None
  210. pass
  211. def handle_heartbeat(client):
  212. while True:
  213. client.publish(topic=get_server_topic(imei=DEFAULT_DEVICE_IMEI, cmd=CMD.HEARTBEAT),
  214. payload=heartbeat_payload(imei=DEFAULT_DEVICE_IMEI))
  215. time.sleep(30)
  216. def on_connect(client, userdata, flags, rc):
  217. # type: (MqttClient, dict, int, dict)->None
  218. logger.info('connected to (%s, %d)' % (MQTT_HOSTNAME, MQTT_PORT))
  219. logger.info('client: {}'.format(client))
  220. logger.info('userdata: {}'.format(userdata))
  221. logger.info('flags: {}'.format(flags))
  222. logger.info('rc: {}'.format(rc))
  223. def on_message(client, userdata, message):
  224. message = json.loads(bytes.decode(message.payload))
  225. logger.info('simdev client: {}'.format(client))
  226. logger.info('simdev userdata: {}'.format(userdata))
  227. logger.info('simdev message: {}'.format(message))
  228. handler = DeviceProtocolHandler(client)
  229. handler.handle(payload=message)
  230. def run():
  231. client = MqttClient('simdev') # type: MqttClient
  232. client.on_connect = on_connect
  233. client.on_message = on_message
  234. client.connect(MQTT_HOSTNAME, MQTT_PORT)
  235. heartbeat_thread = threading.Thread(target=handle_heartbeat, args=(client,))
  236. heartbeat_thread.setDaemon(True)
  237. heartbeat_thread.start()
  238. client.subscribe(topic=get_device_topic(imei=DEFAULT_DEVICE_IMEI, cmd=MULTI_LEVEL_ALL))
  239. client.loop_forever()
  240. if __name__ == '__main__':
  241. run()