# coding=utf-8 import csv import os, sys import uuid import datetime import pandas import simplejson as json from django.conf import settings from base import init_env env = sys.argv[1] os.environ.setdefault('DJANGO_SETTINGS_MODULE', env) init_env(interactive=False) from apilib.utils_mqtt import get_share_prefix from apps.web.constant import Const, MQTT_GROUP from apps.web.core.mqtt_client import MqttClient from apps.web.device.models import Device class M(MqttClient): def __init__(self, *args, **kwargs): super(M, self).__init__(*args, **kwargs) self.powerData = [] @staticmethod def on_connect_func(client, *args, **kwargs): device_topic = get_share_prefix(MQTT_GROUP.event, Const.SERVER_TOPIC_PREFIX)+'/865650048394338'+"/100" client.subscribe(device_topic, qos=Const.MQTT_QOS) print "on connect ok" @staticmethod def on_message_func(client, obj, msg): msgDict = json.loads(bytes.decode(msg.payload)) data = msgDict.get("data") handFunc = client.dispatch(msgDict) if not handFunc: return client.powerData = handFunc(data) print client.powerData client.collect_call_back(client.powerData) @staticmethod def handle_jiu_hen_data(data): needData = data[10:-2] dataList = list() timeStr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") while needData: port = int(needData[:2], 16) status = needData[2:4] chargeTime = int(needData[4:8], 16) power = int(needData[8:12], 16) elec = int(needData[12:16], 16) needData = needData[16:] dataList.append( { "port": port, "status": status, "chargeTime": chargeTime, "elec": elec, "power": power, "timeStr": timeStr } ) return dataList @staticmethod def handle_dian_chuan_data(data): needData = data[18:-2] timeStr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 继电器状态字节 statusData = needData[6:10] # 功率字节 powerData = needData[10: 50] # 剩余时间字节 timeData = needData[50:90] dataList = [] statusData = "{:0>10}".format(bin(int(statusData, 16)).replace("0b", "")) for i in xrange(10): dataList.append( { "port": i + 1, "status": int(statusData[i]), "chargeTime": int(timeData[i * 4: (i + 1) * 4], 16), "elec": 0, "power": int(powerData[i * 4: (i + 1) * 4], 16), "timeStr": timeStr } ) return dataList @staticmethod def get_jiu_hen_cmd(data): return data[4:6] @staticmethod def get_dian_chuan_cmd(data): return data[4:6] def dispatch(self, msgDict): FUNC_MAP = { "100210_24": self.handle_dian_chuan_data, "100202_21": self.handle_jiu_hen_data } CMD_MAP = { "100202": self.get_jiu_hen_cmd, "100210": self.get_dian_chuan_cmd } devNo = msgDict.get("IMEI", "") dev = Device.get_dev(devNo) if not dev: return driverCode = dev.get("devType", dict()).get("code") if not driverCode: return cmdFunc = CMD_MAP.get(driverCode) if not cmdFunc: return cmd = cmdFunc(msgDict.get("data", "")) _key = "{}_{}".format(driverCode, cmd) return FUNC_MAP.get(_key) class DrawPower(object): def __init__(self, path=None): if path is None: path = "power.csv" self.path = path self.client = M(client_id='webapp_'+str(uuid.uuid1())) self.client.collect_call_back = self.save_data def save_data(self, dataList): if not dataList or not len(dataList): return flag = os.path.exists(self.path) with open(self.path, "ab+") as f: fieldnames = dataList[0].keys() writer = csv.DictWriter(f, fieldnames=fieldnames) if not flag: writer.writeheader() writer.writerows(dataList) def read_data(self): return pandas.read_csv(self.path) def draw(self, port=None, allPorts=10): print "drawing......" if port: # data = self.read_data()[port-1: : allPorts] data = self.read_data() ax = data.plot(y=["power", "chargeTime"], x="timeStr") fig = ax.get_figure() fig.savefig("{}.png".format(self.path.split(".")[0])) else: for i in xrange(allPorts): data = self.read_data()[i:: allPorts] ax = data.plot(y=["power", "chargeTime"], x="timeStr") fig = ax.get_figure() fig.savefig("{}-{}.png".format(self.path.split(".")[0], i+1)) def run(self): try: self.client.on_message = self.client.on_message_func self.client.on_connect = self.client.on_connect_func self.client.connect(settings.MQTT_HOSTNAME, settings.MQTT_PORT, 60) print settings.MQTT_HOSTNAME print settings.MQTT_PORT self.client.loop_forever() finally: self.client.disconnect() self.client.close() if __name__ == '__main__': d = DrawPower("1600601534269816.csv") # d.run() d.draw(1)