def readpara3(DI): strdata = '' # 电流互感器变比 # 电压互感器变比 if DI[3] == 0x06: strdata = para3cfg['电流互感器变比'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x07: strdata = para3cfg['电压互感器变比'] strdata = pfun._strReverse(strdata) return strdata
def dl645_makeframe(dt): # datavalue 转换 if 'datavalue' not in dt or dt['datavalue'] == None or len( dt['datavalue']) == 0: dt['data'] = [0x02] dt['ctrl'] |= 0xC0 else: dt['data'] += fat.str2hex(dt['datavalue'], 0) # 计算长度 dlen = len(dt['data']) dt['dlen'] = fat.hex2str([dlen], 0) dt['ctrl'] = fat.hex2str([dt['ctrl'] | 0x80], 0) dt['addr'] = pfun._strReverse(dt['addr']) dt['data'] = fat.hex2str(dt['data'], 1) # hex frame = '68' + dt['addr'] + '68' + dt['ctrl'] + dt['dlen'] + dt[ 'data'] # + dt['cs'] + '16' # 计算CRC dt['cs'] = pfun.calcCheckSum(frame) frame += dt['cs'] + '16' # print('Send:', frame) # 字节间增加空格 framespace = '' for i in range(0, len(frame), 2): framespace += frame[i:i + 2] + ' ' return framespace
def dl645_dealframe(frame): frame = frame.replace(' ', '') if len(frame) < MIN_LEN_645FRAME: return False, None frame = frame.upper() dt = {'addr': '', 'ctrl': '', 'data': ''} for i in range(0, len(frame), 2): if frame[i:i + 2] == '68' and frame[( i + POS_64507_HEAD2):(i + POS_64507_HEAD2) + 2] == '68': dataLen = int(frame[(i + POS_64507_LEN):(i + POS_64507_LEN + 2)], 16) * 2 if dataLen + POS_64507_LEN < len(frame): frameLen = i + dataLen + POS_64507_LEN checkSum = calcCheckSum(frame[i:(frameLen + 2)]) checkSum = checkSum[-2:] checkSum = checkSum.upper() if checkSum == frame[frameLen + 2:frameLen + 4] and \ frame[frameLen + 4:frameLen + 6] == '16': addr = frame[i + POS_64507_ADDR:i + POS_64507_ADDR + 12].upper() dt['addr'] = pfun._strReverse(addr) # dt['ctrl'] = frame[i + POS_64507_CTRL:i + POS_64507_CTRL + 2] dt['ctrl'] = int( frame[i + POS_64507_CTRL:i + POS_64507_CTRL + 2], 16) # dt['data'] = frame[i + POS_64507_DATA:i + POS_64507_DATA + dataLen] datastr = frame[i + POS_64507_DATA:i + POS_64507_DATA + dataLen] dt['data'] = fat.str2hex(datastr, 1) if dt['ctrl'] & 0x80 == 0: # 只响应抄读帧 return True, dt return False, None
def readpara2(DI): strdata = '' # 年时区数 p≤14 # 日时段表数 q≤8 # 日时段数(每日切换数) m≤14 # 费率数 k≤63 # 公共假日数 n≤254 # 谐波分析次数 # 梯度数 if DI[3] == 0x01: strdata = para2cfg['年时区数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x02: strdata = para2cfg['日时段表数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x03: strdata = para2cfg['日时段数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x04: strdata = para2cfg['费率数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x05: strdata = para2cfg['公共假日数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x06: strdata = para2cfg['谐波分析次数'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x07: strdata = para2cfg['梯度数'] strdata = pfun._strReverse(strdata) return strdata
def upgradeRecvDataToMap(bmapstr, uplist): bmapstr = pfun._strReverse(bmapstr) for i in range(0, len(bmapstr), 2): b = bmapstr[i:i + 2] n = int(b, 16) for j in range(8): if n & (1 << j): uplist["bmap"][i * 4 + j] = 1 else: uplist["bmap"][i * 4 + j] = 0
def upgradeRecvDataToMap(index, bmapstr, self): bmapstr = pfun._strReverse(bmapstr) for i in range(0, len(bmapstr), 2): b = bmapstr[i:i + 2] n = int(b, 16) for j in range(8): if n & (1 << j): self.uplist["bmap"][index*512 + i * 4 + j] = 1 else: self.uplist["bmap"][index*512 + i * 4 + j] = 0
def dl645_str2nxx(s, n): slen = int(len(s) / 2 / n) # 字符串两字节, 数据4字节 dl = [] j = 0 for i in range(slen): d = s[j:j + 2 * n] d = pfun._strReverse(d) dl += [d] j += 2 * n return dl
def dl645_x_xxx2hex(e, s=0): if s == 1 and e < 0: # 有符号 strhex = '00000000' + str(int(e * -1000)) s = str(int(strhex[-4], 10) | 0x8) # 最高字节 | 0x80 表示符号位 strhex = s + strhex[-3:] else: strhex = '00000000' + str((int(e * 1000))) strhex = strhex[-4:] strhex = pfun._strReverse(strhex) return strhex
def unsigned_hex_str2signed(d): if min(d.lower()) == 'f': return 0 d = pub._strReverse(d) try: a = int(d, 16) except: a = 0 print(unsigned_hex_str2signed.__name__, 'err') return a
def Mex_MakeDataLen(dt): if 0x80 < dt['datalen'] <= 0xFF: s = 0x81 s = hex(s)[-2:] + hex(dt['datalen']).replace('0x', '0000')[-2:] elif 0xFF < dt['datalen'] <= 0xFFFF: s = 0x82 n = hex(dt['datalen']).replace('0x', '0000')[-4:] n = pfun._strReverse(n) s = hex(s)[-2:] + n else: s = hex(dt['datalen']).replace('0x', '0000')[-2:] return s
def VARIANT_01(d): l = [] n = 0 rn, ld = OOP_WORD4V(d[n:]) # 电压 n += rn l += ld rn, ld = OOP_INT4V(d[n:]) # 电流 n += rn l += ld # 零线电流 l += [pub._strReverse(d[n:n + 8])] return l
def Mex_DataLenParse(d, dt): try: a = int(d[:2], 16) except: a = 0 if a & 0x80: a &= 0x7F sd = pfun._strReverse(d[2:a * 2 + 2]) # 长度域字符串倒序 dt['datalen'] = int(sd, 16) dl = (a + 1) * 2 else: dt['datalen'] = a dl = 2 return dl
def dl645_xxx_xxx2hex(e, s=0, t=BCD): if s == 1 and e < 0: # 有符号 strhex = '00000000' + str(int(e * -1000)) s = str(int(strhex[-6], 10) | 0x8) # 最高字节 | 0x80 表示符号位 strhex = s + strhex[-5:] else: if t == HEX: strhex = hex(int(e * 1000)) strhex = strhex.replace('0x', '00000000') else: strhex = '00000000' + str((int(e * 1000))) strhex = strhex[-6:] strhex = pfun._strReverse(strhex) return strhex
def upgradeSendFile(self, i): sindex = hex(i + 1).replace("0x", "0000")[-4:] prtl = judgePrtl("LY_JSON") data = "04A00501" # print(value) value = pfun._strReverse(self.flist[i]) # print(value) value = self.FILE_MANUIDEN + "#" + self.FILE_DEV_TYPE + "#" + self.FILE_PACK_NUM + "#" + sindex + "#" + value # 字节倒序 List = dict(zip([data], [value])) VList = [] VList += ["UpDate"] VList += [List] senddata = prtl2Make(prtl, VList) return senddata
def signed_hex_str2signed(d): if min(d.lower()) == 'f': return 0 d = pub._strReverse(d) try: a = int(d, 16) except: a = 0 print(signed_hex_str2signed.__name__, 'err') if a > 0x80000000: b = -(~a + 2) d = -0xffffffff + b else: d = a return d
def readpara1(DI): strdata = '' # YYMMDDWW 4 日期及星期(其中0代表星期天) # hhmmss 3 时间 # NN 1 最大需量周期 # NN 1 滑差时间 # XXXX 2 校表脉冲宽度 # YYMMDDhhmm 5 两套时区表切换时间 # YYMMDDhhmm 5 两套日时段表切换时间 # YYMMDDhhmm 5 两套分时费率切换时间 # YYMMDDhhmm 5 两套阶梯切换时间 if DI[3] == 0x01: # 日期及星期(其中0代表星期天) t = time.time() dt_obj = datetime.datetime.fromtimestamp(t) strdata = dt_obj.strftime("0%w%d%m%y") elif DI[3] == 0x02: # 时间 t = time.time() dt_obj = datetime.datetime.fromtimestamp(t) strdata = dt_obj.strftime("%S%M%H") elif DI[3] == 0x03: strdata = para1cfg['最大需量周期'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x04: strdata = para1cfg['滑差时间'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x05: strdata = para1cfg['最大需量周期'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x06: strdata = para1cfg['两套时区表切换时间'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x07: strdata = para1cfg['两套日时段表切换时间'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x08: strdata = para1cfg['两套分时费率切换时间'] strdata = pfun._strReverse(strdata) elif DI[3] == 0x09: strdata = para1cfg['两套阶梯切换时间'] strdata = pfun._strReverse(strdata) return strdata
def dl645_xxx_x2hex(e): strhex = '00000000' + str((int(e * 10))) strhex = strhex[-4:] strhex = pfun._strReverse(strhex) return strhex
def frame_head_process(s): at = {'PRIORITY': 0, 'PRM': 0, 'INDEX': 0, 'LABEL': 0, 'SOURCE': '', 'DESTINATION': '', 'TAG': 0, 'Length': 0, 'Payload': '' } s = s.replace(' ', '') s = s.replace(':', '') s = s.replace(';', '') s = s.replace(':', '') s = s.replace(';', '') if len(s) < 16: at['err'] = 'frame len error' return at # PRIORITY PRM 1 # 优先级(数值越小优先级越高,0为最高优先级) # 启动标志位(PRM=1,表示启动) priprm = int(s[:2], 16) at['PRM'] = priprm & 0x01 at['PRIORITY'] = priprm >> 1 s = s[2:] # INDEX 2 # 消息序号(从0循环递增,响应消息同请求消息保持一致) at['INDEX'] = int(pub._strReverse(s[:4]), 16) s = s[4:] # LABEL 2 # 消息标签(发送方附加标签,响应时带回) at['LABEL'] = int(pub._strReverse(s[:4]), 16) s = s[4:] # SOURCE N # 消息发送方名称,字符串,以0结尾,命名规范见5.2 end_source = s.find('00') if end_source > 0: b = bytes.fromhex(s[:end_source]) at['SOURCE'] = str(b, encoding="utf-8") else: at['err'] = 'SOURCE err' return at s = s[(end_source + 2):] # DESTINATION N # 消息接收方名称,字符串,以0结尾,命名规范见5.2 end_dest = s.find('00') if end_dest > 0: b = bytes.fromhex(s[:end_dest]) at['DESTINATION'] = str(b, encoding="utf-8") else: at['err'] = 'DESTINATION err' return at s = s[(end_dest + 2):] if len(s) < 8: at['err'] = 'TAG len error' return at # MSG’s—TAG 4 # 消息接口ID(消息接口定义见第7章) at['TAG'] = pub._strReverse(s[:8]) s = s[8:] if len(s) < 2: at['err'] = 'Length error' return at # MSG’s—Length N # 消息有效载荷长度,采用可变长度编码(A-XDR) l = int(s[:2], 16) if l & 0x80: ln = l & 0x7F ln = ln * 2 + 2 try: at['Length'] = int(s[2:ln], 16) except: at['Length'] = 0 else: ln = 2 at['Length'] = l s = s[ln:] if len(s) != at['Length'] * 2: at['err'] = 'Payload Length error' # MSG’s—Payload N # 有效载荷,即消息数据单元(定义见附录) at['Payload'] = s return at