From c59e4d9c117aeb2b4c24e947aa156d3067445f10 Mon Sep 17 00:00:00 2001 From: sdvdxl Date: Tue, 11 May 2021 17:10:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?add=20=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sdvdxl --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index d2e1db0..daac659 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,20 @@ 参考 [软网关开发说明](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 文件夹下, -- Gitee From 0b1caaa0cccf26d4c9116f8c657c9dbc1fe2f677 Mon Sep 17 00:00:00 2001 From: sdvdxl Date: Tue, 11 May 2021 19:25:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?add=20=E5=B9=BF=E6=92=AD=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/iotos-soft-gateway-demo.iml | 3 + README.md | 4 + pom.xml | 6 + .../subsystem/IoTGatewayApplication.java | 2 +- .../config/SubsystemResourcesConfig.java | 21 +++ .../subsystem/dto/RadioDevice.java | 24 ++++ .../subsystem/service/UdpServerService.java | 134 ++++++++++++++++++ src/main/resources/application.yml | 5 +- 8 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/hekr/iotos/softgateway/subsystem/config/SubsystemResourcesConfig.java create mode 100644 src/main/java/me/hekr/iotos/softgateway/subsystem/dto/RadioDevice.java create mode 100644 src/main/java/me/hekr/iotos/softgateway/subsystem/service/UdpServerService.java diff --git a/.idea/iotos-soft-gateway-demo.iml b/.idea/iotos-soft-gateway-demo.iml index 65eb2b6..e53dca1 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 daac659..df91b9e 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,7 @@ tcp 和 udp 按需依赖。 开发完成后,将网关和子设备产品导出,(如果有其他文件也可以)放到 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 2b5719a..af9b16f 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 40d3be6..e7b861c 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 0000000..dd9e9cb --- /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 0000000..e26d5d1 --- /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 0000000..9bb98c8 --- /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 ecf6bf0..7df3374 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 -- Gitee