""" 主站通信脚本 mqtt协议 """ import time import random import logging from paho.mqtt import client as mqtt_client from device.LaminaAdapter import ParamMap_LaminaAdapter from device.DeviceMQTT import DeviceMQTT from device.function import protocols MainStation = { "broker": '123.249.75.235', "port": 1883, "account": ('TTE0101TC2311000003', 'qh10579lcb7au8o2') } ParamMap_LaminaCombiner = { # 1 - Hex # 2 - Int16[ratio] # 3 - lnt32[ratio] # 4 - str # 5 - addr # 6 - float 0x000: ["系统型号", 4, 16], 0x010: ["程序版本", 4, 16], 0x100: ["主板温度" , 2, 10], 0x101: ["输入电流1" , 2, 100], 0x102: ["输入电流2" , 2, 100], 0x103: ["输入电流3" , 2, 100], 0x104: ["输入电流4" , 2, 100], 0x105: ["输入电流5" , 2, 100], 0x106: ["输入电流6" , 2, 100], 0x107: ["输入电流7" , 2, 100], 0x108: ["输入电流8" , 2, 100], 0x11A: ["适配器01交互滴答", 2, 1], 0x11B: ["适配器02交互滴答", 2, 1], 0x11C: ["适配器03交互滴答", 2, 1], 0x11D: ["适配器04交互滴答", 2, 1], 0x11E: ["适配器05交互滴答", 2, 1], 0x11F: ["适配器06交互滴答", 2, 1], 0x120: ["适配器07交互滴答", 2, 1], 0x121: ["适配器08交互滴答", 2, 1], 0x122: ["适配器09交互滴答", 2, 1], 0x123: ["适配器10交互滴答", 2, 1], 0x124: ["适配器11交互滴答", 2, 1], 0x125: ["适配器12交互滴答", 2, 1], 0x126: ["适配器13交互滴答", 2, 1], 0x127: ["适配器14交互滴答", 2, 1], 0x128: ["适配器15交互滴答", 2, 1], 0x129: ["适配器16交互滴答", 2, 1], 0x12A: ["路由拓扑从节点个数", 2, 1], 0x12B: ["路由管理状态机状态", 2, 1], 0x12C: ["正在升级的适配器序号", 2, 1], 0x200: ["从板温度" , 2, 10], 0x201: ["输入电流9" , 2, 100], 0x202: ["输入电流10" , 2, 100], 0x203: ["输入电流11" , 2, 100], 0x204: ["输入电流12" , 2, 100], 0x205: ["输入电流13" , 2, 100], 0x206: ["输入电流14" , 2, 100], 0x207: ["输入电流15" , 2, 100], 0x208: ["输入电流16" , 2, 100], 0x800: ["设备地址", 5, 3], 0x803: ["时间", 5, 3], 0x806: ["文件记录日志级别", 1], 0x807: ["串口输出日志级别", 1], 0x808: ["日志输出控制字", 1], 0x809: ["mqtt设备编码(deviceID)", 4, 25], 0x822: ["mqtt直流表子设备编码(deviceID)", 4, 25], 0x83B: ["mqtt适配器子设备编码(deviceID)", 4, 25], 0x854: ["报文控制字", 1], 0x855: ["汇流箱类型", 1], 0x856: ["待升级适配器映射", 1], 0x857: ["适配器1地址", 5, 3], 0x85A: ["适配器1线路ID", 1], 0x85B: ["适配器2地址", 5, 3], 0x85E: ["适配器2线路ID", 1], 0x85F: ["适配器3地址", 5, 3], 0x862: ["适配器3线路ID", 1], 0x863: ["适配器4地址", 5, 3], 0x866: ["适配器4线路ID", 1], 0x867: ["适配器5地址", 5, 3], 0x86A: ["适配器5线路ID", 1], 0x86B: ["适配器6地址", 5, 3], 0x86E: ["适配器6线路ID", 1], 0x86F: ["适配器7地址", 5, 3], 0x872: ["适配器7线路ID", 1], 0x873: ["适配器8地址", 5, 3], 0x876: ["适配器8线路ID", 1], 0x877: ["适配器9地址", 5, 3], 0x87A: ["适配器9线路ID", 1], 0x87B: ["适配器10地址", 5, 3], 0x87E: ["适配器10线路ID", 1], 0x87F: ["适配器11地址", 5, 3], 0x882: ["适配器11线路ID", 1], 0x883: ["适配器12地址", 5, 3], 0x886: ["适配器12线路ID", 1], 0x887: ["适配器13地址", 5, 3], 0x88A: ["适配器13线路ID", 1], 0x88B: ["适配器14地址", 5, 3], 0x88E: ["适配器14线路ID", 1], 0x88F: ["适配器15地址", 5, 3], 0x892: ["适配器15线路ID", 1], 0x893: ["适配器16地址", 5, 3], 0x896: ["适配器16线路ID", 1], 0x897: ["档案自适用使能", 1], 0x898: ["档案自适用收集地址时间", 2, 1], 0x899: ["适配器开机时间", 2, 1], 0x89A: ["适配器关机时间", 2, 1], 0x89B: ["有流阈值", 2, 1], 0x89C: ["无流阈值", 2, 1], 0x89D: ["路由组网时间", 2, 1], 0x89E: ["并发抄读最大并发数", 2, 1], 0x89F: ["并发抄读等待回复超时时间", 2, 1], 0x8A0: ["并发抄读数据有效维持时间", 2, 1], 0x8A1: ["输出母线过压阈值", 2, 1], 0x8A2: ["默认电池基准电压", 2, 1], 0x8A3: ["实际电池基准电压", 2, 1], 0x8A4: ["功率限制功能关闭的适配器个数", 2, 1], 0x8A5: ["功率限制功能使关闭的适配器映射", 2, 1], 0x8A6: ["功率限制比率", 2, 1], 0x8A7: ["下挂电表类型", 1], 0x8A8: ["功率限制电池电压回执(差值)", 2, 1], 0x8A9: ["功率恢复电池电压回执(差值)", 2, 1], 0x8AA: ["是否ODM", 1], 0x8AB: ["系统类型", 4, 16], 0x8BB: ["控制器生产厂商", 4, 16], 0x8CB: ["控制器型号", 4, 16], 0x8DB: ["厂家缩写", 4, 4], 0x8DF: ["汇流箱软件版本前缀", 4, 8], 0x8E7: ["适配器软件版本前缀", 4, 8], 0x8EF: ["适配器生产厂商", 4, 8], 0x8F7: ["适配器型号", 4, 16], } class LaminaStation(DeviceMQTT): def __init__(self, device_id, station=None, **kwargs): """ 设备初始化 """ def check_frame_modbus_MultiDevice(frame): """ 多设备帧报文检测 """ frame_block = self.block.copy() if (0x4000 < frame_block['data_addr']) and (frame_block['data_addr'] < 0x6000): """ 报文来自于适配器 """ dev_id = (frame_block['data_addr'] - 0x4000) // 0x200 frame_block['data_addr'] -= 0x4000 + 0x200 * dev_id frame_block['data_define'] = ParamMap_LaminaAdapter if ((frame_block['data_addr'] + frame_block['data_len']) >= 0x200): raise ValueError("Data addresses across boundaries") return protocols.check_frame_modbus(frame, frame_block) if station is None: station = MainStation super().__init__(**station, device_id=device_id, callbacks=(lambda : protocols.make_frame_modbus(self.block), check_frame_modbus_MultiDevice), **kwargs) self.block = { 'addr_dev' : 0x00, 'data_define': ParamMap_LaminaCombiner, } def frame_read_adapter(self, id, daddr, dlen) -> bool: """ 读取适配器数据 """ return self.frame_read(0x4000 + id * 0x200 + daddr, dlen) def frame_read(self, daddr=0x60, dlen=0x30) -> bool: self.block['type'] = 'read' self.block['data_addr'] = daddr self.block['data_len'] = dlen return self._transfer_data() def frame_write_one(self, daddr=0x85, dval=-900) -> bool: self.block['type'] = 'write_one' self.block['data_addr'] = daddr # item_coff = self.block['data_define'][daddr][2] if len(self.block['data_define'][daddr]) > 2 else 1 self.block['data_val'] = int(dval) # * item_coff return self._transfer_data() def frame_write_dual(self, daddr=0x91, dval=600) -> bool: self.block['type'] = 'write_dual' self.block['data_addr'] = daddr # item_coff = self.block['data_define'][daddr][2] if len(self.block['data_define'][daddr]) > 2 else 1 self.block['data_val'] = int(dval) # * item_coff return self._transfer_data() def frame_write_str(self, daddr=0x82, dval=[0x06, 0x05, 0x04, 0x03, 0x02, 0x01]) -> bool: self.block['type'] = 'write_str' self.block['data_addr'] = daddr self.block['data_val'] = dval return self._transfer_data() if __name__ == '__main__': mode_config = { "dev1": {'device_id': 'TTE0101DX2406140046', # 张家港鹿苑北单管塔 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev2": {'device_id': 'TTE0101DX2409230113', # 常来东-光伏 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev3": {'device_id': 'TTE0101DX2406270041', # 大丰市镇区补点139 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev4": {'device_id': 'TTE0101DX2407020114', # 大丰大龙南 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev5": {'device_id': 'TTE0101DX2407010082', # 大丰草堰镇双垛村 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev6": {'device_id': 'TTE0101DX2406140040', # 张家港泗港公落地内爬单管塔 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev7": {'device_id': 'TTE0101DX2406260040', # 常熟河坝落地外爬单管塔 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev8": {'device_id': 'TTE0101DX2407080036', # 昆山好孩子西落地外爬单管塔 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev9": {'device_id': 'TTE0101DX2406140009', # 市区东山镇 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev10": {'device_id': 'TTE0101DX2406270018', # 张家港兆丰北单管塔 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev11": {'device_id': 'TTE0101DX2407290011', # 昆山市吴淞江污水厂基站机房 'frame_print': True, 'time_out': 4, 'retry': 1}, "dev12": {'device_id': 'TTE0101DX2409210071', # 丰顺村铁路搬迁-光伏 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev13": {'device_id': 'TTE0101DX2410110017', # 张家港市福源纺织基站机房 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev14": {'device_id': 'TTE0101DX2406140008', # 张家港乐余良种场落地外爬单管塔 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev15": {'device_id': 'TTE0101DX2406270099', # 张家港塘市东落地景观塔 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev16": {'device_id': 'TTE0101DX2409210027', # 2017-YD:定州北只东 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev17": {'device_id': 'TTE0101DX2406280009', # 壮志村委会-光伏 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev18": {'device_id': 'TTE0101DX2406260013', # 开发区竹行机房-光伏 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev19": {'device_id': 'TTE0101DX2409210093', # 2016-YD:定州北木庄 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev20": {'device_id': 'TTE0101DX2409270062', # 内丘中张村北 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev21": {'device_id': 'TTE0101DX2407080037', # 市区临湖东吴德生 'frame_print': True, 'time_out': 6, 'retry': 1}, "dev22": {'device_id': 'TTE0101DX2406300067', # (新版限功率升级) 'frame_print': True, 'time_out': 6, 'retry': 1}, } dev_lamina = LaminaStation(**mode_config["dev22"]) dev_lamina.frame_read(0x0000, 0x20) time.sleep(2) dev_lamina.frame_read(0x857, 0x40) if not hasattr(__builtins__,"__IPYTHON__"): pass dev_lamina.frame_read(0x400E + 0x200 * (6-1), 0x20) dev_lamina.frame_read(0x4072 + 0x200 * (6-1), 0x03)