fix: 按键事件解析逻辑
All checks were successful
iot-test-platform CI/CD / build-and-deploy (push) Successful in 30s
All checks were successful
iot-test-platform CI/CD / build-and-deploy (push) Successful in 30s
This commit is contained in:
@@ -30,6 +30,8 @@ public class Consts {
|
||||
public static final Integer MSGID_TRANSMISSION_TYPE_PRESSURE = 0x0600;
|
||||
/** 查询终端参数应答 **/
|
||||
public static final Integer MSGID_PARAM_QUERY_RESP = 0x0104;
|
||||
/** 按键事件上报 **/
|
||||
public static final Integer MSGID_BUTTON_EVENT = 0x0006;
|
||||
|
||||
|
||||
/** 平台通用应答 **/
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.iot.transport.jt808.entity.request;
|
||||
|
||||
import com.iot.transport.jt808.entity.DataPack;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 按键事件上报消息 (0x0006)
|
||||
* 4.10.1 短按按键
|
||||
* 4.10.2 长按按键
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ButtonEventPack extends DataPack {
|
||||
/**
|
||||
* 按键ID
|
||||
* 0x01: 短按1号键
|
||||
* 0x0b: 长按1号键
|
||||
* 0x0c: 长按2号键
|
||||
* 0x0d: 长按3号键
|
||||
* 0x0e: 长按4号键
|
||||
*/
|
||||
private int keyId;
|
||||
|
||||
/**
|
||||
* 按键状态/次数
|
||||
* 0x01: 按键一次
|
||||
*/
|
||||
private int keyState;
|
||||
|
||||
public ButtonEventPack() {
|
||||
}
|
||||
|
||||
public ButtonEventPack(DataPack packageData) {
|
||||
this();
|
||||
this.channel = packageData.getChannel();
|
||||
this.checkSum = packageData.getCheckSum();
|
||||
this.bodyBytes = packageData.getBodyBytes();
|
||||
this.packHead = packageData.getPackHead();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.iot.transport.jt808.entity.DataPack;
|
||||
import com.iot.transport.jt808.entity.DataPack.PackHead;
|
||||
import com.iot.transport.jt808.entity.request.LocationPack;
|
||||
import com.iot.transport.jt808.entity.request.RegisterPack;
|
||||
import com.iot.transport.jt808.entity.request.ButtonEventPack;
|
||||
import com.iot.transport.jt808.entity.request.RegisterPack.TerminalRegInfo;
|
||||
import com.iot.transport.jt808.util.BCDUtil;
|
||||
import com.iot.transport.jt808.util.BitUtil;
|
||||
@@ -211,6 +212,23 @@ public class DataDecoder {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ButtonEventPack toButtonEventPack(DataPack packageData) {
|
||||
ButtonEventPack ret = new ButtonEventPack(packageData);
|
||||
byte[] data = ret.getBodyBytes();
|
||||
|
||||
// 1. byte[0] 按键ID
|
||||
if (data.length > 0) {
|
||||
ret.setKeyId(this.parseIntFromBytes(data, 0, 1));
|
||||
}
|
||||
|
||||
// 2. byte[1] 按键状态/次数
|
||||
if (data.length > 1) {
|
||||
ret.setKeyState(this.parseIntFromBytes(data, 1, 1));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public LocationPack toLocationInfoUploadMsg(DataPack packageData) {
|
||||
LocationPack ret = new LocationPack(packageData);
|
||||
|
||||
@@ -8,11 +8,13 @@ import com.iot.transport.jt808.service.handler.terminal.HeartbeatHandler;
|
||||
import com.iot.transport.jt808.service.handler.terminal.LocationUploadHandler;
|
||||
import com.iot.transport.jt808.service.handler.terminal.LoginOutHandler;
|
||||
import com.iot.transport.jt808.service.handler.terminal.RegisterHandler;
|
||||
import com.iot.transport.jt808.service.handler.terminal.ButtonEventHandler;
|
||||
|
||||
public class MessageHandlerFactory {
|
||||
|
||||
/**
|
||||
* 消息和处理类映射表
|
||||
*
|
||||
*/
|
||||
public static Map<Integer, Class<?>> handlerMap = new HashMap<Integer, Class<?>>();
|
||||
static{
|
||||
@@ -21,6 +23,7 @@ public class MessageHandlerFactory {
|
||||
handlerMap.put(Consts.MSGID_LOG_OUT, LoginOutHandler.class); // 终端注销
|
||||
handlerMap.put(Consts.MSGID_AUTHENTICATION, AuthenticationHandler.class); // 终端鉴权
|
||||
handlerMap.put(Consts.MSGID_LOCATION_UPLOAD, LocationUploadHandler.class); // 位置信息汇报
|
||||
handlerMap.put(Consts.MSGID_BUTTON_EVENT, ButtonEventHandler.class); // 按键事件上报
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.iot.transport.jt808.common.Consts;
|
||||
import com.iot.transport.jt808.entity.request.BatteryVersionInfo;
|
||||
import com.iot.transport.jt808.entity.request.BluetoothInfo;
|
||||
import com.iot.transport.jt808.entity.request.LocationPack;
|
||||
import com.iot.transport.jt808.entity.request.ButtonEventPack;
|
||||
import java.util.List;
|
||||
|
||||
public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1)
|
||||
@@ -114,6 +115,23 @@ public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1)
|
||||
locMap.put("lon", locPack.getLongitude());
|
||||
logMap.put("location", locMap);
|
||||
|
||||
} catch (Exception e) {
|
||||
logMap.put("details", packageData.toString() + " (Parse Error: " + e.getMessage() + ")");
|
||||
}
|
||||
} else if (msgId == Consts.MSGID_BUTTON_EVENT || msgId == 0x0006) {
|
||||
try {
|
||||
ButtonEventPack btnPack = this.decoder.toButtonEventPack(packageData);
|
||||
logMap.put("details", btnPack.toString());
|
||||
logMap.put("type", "badge"); // Keep it as badge type to update the device
|
||||
logMap.put("id", header.getTerminalPhone());
|
||||
|
||||
// Add button event info
|
||||
Map<String, Object> btnInfo = new HashMap<>();
|
||||
btnInfo.put("keyId", btnPack.getKeyId());
|
||||
btnInfo.put("keyState", btnPack.getKeyState());
|
||||
btnInfo.put("timestamp", System.currentTimeMillis());
|
||||
logMap.put("buttonEvent", btnInfo);
|
||||
|
||||
} catch (Exception e) {
|
||||
logMap.put("details", packageData.toString() + " (Parse Error: " + e.getMessage() + ")");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.iot.transport.jt808.service.handler.terminal;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.iot.transport.jt808.common.Consts;
|
||||
import com.iot.transport.jt808.entity.DataPack;
|
||||
import com.iot.transport.jt808.entity.DataPack.PackHead;
|
||||
import com.iot.transport.jt808.entity.request.ButtonEventPack;
|
||||
import com.iot.transport.jt808.entity.response.ServerBodyPack;
|
||||
import com.iot.transport.jt808.service.handler.MessageHandler;
|
||||
|
||||
/**
|
||||
* 按键事件上报 (0x0006) ==> 平台通用应答
|
||||
*/
|
||||
public class ButtonEventHandler extends MessageHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public ButtonEventHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(DataPack packageData) {
|
||||
|
||||
PackHead header = packageData.getPackHead();
|
||||
logger.info("[按键上报],msgid={}, phone={},flowid={}", header.getId(), header.getTerminalPhone(), header.getFlowId());
|
||||
|
||||
try {
|
||||
ButtonEventPack msg = this.decoder.toButtonEventPack(packageData);
|
||||
log.info("按键事件: KeyID={}, State={}", msg.getKeyId(), msg.getKeyState());
|
||||
|
||||
// 回复通用应答
|
||||
int flowId = super.getFlowId(msg.getChannel());
|
||||
ServerBodyPack respMsgBody = new ServerBodyPack(header.getFlowId(), header.getId(), ServerBodyPack.success);
|
||||
byte[] bs = this.msgEncoder.encode4ServerCommonRespMsg(msg, respMsgBody, flowId);
|
||||
super.send2Client(msg.getChannel(), bs);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("[按键上报]错误, err={}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,6 +296,13 @@
|
||||
+{{ badge.bluetooth.length - 2 }} 更多...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 按键事件提示 -->
|
||||
<div v-if="badge.lastButtonEvent" class="mt-2 alert alert-warning p-1 mb-0 text-center" style="font-size: 0.75rem;">
|
||||
<i class="fas fa-hand-pointer me-1"></i>
|
||||
{{ formatButtonEvent(badge.lastButtonEvent) }}
|
||||
<span class="text-muted ms-1">({{ formatTime(badge.lastButtonEvent.timestamp) }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -444,10 +451,26 @@
|
||||
|
||||
// 1. 处理工牌数据 (识别 type=badge)
|
||||
if (data.type === 'badge' && data.id) {
|
||||
// 合并旧数据,保留 lastButtonEvent 如果新数据没有覆盖它
|
||||
const oldData = this.badges[data.id] || {};
|
||||
const newButtonEvent = data.buttonEvent;
|
||||
|
||||
this.badges[data.id] = {
|
||||
...oldData,
|
||||
...data,
|
||||
lastUpdate: now
|
||||
lastUpdate: now,
|
||||
// 如果这次是按键事件,更新 lastButtonEvent;否则保留旧的(可以加个超时自动清除逻辑)
|
||||
lastButtonEvent: newButtonEvent || oldData.lastButtonEvent
|
||||
};
|
||||
|
||||
// 简单的超时清除按键提示 (5秒后消失)
|
||||
if (newButtonEvent) {
|
||||
setTimeout(() => {
|
||||
if (this.badges[data.id] && this.badges[data.id].lastButtonEvent === newButtonEvent) {
|
||||
this.badges[data.id].lastButtonEvent = null;
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 处理计数器数据 (识别 type=counter)
|
||||
@@ -603,6 +626,20 @@
|
||||
if (source === 'SYSTEM') return 'bg-info text-dark';
|
||||
if (source === 'TCP') return 'bg-warning text-dark';
|
||||
return 'bg-success';
|
||||
},
|
||||
formatButtonEvent(evt) {
|
||||
if (!evt) return '';
|
||||
let action = '按键';
|
||||
// 0x01-0x0A: 短按
|
||||
if (evt.keyId >= 0x01 && evt.keyId <= 0x0A) {
|
||||
action = `短按 ${evt.keyId}号键`;
|
||||
}
|
||||
// 0x0B-0x14: 长按
|
||||
else if (evt.keyId >= 0x0B && evt.keyId <= 0x14) {
|
||||
const keyNum = evt.keyId - 0x0A;
|
||||
action = `长按 ${keyNum}号键`;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}).mount('#app')
|
||||
|
||||
Reference in New Issue
Block a user