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 配置