package com.sandu.ximon.admin.manager.iot.frame.inner.report; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.NumberUtil; 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 van * A7-81-40 * PLC读心跳包 上报 */ @Data @ToString(callSuper = true) public class A7PlcHeartbeatReportInnerFrame extends BaseResponseInnerFrame { // 目标地址 2 private String destinationAddress; // 心跳包数据 104 private HeartBeatDataPackage heartBeatDataPackage; private String originFrame; @Override public A7PlcHeartbeatReportInnerFrame 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, 12)); String heartBeatData = hex.substring(12, 172); 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 { // 年RTC 1 private Integer year; // 月RTC 1 private Integer month; // 日RTC 1 private Integer day; // 时RTC 1 private Integer hour; // 分RTC 1 private Integer min; // 秒RTC 1 private Integer sec; // 设备温度 2 1字节整数1字节小数 private Double deviceTemperature; //@ApiModelProperty("电网相数(单、三相)") private Long phase; //A相电压 //@ApiModelProperty("A相电压") private Double voltageA; //B相电压 //@ApiModelProperty("B相电压") private Double voltageB; //B相电压 //@ApiModelProperty("B相电压") private Double voltageC; //A相电流 //@ApiModelProperty("A相电流") // @TableField(value = "electric_current_A") private Double electricCurrentA; //B相电流 //@ApiModelProperty("B相电流") // @TableField(value = "electric_current_B") private Double electricCurrentB; //C相电流 //@ApiModelProperty("C相电流") // @TableField(value = "electric_current_C") private Double electricCurrentC; //合相有功功率 //@ApiModelProperty("合相有功功率") // @TableField(value = "active_power_All") private Double activePowerAll; //A相有功功率 //@ApiModelProperty("A相有功功率") // @TableField(value = "active_power_A") private Double activePowerA; //B相有功功率 //@ApiModelProperty("B相有功功率") // @TableField(value = "active_power_B") private Double activePowerB; //C相有功功率 //@ApiModelProperty("C相有功功率") // @TableField(value = "active_power_C") private Double activePowerC; //合相无功功率 //@ApiModelProperty("合相无功功率") // @TableField(value = "reactive_power_All") private Double reactivePowerAll; //A相无功功率 //@ApiModelProperty("A相无功功率") // @TableField(value = "reactive_power_A") private Double reactivePowerA; //B相无功功率 //@ApiModelProperty("B相无功功率") // @TableField(value = "reactive_power_B") private Double reactivePowerB; //C相无功功率 //@ApiModelProperty("C相无功功率") // @TableField(value = "reactive_power_C") private Double reactivePowerC; //合相视在功率 //@ApiModelProperty("合相视在功率") // @TableField(value = "apparent_power_All") private Double apparentPowerAll; //A相视在功率 //@ApiModelProperty("A相视在功率") // @TableField(value = "apparent_power_A") private Double apparentPowerA; //B相视在功率 //@ApiModelProperty("B相视在功率") // @TableField(value = "apparent_power_B") private Double apparentPowerB; //C相视在功率 //@ApiModelProperty("C相视在功率") // @TableField(value = "apparent_power_C") private Double apparentPowerC; //合相功率因素 //@ApiModelProperty("合相功率因素") // @TableField(value = "power_factor_All") private Double powerFactorAll; //A相功率因素 //@ApiModelProperty("A相功率因素") // @TableField(value = "power_factor_A") private Double powerFactorA; //B相功率因素 //@ApiModelProperty("B相功率因素") // @TableField(value = "power_factor_B") private Double powerFactorB; //C相功率因素 //@ApiModelProperty("C相功率因素") // @TableField(value = "power_factor_C") private Double powerFactorC; //正向有功总电量 //@ApiModelProperty("正向有功总电量") // @TableField(value = "total_positive_using_power") private Double totalPositiveUsingPower; //反向有功总电量 //@ApiModelProperty("反向有功总电量") // @TableField(value = "total_reverse_using_power") private Double totalReverseUsingPower; //光强值 //@ApiModelProperty("光强值") // @TableField(value = "light_intensity") private Long lightIntensity; //0时控/1光控 //@ApiModelProperty("0时控/1光控") // @TableField(value = "control_1") private Long control1; //0关/64开 //@ApiModelProperty("0关/64开") // @TableField(value = "status_1") private Long status1; //0时控/1光控 //@ApiModelProperty("0时控/1光控") // @TableField(value = "control_2") private Long control2; //0关/64开 //@ApiModelProperty("0关/64开") // @TableField(value = "status_2") private Long status2; //0时控/1光控 //@ApiModelProperty("0时控/1光控") // @TableField(value = "control_3") private Long control3; //0关/64开 //@ApiModelProperty("0关/64开") // @TableField(value = "status_3") private Long status3; //0时控/1光控 //@ApiModelProperty("0时控/1光控") // @TableField(value = "control_n") private Long controlN; //0关/64开 //@ApiModelProperty("0关/64开") // @TableField(value = "status_n") private Long statusN; // 保留 14 private String retain; // 原帧 private String originFrame; @Override public HeartBeatDataPackage transformFrame(String hex) { this.originFrame = hex; this.year = HexUtil.hexToInt(hex.substring(0, 2)); this.month = HexUtil.hexToInt(hex.substring(2, 4)); this.day = HexUtil.hexToInt(hex.substring(4, 6)); this.hour = HexUtil.hexToInt(hex.substring(6, 8)); this.min = HexUtil.hexToInt(hex.substring(8, 10)); this.sec = HexUtil.hexToInt(hex.substring(10, 12)); // //需要把十六进制转二进制 this.deviceTemperature = NumberUtil.round(temperatureTransition(hex.substring(12, 16)), 2).doubleValue(); this.phase = Long.valueOf(HexUtil.hexToInt(hex.substring(16, 18))); this.voltageA = NumberUtil.round(HexUtil.hexToInt(hex.substring(18, 22)) * 0.1, 1).doubleValue(); this.voltageB = NumberUtil.round(HexUtil.hexToInt(hex.substring(22, 26)) * 0.1, 1).doubleValue(); this.voltageC = NumberUtil.round(HexUtil.hexToInt(hex.substring(26, 30)) * 0.1, 1).doubleValue(); this.electricCurrentA = NumberUtil.round(HexUtil.hexToInt(hex.substring(30, 34)) * 0.01, 2).doubleValue(); this.electricCurrentB = NumberUtil.round(HexUtil.hexToInt(hex.substring(34, 38)) * 0.01, 2).doubleValue(); this.electricCurrentC = NumberUtil.round(HexUtil.hexToInt(hex.substring(38, 42)) * 0.01, 2).doubleValue(); this.activePowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(42, 46)) * 1.00, 2).doubleValue(); this.activePowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(46, 50)) * 1.00, 2).doubleValue(); this.activePowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(50, 54)) * 1.00, 2).doubleValue(); this.activePowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(54, 58)) * 1.00, 2).doubleValue(); this.reactivePowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(58, 62)) * 1.00, 2).doubleValue(); this.reactivePowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(62, 66)) * 1.00, 2).doubleValue(); this.reactivePowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(66, 70)) * 1.00, 2).doubleValue(); this.reactivePowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(70, 74)) * 1.00, 2).doubleValue(); this.apparentPowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(74, 78)) * 1.00, 2).doubleValue(); this.apparentPowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(78, 82)) * 1.00, 2).doubleValue(); this.apparentPowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(82, 86)) * 1.00, 2).doubleValue(); this.apparentPowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(86, 90)) * 1.00, 2).doubleValue(); this.powerFactorAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(90, 94)) * 0.001, 3).doubleValue(); this.powerFactorA = NumberUtil.round(HexUtil.hexToInt(hex.substring(94, 98)) * 0.001, 3).doubleValue(); this.powerFactorB = NumberUtil.round(HexUtil.hexToInt(hex.substring(98, 102)) * 0.001, 3).doubleValue(); this.powerFactorC = NumberUtil.round(HexUtil.hexToInt(hex.substring(102, 106)) * 0.001, 3).doubleValue(); this.totalPositiveUsingPower = NumberUtil.round(HexUtil.hexToLong(hex.substring(106, 114)) * 0.01, 2).doubleValue(); this.totalReverseUsingPower = NumberUtil.round(HexUtil.hexToLong(hex.substring(114, 122)) * 0.01, 2).doubleValue(); this.lightIntensity = (long) HexUtil.hexToInt(hex.substring(122, 128)); this.control1 = (long) HexUtil.hexToInt(hex.substring(128, 130)); this.status1 = (long) HexUtil.hexToInt(hex.substring(130, 132)); this.control2 = (long) HexUtil.hexToInt(hex.substring(132, 134)); this.status2 = (long) HexUtil.hexToInt(hex.substring(134, 136)); this.control3 = (long) HexUtil.hexToInt(hex.substring(136, 138)); this.status3 = (long) HexUtil.hexToInt(hex.substring(138, 140)); this.controlN = (long) HexUtil.hexToInt(hex.substring(140, 142)); this.statusN = (long) HexUtil.hexToInt(hex.substring(142, 144)); this.retain = hex.substring(144, 160); return this; } /** * 将16进制转成2进制,进行补码(反码基础上+1),得到正确数值 * 传入16进制的温度,类型为String * 如F500 */ public static 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 static 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; } } }