diff --git a/.idea/iotos-soft-gateway-demo.iml b/.idea/iotos-soft-gateway-demo.iml
index 65eb2b6be21c2c2c53bac26eb23668082cb55d0f..e53dca1516b954a2c79bb3a98531fdb7e8967ff0 100644
--- a/.idea/iotos-soft-gateway-demo.iml
+++ b/.idea/iotos-soft-gateway-demo.iml
@@ -12,6 +12,9 @@
+
+
+
diff --git a/README.md b/README.md
index d2e1db01eb559191522a74808b8aa5bce06239b3..df91b9ee78439153e449685eb6bc0031349813a1 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,25 @@
参考 [软网关开发说明](https://gitee.com/geekhekr/iotos-soft-gateway/blob/master/README.md#%E4%B8%9A%E5%8A%A1%E5%BC%80%E5%8F%91)
+pom 需要依赖
+
+```xml
+
+ me.hekr.iotos.softgateway
+ framework-core
+ 0.0.1
+
+```
+
+tcp 和 udp 按需依赖。
+
+如果 sdk 不能满足,可以 fork sdk 项目,提交 pr,或者自行 fork 之后按照项目发布说明发布到自己的仓库,然后依赖地址改为自己的 git 地址即可。
+
## 打包
开发完成后,将网关和子设备产品导出,(如果有其他文件也可以)放到 docs 文件夹下,
执行命令 `mvn clean package -Dmaven.test.skip=true` 会打包 jar 并将 README,docs 文件夹下的文件一并打包成 zip,生产的文件在 `target` 目录下。
+
+## 项目示例说明
+
+本项目模拟了一个简单广播系统,(因为需要广播系统的服务端,所以项目启动了一个udp server)。驱动(客户端)定时发送查询帧查询设备状态,然后上报给 IoT 平台。
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 2b5719acfb69ef4d99ca243214017c0393e8df4c..af9b16f56cc4a056f299522ad4425964493ed7a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,12 @@
framework-core
0.0.1
+
+
+ me.hekr.iotos.softgateway
+ framework-network-udp
+ 0.0.1
+
diff --git a/src/main/java/me/hekr/iotos/softgateway/subsystem/IoTGatewayApplication.java b/src/main/java/me/hekr/iotos/softgateway/subsystem/IoTGatewayApplication.java
index 40d3be60b2014dbcdaf08bcc353c813fc4758994..e7b861c74e0c6fb6cf3291b49542e8ae05fcfb7b 100644
--- a/src/main/java/me/hekr/iotos/softgateway/subsystem/IoTGatewayApplication.java
+++ b/src/main/java/me/hekr/iotos/softgateway/subsystem/IoTGatewayApplication.java
@@ -10,7 +10,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
public class IoTGatewayApplication {
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) {
SpringApplication.run(IoTGatewayApplication.class, args);
}
}
diff --git a/src/main/java/me/hekr/iotos/softgateway/subsystem/config/SubsystemResourcesConfig.java b/src/main/java/me/hekr/iotos/softgateway/subsystem/config/SubsystemResourcesConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd9e9cb417a1361506f70c91913cb62bc1adf9c8
--- /dev/null
+++ b/src/main/java/me/hekr/iotos/softgateway/subsystem/config/SubsystemResourcesConfig.java
@@ -0,0 +1,21 @@
+package me.hekr.iotos.softgateway.subsystem.config;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import me.hekr.iotos.softgateway.subsystem.service.UdpServerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/** @author iotos */
+@Component
+public class SubsystemResourcesConfig {
+ @Autowired private UdpServerService udpServerService;
+
+ @PostConstruct
+ public void init() {
+ udpServerService.start();
+ }
+
+ @PreDestroy
+ public void close() {}
+}
diff --git a/src/main/java/me/hekr/iotos/softgateway/subsystem/dto/RadioDevice.java b/src/main/java/me/hekr/iotos/softgateway/subsystem/dto/RadioDevice.java
new file mode 100644
index 0000000000000000000000000000000000000000..e26d5d1902881ab530e2a4809067146444299792
--- /dev/null
+++ b/src/main/java/me/hekr/iotos/softgateway/subsystem/dto/RadioDevice.java
@@ -0,0 +1,24 @@
+package me.hekr.iotos.softgateway.subsystem.dto;
+
+import lombok.Data;
+
+/**
+ * 广播设备
+ *
+ * @author iotos
+ */
+@Data
+public class RadioDevice {
+
+ /** 设备id */
+ private String radioDevId;
+
+ /** 1 在线, 0离线 */
+ private int status;
+
+ /** 音量 */
+ private int vol;
+
+ /** 播放状态 0 停止, 1 播放, 2 暂停 */
+ private int playStat;
+}
diff --git a/src/main/java/me/hekr/iotos/softgateway/subsystem/service/UdpServerService.java b/src/main/java/me/hekr/iotos/softgateway/subsystem/service/UdpServerService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9bb98c86637f0193dd6eb597658a0dda1e7beddf
--- /dev/null
+++ b/src/main/java/me/hekr/iotos/softgateway/subsystem/service/UdpServerService.java
@@ -0,0 +1,134 @@
+package me.hekr.iotos.softgateway.subsystem.service;
+
+import static java.util.stream.Collectors.toList;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.IntStream;
+import lombok.extern.slf4j.Slf4j;
+import me.hekr.iotos.softgateway.core.config.DeviceMapper;
+import me.hekr.iotos.softgateway.core.config.DeviceMapper.Props;
+import me.hekr.iotos.softgateway.core.klink.KlinkService;
+import me.hekr.iotos.softgateway.core.utils.JsonUtil;
+import me.hekr.iotos.softgateway.network.common.DecodePacket;
+import me.hekr.iotos.softgateway.network.common.PacketCoder;
+import me.hekr.iotos.softgateway.network.udp.UdpClient;
+import me.hekr.iotos.softgateway.network.udp.UdpServer;
+import me.hekr.iotos.softgateway.subsystem.dto.RadioDevice;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+/** @author iotos */
+@Slf4j
+@Service
+public class UdpServerService {
+ private static final int SERVER_PORT = 1030;
+ private final PacketCoder packetCoder = getPacketCoder();
+ private UdpServer udpServer;
+ private UdpClient udpClient;
+ @Autowired private KlinkService klinkService;
+
+ private static PacketCoder getPacketCoder() {
+ return new PacketCoder() {
+ @Override
+ public byte[] encode(String s) {
+ return s.getBytes(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public DecodePacket decode(byte[] bytes) {
+ return DecodePacket.wrap(new String(bytes, StandardCharsets.UTF_8), bytes.length);
+ }
+ };
+ }
+
+ @Scheduled(fixedDelay = 10 * 1000, initialDelay = 0)
+ public void syncDeviceStatus() {
+ List devices =
+ JsonUtil.fromJson(
+ udpClient.send("getAllStatus"), new TypeReference>() {});
+
+ for (RadioDevice d : devices) {
+ Optional subsystemDev =
+ DeviceMapper.getBySubSystemProperties(Props.p("radioDevId", d.getRadioDevId()).get());
+ if (!subsystemDev.isPresent()) {
+ log.warn("没有配置映射设备信息,请在远程配置中进行配置,设备信息:{}", d);
+ continue;
+ }
+
+ DeviceMapper dev = subsystemDev.get();
+
+ // 如果是离线,设置iot的设备离线
+ if (d.getStatus() == 0) {
+ klinkService.devLogout(dev.getPk(), dev.getDevId());
+ continue;
+ }
+
+ Map params = new HashMap<>(3);
+ params.put("vol", d.getVol());
+ params.put("playStat", d.getPlayStat());
+ klinkService.devSend(dev.getPk(), dev.getDevId(), "report", params);
+ }
+ }
+
+ public void start() {
+ startServer();
+ startClient();
+ }
+
+ private void startClient() {
+ udpClient = new UdpClient<>("localhost", SERVER_PORT, 1021);
+ udpClient.setMessageListener(
+ ctx -> System.out.println("收到来自 " + ctx.getAddress() + " 的消息:" + ctx.getMessage()));
+ udpClient.setPacketCoder(packetCoder);
+ udpClient.setEnableNetLog(false);
+ udpClient.setSync(true);
+ // 同步模式设置超时时间
+ udpClient.setTimeout(3000);
+ udpClient.start();
+ }
+
+ private void startServer() {
+ udpServer = new UdpServer<>(1030);
+ // 设置编解码
+ udpServer.setPacketCoder(packetCoder);
+
+ // 设置消息监听器
+ udpServer.setMessageListener(
+ ctx -> {
+ // 模拟获取设备等信息
+ String msg = ctx.getMessage();
+ log.info("收到消息:{}", msg);
+ // 获取所有设备信息
+ switch (msg) {
+ case "getAllStatus":
+ udpServer.send(ctx, JsonUtil.toJson(getDeviceStatus()));
+ break;
+ // 可以自行扩展其他指令
+ default:
+ }
+ });
+ // 开启网络日志
+ udpServer.setEnableNetLog(true);
+ udpServer.start();
+ }
+
+ private List getDeviceStatus() {
+ return IntStream.range(0, 3)
+ .mapToObj(
+ i -> {
+ RadioDevice d = new RadioDevice();
+ d.setRadioDevId("radio_id_" + i);
+ d.setStatus(i % 2);
+ d.setPlayStat(i % 3);
+ d.setVol(i);
+ return d;
+ })
+ .collect(toList());
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index ecf6bf0c7eceae9f48d37e5822659c9e145dbc7c..7df337413f4c4ee71adeb08c913ae87cbc831809 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -21,8 +21,9 @@ logging:
# 比如 level.me.hekr.iotos: DEBUG
level:
root: INFO
- me.hekr.iotos: INFO
- io.netty: INFO
+ org.spring: WARN
+ me.hekr.iotos: DEBUG
+ io.netty: DEBUG
# 日志文件保存位置
file: logs/iotos-soft-gateway.log