smart_box.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import os, sys
  4. import random
  5. PROJECT_ROOT = os.path.join(os.path.abspath(os.path.split(os.path.realpath(__file__))[0] + "/.."), '..')
  6. sys.path.insert(0, PROJECT_ROOT)
  7. import signal
  8. import threading
  9. import simplejson as json
  10. import time
  11. from library.paho.mqtt import client
  12. class MqttClient(client.Client):
  13. def close(self):
  14. if self._sock:
  15. self._sock.close()
  16. self._sock = None
  17. if self._sockpairR:
  18. self._sockpairR.close()
  19. self._sockpairR = None
  20. if self._sockpairW:
  21. self._sockpairW.close()
  22. self._sockpairW = None
  23. def publish_207(simulator):
  24. # type: (SimulatorSmartBox)->None
  25. print('publish_207')
  26. simulator.today_coins = simulator.today_coins + random.randint(1,5)
  27. simulator.publish_message(cmd = 207, payload = {
  28. 'signal': 31,
  29. 'cmd': 207,
  30. 'IMEI': simulator.imei,
  31. 'coin': simulator.today_coins
  32. })
  33. simulator.start_heart_beat()
  34. simulators = []
  35. def do_ctrl_c(signum, frame):
  36. print('You choose to stop me.')
  37. for simulator in simulators:
  38. simulator.exit()
  39. exit(0)
  40. signal.signal(signal.SIGINT, do_ctrl_c)
  41. signal.signal(signal.SIGTERM, do_ctrl_c)
  42. class SimulatorSmartBox(object):
  43. def __init__(self, mqtt_server, mqtt_port, mqtt_user, mqtt_pwd, imei):
  44. simulators.append(self)
  45. self.mqtt_server = mqtt_server
  46. self.mqtt_port = mqtt_port
  47. self.mqtt_user = mqtt_user
  48. self.mqtt_pwd = mqtt_pwd
  49. self.imei = imei
  50. self.mqtt_client = MqttClient(self.imei)
  51. self.pwm_wid = 40
  52. self.pwm_inter = 500
  53. self.pwm_idle = 1
  54. self.port = mqtt_port
  55. self.server = mqtt_server
  56. self.poweron_reason = 3
  57. self.soft_ver = '6.12.100'
  58. self.today_coins = 0
  59. reponse_201 = self.get_device_info()
  60. reponse_201.update({
  61. 'rst': 0,
  62. 'cmd': 201
  63. })
  64. self.response = {
  65. 201: reponse_201,
  66. 203: {
  67. 'cmd': 203,
  68. 'IMEI': self.imei,
  69. 'rst': 0
  70. }
  71. }
  72. def publish_message(self, cmd, payload, qos = 0):
  73. self.mqtt_client.publish(topic = 'server/{imei}/{cmd}'.format(imei = self.imei, cmd = cmd),
  74. payload = json.dumps(payload), qos = qos)
  75. @property
  76. def driverCode(self):
  77. assert 'must initial'
  78. @property
  79. def driverVersion(self):
  80. return 'v1.0.0'
  81. def start(self):
  82. self.mqtt_client.on_message = self.on_message
  83. self.mqtt_client.on_connect = self.on_connect
  84. self.mqtt_client.on_disconnect = self.on_disconnect
  85. self.mqtt_client.on_subscribe = self.on_subscribe
  86. self.mqtt_client.username_pw_set(self.mqtt_user, self.mqtt_pwd)
  87. self.mqtt_client.will_set(topic = "server/{imei}/208".format(imei = self.imei),
  88. payload = json.dumps({
  89. 'cmd': 208,
  90. 'IMEI': self.imei,
  91. 'offline': 1
  92. }))
  93. self.mqtt_client.connect(self.mqtt_server, self.mqtt_port, 60)
  94. self.mqtt_client.loop_forever()
  95. def exit(self):
  96. self.mqtt_client._thread_terminate = True
  97. self.mqtt_client.disconnect()
  98. exit(0)
  99. def connect_cb(self, client, userdata, flags, rc):
  100. pass
  101. def disconnect_cb(self, client, userdata):
  102. exit(0)
  103. @property
  104. def device_extend_info(self):
  105. assert 'must initial'
  106. def get_device_info(self):
  107. device_info = {
  108. 'IMEI': self.imei,
  109. 'signal': 31,
  110. 'pwm_wid': 50,
  111. 'pwm_inter': self.pwm_inter,
  112. 'pwm_idle': self.pwm_idle,
  113. 'ip1': self.server,
  114. 'port1': self.port,
  115. 'poweron_reason': self.poweron_reason,
  116. 'soft_ver': self.soft_ver,
  117. 'mf': 'vivestone',
  118. 'coreVer': 'Luat_V0038_8955_SSL'
  119. }
  120. device_info.update(self.device_extend_info)
  121. return device_info
  122. def start_heart_beat(self):
  123. t = threading.Timer(30, publish_207, (self,))
  124. t.start()
  125. def do_message(self, cmd, payload):
  126. # type: (int, dict)->None
  127. if cmd == 200:
  128. return
  129. response = self.response[cmd]
  130. if cmd in [201, 203]:
  131. self.publish_message(
  132. cmd = cmd,
  133. payload = response)
  134. return
  135. def on_subscribe(self, client, userdata, mid, granted_qos):
  136. print('receive disconnect message. client = %s; userdata = %s; mid = %s, granted_qos = %s' % (
  137. str(client), str(userdata), mid, granted_qos))
  138. topic = "server/{imei}/200".format(imei = self.imei)
  139. shake_message = self.get_device_info()
  140. shake_message["cmd"] = 200
  141. shake_message["timestamp"] = long(time.time() * 1000)
  142. self.publish_message(cmd = 200, payload = shake_message, qos = 1)
  143. self.start_heart_beat()
  144. def on_disconnect(self, client, userdata, result):
  145. print('receive disconnect message. client = %s; userdata = %s; result = %s' % (str(client), str(userdata), result))
  146. client.unsubscribe('smart_box/{imei}/+'.format(imei = self.imei))
  147. def on_connect(self, client, userdata, flags, rc):
  148. print('receive connect message. client = %s; userdata = %s; flags = %s, rc = %s' % (
  149. str(client), str(userdata), flags, rc))
  150. topic = 'smart_box/{imei}/+'.format(imei = self.imei)
  151. client.subscribe(topic = topic, qos = 0)
  152. self.connect_cb(client, userdata, flags, rc)
  153. def on_message(self, client, userdata, message):
  154. print('receive data message. client = %s; userdata = %s; message = %s' % (
  155. str(client), str(userdata), message))
  156. msgDict = json.loads(bytes.decode(message.payload))
  157. print('receive msessage = {}'.format(msgDict))
  158. imei = msgDict['IMEI']
  159. if imei != self.imei:
  160. print 'is not my imei. my %s != %s' % (self.imei, imei)
  161. return
  162. cmd = int(msgDict.pop('cmd'))
  163. self.do_message(cmd, msgDict)
  164. def on_disconnect(self, client, userdata, rc):
  165. print('receive disconnect message. client = %s; userdata = %s; rc = %s' % (
  166. str(client), str(userdata), rc))
  167. self.disconnect_cb(client, userdata)