package com.sandu.ximon.admin.manager.iot.frame.inner.report; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame; import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame; import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils; import lombok.Data; import lombok.ToString; /** * @author chenjiantian * @date 2021/12/6 18:20 * A5-82-45 * c3充电桩故障码 上报 */ @Data @ToString(callSuper = true) public class A5C3HeartbeatReportInnerFrame extends BaseResponseInnerFrame { // 目标地址 4 private String destinationAddress; // 心跳包数据 private HeartBeatDataPackage heartBeatDataPackage; @Override public A5C3HeartbeatReportInnerFrame transformFrame(String hex) { // 长度不一致时,返回null if (StrUtil.isBlank(hex)) { return null; } // MQTT通信方式(1) setConnectType(hex.substring(0, 2)); // 功能码(1) setFunctionCode(hex.substring(2, 4)); // 负荷长度(2) setPayloadLength(hex.substring(4, 8)); setDestinationAddress(hex.substring(8, 16)); String heartBeatData = hex.substring(8, hex.length() - 8); HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage(); heartBeatDataPackage.transformFrame(heartBeatData); setHeartBeatDataPackage(heartBeatDataPackage); setCrc32(hex.substring(hex.length() - 8)); // 校验CRC32 String frame = hex.substring(2, hex.length() - 8); this.setValidate(CRC32Utils.validateFrame(frame, getCrc32())); return this; } @Data public static class HeartBeatDataPackage implements IResponseInnerFrame { // c3Mac(id hex) private String c3Mac; // 年 private String year; // 月 private String month; // 日 private String day; // 时 private String hour; // 分 private String min; // 秒 private String sec; // 充电桩口 private String chargingPort; // 充电桩口状态位 1.空闲 2.充电中 3.充电中断,等待服务器确认 4.充电结束,等待服务器确认 5.有故障 6.与充电桩对接中 private String statusBit; // 设备温度 0.1℃ private String deviceTemperature; // 电网电压 0.1V private String gridVoltage; // 电网电流 0.1A private String gridCurrent; // 频率 0.01Hz private String frequency; // 功率因素 0.001 private String powerFactor; // 有功功率 0.1KW private String activePower; // 无功功率 0.1KFar private String reactivePower; // 已充电量 0.01KWh private String chargedCapacity; // 预约电量 1KWh private String reservedCapacity; // 剩余金额 0.1元 private String remainingAmount; // 已充时长 private String alreadyChargingTime; @Override public HeartBeatDataPackage transformFrame(String hex) { if (StrUtil.isBlank(hex)) { return null; } this.c3Mac = hex.substring(0, 8); this.year = parseVal(hex.substring(8, 10)); this.month = parseVal(hex.substring(10, 12)); this.day = parseVal(hex.substring(12, 14)); this.hour = parseVal(hex.substring(14, 16)); this.min = parseVal(hex.substring(16, 18)); this.sec = parseVal(hex.substring(18, 20)); this.chargingPort = parseVal(hex.substring(20, 24)); this.statusBit = parseVal(hex.substring(24, 26)); this.deviceTemperature = temperatureTransition(hex.substring(26, 30)) + ""; this.gridVoltage = (parseVal(hex, 30, 34) * 0.01) + ""; this.gridCurrent = (parseVal(hex, 34, 38) * 0.01 + ""); this.frequency = (parseVal(hex, 38, 42) * 0.01 + ""); this.powerFactor = (parseVal(hex, 42, 46) * 0.01 + ""); this.activePower = (parseVal(hex, 46, 50) * 0.01 + ""); this.reactivePower = (parseVal(hex, 50, 54) * 0.01 + ""); this.chargedCapacity = (parseVal(hex, 54, 58) * 0.01 + ""); this.reservedCapacity = (parseVal(hex, 58, 62) * 0.01 + ""); this.remainingAmount = (parseVal(hex, 62, 66) * 0.01 + ""); this.alreadyChargingTime = parseVal(hex.substring(66, 72)); //72-80保留,暂未使用 return this; } private Integer parseVal(String frame, int start, int end) { return Integer.parseInt(frame.substring(start, end), 16); } private String parseVal(String hex) { return Integer.parseInt(hex, 16) + ""; } /** * 将16进制转成2进制,进行补码(反码基础上+1),得到正确数值 * 传入16进制的温度,类型为String * 如F500 */ public Double temperatureTransition(String temperature) { //将传进来的16进制的转为2进制 String twoBinStr = hexStr2BinStr(temperature); if ("1".equals(twoBinStr.substring(0, 1))) { //最高位是1,为负数,将16进制的进行补码,返回 int max = 0b1111111111111111; double result = (max - HexUtil.hexToInt(temperature)) * (-0.01); return result; } else if ("0".equals(twoBinStr.substring(0, 1))) { //最高位是0,正数,直接返回 double result = (HexUtil.hexToInt(temperature)) * (0.01); return result; } // return 0.00; } /** * 16进制字符串转为二进制 */ public String hexStr2BinStr(String hexStr) { if (hexStr == null || hexStr.length() % 2 != 0) { return null; } String bString = "", tmp; for (int i = 0; i < hexStr.length(); i++) { tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexStr.substring(i, i + 1), 16)); bString += tmp.substring(tmp.length() - 4); } return bString; } } }