chore: 客流计数器对接-数据解析、自定义返回DTO
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
package com.viewshanghai.module.iot.gateway.codec.people;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.viewshanghai.framework.common.util.json.JsonUtils;
|
||||
import com.viewshanghai.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import com.viewshanghai.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import com.viewshanghai.module.iot.gateway.codec.IotDeviceMessageCodec;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 客流计数器设备 编解码器
|
||||
* <p>
|
||||
* 适配设备上传的特定 JSON 格式
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class IotPeopleCounterCodec implements IotDeviceMessageCodec {
|
||||
|
||||
/**
|
||||
* 编解码器类型,需要在设备管理中配置为该值
|
||||
*/
|
||||
public static final String TYPE = "PEOPLE_COUNTER";
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IotDeviceMessage decode(byte[] bytes) {
|
||||
// 1. 预处理:转换字符串并修复可能的中文引号问题
|
||||
String jsonStr = new String(bytes, StandardCharsets.UTF_8);
|
||||
jsonStr = jsonStr.replace("“", "\"").replace("”", "\""); // 修复中文双引号
|
||||
|
||||
// 2. 解析 JSON
|
||||
PeopleCounterPayload payload;
|
||||
try {
|
||||
payload = JsonUtils.parseObject(jsonStr, PeopleCounterPayload.class);
|
||||
} catch (Exception e) {
|
||||
log.error("[decode][解析设备数据失败: {}]", jsonStr, e);
|
||||
throw new IllegalArgumentException("JSON 格式错误");
|
||||
}
|
||||
Assert.notNull(payload, "消息内容不能为空");
|
||||
|
||||
// 3. 构建属性参数 Map (params)
|
||||
Map<String, Object> params = MapUtil.newHashMap();
|
||||
// 3.1 基础属性
|
||||
params.put("rssi", payload.getRssi());
|
||||
params.put("model", payload.getModel());
|
||||
params.put("version", payload.getVersion());
|
||||
params.put("pair_status", StrUtil.trim(payload.getPair())); // 去除可能的空格
|
||||
|
||||
// 3.2 业务数据 (取 data 列表中时间最新的一条)
|
||||
LocalDateTime reportTime = LocalDateTime.now();
|
||||
if (CollUtil.isNotEmpty(payload.getData())) {
|
||||
// 尝试按时间排序取最新,或者直接取最后一条(视设备协议而定,这里假设时间字符串可排序)
|
||||
PeopleCounterData latestData = payload.getData().stream()
|
||||
.max(Comparator.comparing(PeopleCounterData::getTime))
|
||||
.orElse(payload.getData().get(payload.getData().size() - 1));
|
||||
|
||||
params.put("people_in", latestData.getIn());
|
||||
params.put("people_out", latestData.getOut());
|
||||
params.put("battery_rx", latestData.getRxBat());
|
||||
params.put("battery_tx", latestData.getTxBat());
|
||||
|
||||
// 解析上报时间(改为使用本地当前时间)
|
||||
// if (StrUtil.isNotBlank(latestData.getTime())) {
|
||||
// try {
|
||||
// // 格式:20250501093000 -> yyyyMMddHHmmss
|
||||
// reportTime = LocalDateTimeUtil.parse(latestData.getTime(), DatePattern.PURE_DATETIME_PATTERN);
|
||||
// } catch (Exception e) {
|
||||
// log.warn("[decode][时间格式解析失败: {}]", latestData.getTime());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// 4. 构建 IotDeviceMessage
|
||||
return IotDeviceMessage.requestOf(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod(), params)
|
||||
.setReportTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode(IotDeviceMessage message) {
|
||||
// 如果需要下发指令给设备,可以在这里实现编码逻辑
|
||||
// 目前需求主要是上报解码,暂不支持下行或透传原样
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备上报的数据结构
|
||||
*/
|
||||
@Data
|
||||
public static class PeopleCounterPayload {
|
||||
private String uuid;
|
||||
private String model;
|
||||
private String version;
|
||||
private String pair;
|
||||
private Integer num;
|
||||
|
||||
// 处理 JSON 中的大写或特殊命名,这里假设 JsonUtils 使用 Jackson
|
||||
@JsonProperty("RSSI")
|
||||
private Integer rssi;
|
||||
|
||||
private List<PeopleCounterData> data;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PeopleCounterData {
|
||||
private String time;
|
||||
private Integer in;
|
||||
private Integer out;
|
||||
private Integer rxBat;
|
||||
private Integer txBat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.viewshanghai.module.iot.gateway.codec.people.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* 客流计数器设备上报响应
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class PeopleCounterUploadResp {
|
||||
|
||||
private Integer statusCode; // 0 正常 1 未绑定平台 2 解析 json 出错
|
||||
private String time; // yyyyMMddHHmmss
|
||||
private String open; // 营业开始时间
|
||||
private String close; // 营业结束时间
|
||||
private Integer saveCycle; // 存储周期
|
||||
private Integer upCycle; // 上报周期
|
||||
private String license; // 0 正常 1 证书到期
|
||||
private String direction; // twoWay / onlyIn / onlyOut / exchange
|
||||
private String upgradeUrl; // 升级地址(无升级可为空)
|
||||
|
||||
/**
|
||||
* 构建默认的客流计数器响应数据
|
||||
*
|
||||
* @return 响应对象
|
||||
*/
|
||||
public static PeopleCounterUploadResp createDefault() {
|
||||
PeopleCounterUploadResp resp = new PeopleCounterUploadResp();
|
||||
resp.setStatusCode(0);
|
||||
resp.setTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
|
||||
resp.setOpen("0800");
|
||||
resp.setClose("2300");
|
||||
resp.setSaveCycle(1);
|
||||
resp.setUpCycle(1);
|
||||
resp.setLicense("0");
|
||||
resp.setDirection("twoWay");
|
||||
resp.setUpgradeUrl("http://op.foorir.com/upgrade/2023120.bin");
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ viewshanghai:
|
||||
gateway:
|
||||
# 设备 RPC 配置
|
||||
rpc:
|
||||
url: ${VIEWSHANGHAI_IOT_GATEWAY_RPC_URL:http://124.221.55.225:48080} # 主程序 API 地址
|
||||
url: ${VIEWSHANGHAI_IOT_GATEWAY_RPC_URL:http://127.0.0.1:48080} # 主程序 API 地址
|
||||
connect-timeout: 30s
|
||||
read-timeout: 30s
|
||||
# 设备 Token 配置
|
||||
|
||||
Reference in New Issue
Block a user