package org.yzh.protocol.t808.T8900Lock; import io.github.yezhihao.protostar.annotation.Field; import io.github.yezhihao.protostar.annotation.Message; import org.yzh.commons.util.BytesUtils; import org.yzh.protocol.basics.JTMessage; import org.yzh.protocol.commons.JT808; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * 消息透传应答 - 蝶阀锁状态响应 */ public class T8900Response { @Field(index = 0, length = 2, desc = "锁ID") private byte[] lockId; @Field(index = 2, length = 1, desc = "命令类型") private byte commandType; @Field(index = 3, length = 1, desc = "锁芯状态") private byte lockCoreStatus; @Field(index = 4, length = 1, desc = "锁体安装位置状态") private byte installationStatus; @Field(index = 5, length = 1, desc = "外壳状态") private byte shellStatus; @Field(index = 6, length = 1, desc = "初始上电锁芯状态") private byte initialPowerStatus; @Field(index = 7, length = 2, desc = "电池电压") private short batteryVoltage; @Field(index = 9, length = 2, desc = "电源电压") private short powerVoltage; @Field(index = 11, length = 1, desc = "年") private byte year; @Field(index = 12, length = 1, desc = "月") private byte month; @Field(index = 13, length = 1, desc = "日") private byte day; @Field(index = 14, length = 1, desc = "时") private byte hour; @Field(index = 15, length = 1, desc = "分") private byte minute; @Field(index = 16, length = 1, desc = "秒") private byte second; @Field(index = 17, length = 1, desc = "校验码") private byte checksum; // Getters with parsed values public String getLockIdHex() { return BytesUtils.bytes2hex(lockId); } public String getLockCoreStatusDesc() { switch (lockCoreStatus) { case 0x01: return "开锁状态"; case 0x02: return "关锁状态"; case 0x03: return "位置异常状态"; case 0x04: return "锁芯正在旋转进行中"; default: return "未知状态:" + lockCoreStatus; } } // 解析状态为可读字符串 public String parseStatus() { return String.format( "锁ID: 0x%04X\n" + "锁芯状态: %s\n" + "锁体状态: %s\n" + "电池电压: %.1fV\n" + "时间: %s", lockId, getStatusDesc(lockCoreStatus, "开锁", "关锁", "位置异常", "旋转中"), getStatusDesc(installationStatus, "正常", "异常"), batteryVoltage * 0.1, getDeviceTimeString() ); } private String getStatusDesc(byte code, String... options) { return code - 1 >= 0 && code - 1 < options.length ? options[code - 1] : "未知"; } private String parseTime(byte[] timeBytes) { // 解析yy-MM-dd hh:mm:ss(示例:假设timeBytes[0]=年低8位,需根据实际协议调整) return String.format("%02d-%02d-%02d %02d:%02d:%02d", timeBytes[0] & 0xFF, timeBytes[1] & 0xFF, timeBytes[2] & 0xFF, timeBytes[3] & 0xFF, timeBytes[4] & 0xFF, timeBytes[5] & 0xFF ); } public String getInstallationStatusDesc() { return installationStatus == 0x01 ? "正常" : "异常"; } public String getShellStatusDesc() { return shellStatus == 0x01 ? "正常" : "异常"; } public String getInitialPowerStatusDesc() { return initialPowerStatus == 0x01 ? "开锁状态" : "关锁状态"; } public double getBatteryVoltage() { return (batteryVoltage & 0xFFFF) * 0.1; } public double getPowerVoltage() { return (powerVoltage & 0xFFFF) * 0.1; } public LocalDateTime getDeviceTime() { int yearValue = 2000 + (year & 0xFF); return LocalDateTime.of( yearValue, month & 0xFF, day & 0xFF, hour & 0xFF, minute & 0xFF, second & 0xFF ); } public String getDeviceTimeString() { return getDeviceTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } // 校验方法 public boolean isValidChecksum() { byte sum = 0; for (int i = 0; i < 17; i++) { sum ^= getByteAt(i); } return sum == checksum; } private byte getByteAt(int index) { switch (index) { case 0: case 1: return lockId[index]; case 2: return commandType; case 3: return lockCoreStatus; case 4: return installationStatus; case 5: return shellStatus; case 6: return initialPowerStatus; case 7: return (byte) (batteryVoltage & 0xFF); case 8: return (byte) ((batteryVoltage >> 8) & 0xFF); case 9: return (byte) (powerVoltage & 0xFF); case 10: return (byte) ((powerVoltage >> 8) & 0xFF); case 11: return year; case 12: return month; case 13: return day; case 14: return hour; case 15: return minute; case 16: return second; default: throw new IndexOutOfBoundsException(); } } // Getters and Setters public byte[] getLockId() { return lockId; } public void setLockId(byte[] lockId) { this.lockId = lockId; } public byte getCommandType() { return commandType; } public void setCommandType(byte commandType) { this.commandType = commandType; } public byte getLockCoreStatus() { return lockCoreStatus; } public void setLockCoreStatus(byte lockCoreStatus) { this.lockCoreStatus = lockCoreStatus; } public byte getInstallationStatus() { return installationStatus; } public void setInstallationStatus(byte installationStatus) { this.installationStatus = installationStatus; } public byte getShellStatus() { return shellStatus; } public void setShellStatus(byte shellStatus) { this.shellStatus = shellStatus; } public byte getInitialPowerStatus() { return initialPowerStatus; } public void setInitialPowerStatus(byte initialPowerStatus) { this.initialPowerStatus = initialPowerStatus; } public short getBatteryVoltageRaw() { return batteryVoltage; } public void setBatteryVoltage(short batteryVoltage) { this.batteryVoltage = batteryVoltage; } public short getPowerVoltageRaw() { return powerVoltage; } public void setPowerVoltage(short powerVoltage) { this.powerVoltage = powerVoltage; } public byte getYear() { return year; } public void setYear(byte year) { this.year = year; } public byte getMonth() { return month; } public void setMonth(byte month) { this.month = month; } public byte getDay() { return day; } public void setDay(byte day) { this.day = day; } public byte getHour() { return hour; } public void setHour(byte hour) { this.hour = hour; } public byte getMinute() { return minute; } public void setMinute(byte minute) { this.minute = minute; } public byte getSecond() { return second; } public void setSecond(byte second) { this.second = second; } public byte getChecksum() { return checksum; } public void setChecksum(byte checksum) { this.checksum = checksum; } }