From 9d6b53c4f6fe5afd9b71da6869684e4957d579b4 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 25 Dec 2025 15:16:53 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=AE=A2=E6=B5=81=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=E5=99=A8=E5=AF=B9=E6=8E=A5-=E6=95=B0=E6=8D=AE=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E3=80=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=94=E5=9B=9E?= =?UTF-8?q?DTO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codec/people/IotPeopleCounterCodec.java | 131 ++++++++++++++++++ .../people/dto/PeopleCounterUploadResp.java | 44 ++++++ .../src/main/resources/application.yaml | 2 +- 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/IotPeopleCounterCodec.java create mode 100644 viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/dto/PeopleCounterUploadResp.java diff --git a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/IotPeopleCounterCodec.java b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/IotPeopleCounterCodec.java new file mode 100644 index 0000000..d2c953f --- /dev/null +++ b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/IotPeopleCounterCodec.java @@ -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; + +/** + * 客流计数器设备 编解码器 + *

+ * 适配设备上传的特定 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 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 data; + } + + @Data + public static class PeopleCounterData { + private String time; + private Integer in; + private Integer out; + private Integer rxBat; + private Integer txBat; + } +} + + diff --git a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/dto/PeopleCounterUploadResp.java b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/dto/PeopleCounterUploadResp.java new file mode 100644 index 0000000..5612f0a --- /dev/null +++ b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/people/dto/PeopleCounterUploadResp.java @@ -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; + } +} diff --git a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/resources/application.yaml b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/resources/application.yaml index 90b73bd..70928a4 100644 --- a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/resources/application.yaml +++ b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/resources/application.yaml @@ -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 配置