# -*- coding: utf-8 -*- # !/usr/bin/env python import random import threading import time from typing import TYPE_CHECKING, Dict from script.simulator.utils import fill_2_hexByte, calc_crc from smart_box import SimulatorSmartBox if TYPE_CHECKING: pass class PortStatus(object): IDLE = 0x01 USING = 0x02 FORBIDDEN = 0x03 FAULT = 0x04 class LoopPortsThread(threading.Thread): def __init__(self, ports): # type: (Ports)->None threading.Thread.__init__(self) self.ports = ports self.exit = False def set_exit(self): self.exit = True def run(self): while True and not self.exit: for port_no, state in self.ports.port_state.iteritems(): # print 'port = {}; status = {}; start_time = {}; end_time = {}; now = {}'.format( # port_no, state['status'], state['start_time'], state['end_time'], int(time.time()) # ) status = state['status'] if status == PortStatus.USING: end_time = state['end_time'] if end_time <= int(time.time()): duration = int(time.time()) - state['start_time'] duration = 0 if duration <= 0 else duration simulator = self.ports.simulator # type: JHDevice left_time = state['left_time'] left_elec = state['left_elec'] data = 'AA091601{}{}{}02'.format(fill_2_hexByte(hex(int(port_no)), 2), fill_2_hexByte(hex(int(left_time)), 4), fill_2_hexByte(hex(int(left_elec)), 4)) data = data + calc_crc(data) simulator.publish_message( 100, { 'ts': int(time.time()), 'IMEI': simulator.imei, 'duration': duration / 60, 'data': data, 'cmd': 100 } ) self.ports.port_state[port_no]['status'] = PortStatus.IDLE self.ports.port_state[port_no]['start_time'] = 0 self.ports.port_state[port_no]['end_time'] = 0 time.sleep(1) class Ports(object): def __init__(self, simulator): # type: (JHDevice)->None self.simulator = simulator # type: JHDevice self.port_state = { 1: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 2: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 3: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 4: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 5: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 6: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 7: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 8: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 9: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 }, 10: { 'status': PortStatus.IDLE, 'start_time': 0, 'end_time': 0 } } def func_0F(self): _data = '55180F010A' for port_no, state in self.port_state.items(): status = state['status'] _data = _data + fill_2_hexByte(hex(int(port_no)), 2) _data = _data + fill_2_hexByte(hex(int(status)), 2) _data = _data + calc_crc(_data) return _data def func_15(self, port): return '550C1501{}00000000FFFFFFFF19'.format(port) class JHDevice(SimulatorSmartBox): def __init__(self, mqtt_server, mqtt_port, mqtt_user, mqtt_pwd, imei): super(JHDevice, self).__init__(mqtt_server, mqtt_port, mqtt_user, mqtt_pwd, imei) self.ports = Ports(self) self.ports_loop_thread = LoopPortsThread(self.ports) self.ports_loop_thread.start() def exit(self): self.ports_loop_thread.set_exit() super(JHDevice, self).exit() def do_message(self, cmd, payload): # type: (int, Dict)->None if cmd >= 210: _data = payload['data'] func = payload['funCode'] if func == '0F' and _data == '00': message = { 'data': self.ports.func_0F() } elif func == '15': message = { 'data': self.ports.func_15(payload['data']) } elif func == '14': port = int(payload['data'][0:2], 16) _money = int(payload['data'][2:6], 16) _time = int(payload['data'][6:10], 16) _elec = int(payload['data'][10:15], 16) _consume_time = 1 _left_time = (_time - _consume_time) _left_elec = int(_elec * float(_left_time) / float(_time)) port_state = self.ports.port_state[port] if port_state['status'] == PortStatus.USING: port_state['end_time'] += _consume_time * 60 else: port_state['status'] = PortStatus.USING port_state['start_time'] = int(time.time()) port_state['end_time'] = port_state['start_time'] + _consume_time * 60 port_state['left_time'] = _left_time port_state['left_elec'] = _left_elec _data = '550514010201' _data = _data + calc_crc(_data) message = { 'data': _data } # 获取参数设置 elif func == '1E': message = { 'data': '551A1E0100B400B41E1E1E03E807D00DAC0DAC3219190101141EFFE0' } else: message = dict() if message and 'rst' not in message: message.update({ 'IMEI': self.imei, 'rst': 0, 'cmd': cmd }) else: message = { 'IMEI': self.imei, 'rst': 1, 'cmd': cmd } return self.publish_message(cmd = cmd, payload = message) else: super(JHDevice, self).do_message(cmd, payload) @property def device_extend_info(self): return { 'driverCode': '100206', 'driverVersion': 'v2.0.2' } class myThread(threading.Thread): # 继承父类threading.Thread def __init__(self, mqtt_server, mqtt_port, mqtt_user, mqtt_pwd, imei): threading.Thread.__init__(self) self.mqtt_server = mqtt_server self.mqtt_port = mqtt_port self.mqtt_user = mqtt_user self.mqtt_pwd = mqtt_pwd self.imei = imei self.setDaemon(False) def run(self): JHDevice(self.mqtt_server, self.mqtt_port, self.mqtt_user, self.mqtt_pwd, self.imei).start() if __name__ == '__main__': imei_list = { 'JH_DUMMY': 'JH_DUMMY_IMEI' } mqtt_server = '211.159.224.10' mqtt_port = 1883 mqtt_user = '20160528@vivestone' mqtt_pwd = 'j429QXqI5CTv' threads = [] for imei in imei_list.values(): thread = myThread(mqtt_server, mqtt_port, mqtt_user, mqtt_pwd, imei) thread.start() threads.append(thread)