diff --git a/dc3-driver/dc3-driver-water-188b-tcp/Dockerfile b/dc3-driver/dc3-driver-water-188b-tcp/Dockerfile new file mode 100644 index 000000000..658b47f42 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/Dockerfile @@ -0,0 +1,32 @@ +# +# Copyright 2018-2020 Pnoker. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM pnoker/alpine-java:1.8.251 +MAINTAINER pnoker + +ENV JAVA_OPS -server -Xms128m -Xmx512m -XX:CompressedClassSpaceSize=128m -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=200m + +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && mkdir -p /dc3-driver/dc3-driver-water-188b-tcp + +WORKDIR /dc3-driver/dc3-driver-water-188b-tcp + +ADD ./target/dc3-driver-water-188b-tcp.jar ./ + +EXPOSE 8702 +EXPOSE 9270 + +CMD java ${JAVA_OPS} -Djava.security.egd=file:/dev/./urandom -jar dc3-driver-water-188b-tcp.jar diff --git a/dc3-driver/dc3-driver-water-188b-tcp/pom.xml b/dc3-driver/dc3-driver-water-188b-tcp/pom.xml new file mode 100644 index 000000000..ef0f52bf1 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + + com.dc3 + dc3-driver + 1.0.0 + + + dc3-driver-water-188b-tcp + jar + + IOT DC3 平台 188B TCP协议驱动。 + + + 4.1.46.Final + + + + + + + io.netty + netty-all + ${netty.version} + + + + + \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/Water188BTcpDriverApplication.java b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/Water188BTcpDriverApplication.java new file mode 100644 index 000000000..6315ff150 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/Water188BTcpDriverApplication.java @@ -0,0 +1,35 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver; + +import org.springframework.boot.SpringApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cloud.client.SpringCloudApplication; + +/** + * @author pnoker + */ +@EnableCaching +@SpringCloudApplication +public class Water188BTcpDriverApplication { + + public static void main(String[] args) { + SpringApplication.run(Water188BTcpDriverApplication.class, args); + } + +} + diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java new file mode 100644 index 000000000..4ff47185f --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.impl; + +import com.dc3.common.model.Device; +import com.dc3.common.model.Point; +import com.dc3.common.sdk.bean.AttributeInfo; +import com.dc3.common.sdk.service.CustomDriverService; +import com.dc3.driver.service.netty.NettyTcpServer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author pnoker + */ +@Slf4j +@Service +public class CustomDriverServiceImpl implements CustomDriverService { + + @Value("${driver.custom.tcp.port}") + private Integer port; + + @Resource + private NettyTcpServer nettyTcpServer; + @Resource + private ThreadPoolExecutor threadPoolExecutor; + + @Override + public void initial() { + threadPoolExecutor.execute(() -> { + log.debug("Water 188B Tcp Driver Starting(::{}) incoming data listener", port); + nettyTcpServer.start(port); + }); + } + + @Override + public String read(Map driverInfo, Map pointInfo, Device device, Point point) throws Exception { + return "nil"; + } + + @Override + public Boolean write(Map driverInfo, Map pointInfo, Device device, AttributeInfo value) throws Exception { + return false; + } + + @Override + public void schedule() { + log.info("schedule not implemented"); + } + +} diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServer.java b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServer.java new file mode 100644 index 000000000..396ae1c31 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServer.java @@ -0,0 +1,63 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.netty; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.timeout.ReadTimeoutHandler; +import io.netty.handler.timeout.WriteTimeoutHandler; +import lombok.SneakyThrows; +import org.springframework.stereotype.Component; + +import java.net.InetSocketAddress; + +/** + * @author pnoker + */ +@Component +public class NettyTcpServer { + + @SneakyThrows + public void start(int port) { + EventLoopGroup group = new NioEventLoopGroup(); + try { + ServerBootstrap bootstrap = new ServerBootstrap(); + bootstrap.group(group) + .channel(NioServerSocketChannel.class) + .localAddress(new InetSocketAddress(port)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) { + socketChannel.pipeline().addLast( + new WriteTimeoutHandler(30), + new ReadTimeoutHandler(30), + new NettyTcpServerHandler() + ); + } + }); + ChannelFuture future = bootstrap.bind().sync(); + future.channel().closeFuture().sync(); + } finally { + group.shutdownGracefully().sync(); + } + } +} \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServerHandler.java b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServerHandler.java new file mode 100644 index 000000000..56fcbb103 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/java/com/dc3/driver/service/netty/NettyTcpServerHandler.java @@ -0,0 +1,238 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.netty; + +import com.alibaba.fastjson.JSON; +import com.dc3.common.bean.batch.BatchDevice; +import com.dc3.common.bean.batch.BatchDriver; +import com.dc3.common.bean.driver.PointValue; +import com.dc3.common.constant.Common; +import com.dc3.common.exception.ServiceException; +import com.dc3.common.sdk.bean.AttributeInfo; +import com.dc3.common.sdk.bean.DriverContext; +import com.dc3.common.sdk.service.rabbit.DriverService; +import com.dc3.common.sdk.util.DriverUtils; +import com.dc3.common.utils.Dc3Util; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 报文说明 + * FEFEFE + * 68 + * 10 + * 03221018200673 表号 + * 0081 + * 96 长度 + * 15: 905F 数据标识DI(90 5F) + * 17: 2B2B3600 正向累计量单位(2B),反向累计量单位(2B),瞬时流量单位(36),水压单位(00) + * 21: 18690100 当前正向累计水量 92.440 + * 25: 00000000 当前剩余金额 + * 29: 00000000 当前状态 + * 33: 00 充值识别码 + * 34: 00000000 当前反向累计流量 + * 38: 000000 当前瞬时流量 + * 41: 0000 当前水压 + * 43: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 48: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 53: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 58: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 63: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 68: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 73: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 78: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 83: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 88: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 93: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 98: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 103:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 108:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 113:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 118:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 123:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 128:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 133:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 138:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 143:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 148:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 153:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 158:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 163:B700 信号强度 + * A9 校验和 + * 16 帧尾 + *

+ * ----0--1--2--3--4--5--6--7--8--9--10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51 + * lg:[FE FE FE 68 10 03 22 10 18 20 06 73 00 81 96 90 5F 2B 2B 36 00 18 69 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 B7 00 A9 16] + * lg:[FE FE FE 68 10 06 02 01 07 20 06 36 00 81 96 90 5F 2B 2B 35 00 0E 01 00 00 00 00 00 00 00 00 00 24 00 00 00 00 00 00 00 00 00 00 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F A3 00 1B 16] + * + * @author pnoker + */ +@Slf4j +@Component +@ChannelHandler.Sharable +public class NettyTcpServerHandler extends ChannelInboundHandlerAdapter { + private static final String START_TAG = "fefefe"; + + private static NettyTcpServerHandler nettyTcpServerHandler; + + @PostConstruct + public void init() { + nettyTcpServerHandler = this; + } + + @Resource + private DriverService driverService; + @Resource + private DriverContext driverContext; + + @Override + public void channelActive(ChannelHandlerContext context) { + log.debug("Water 188B Driver Listener({}) accept clint({})", context.channel().localAddress(), context.channel().remoteAddress()); + } + + @Override + public void channelRead(ChannelHandlerContext context, Object msg) { + ByteBuf byteBuf = (ByteBuf) msg; + decode(context, byteBuf); + } + + @Override + public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) { + log.error(throwable.getMessage(), throwable); + context.close(); + } + + /** + * 自注册设备 + * + * @param deviceName + * @throws IOException + */ + private void autoRegister(String deviceName) throws IOException { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("import/batch-import-188b-tcp-template.json"); + if (null == inputStream) { + inputStream = this.getClass().getResourceAsStream("import/batch-import-188b-tcp-template.json"); + } + List batchDrivers = JSON.parseArray( + Dc3Util.inputStreamToString(inputStream), + BatchDriver.class + ); + BatchDevice batchDevice = new BatchDevice(); + batchDevice.setName(deviceName); + batchDrivers.get(0).getProfiles().get(0).getGroups().get(0).getDevices().add(batchDevice); + nettyTcpServerHandler.driverService.batchImportBatchDriver(batchDrivers); + } + + public void decode(ChannelHandlerContext context, ByteBuf byteBuf) { + if (!START_TAG.equals(ByteBufUtil.hexDump(byteBuf, 0, 3))) { + throw new ServiceException("Start Tag Invalid"); + } + String deviceName = ByteBufUtil.hexDump(byteBuf, 5, 7); + log.info("Receive Device({})[{}] Bytes -> {}", deviceName, context.channel().remoteAddress(), ByteBufUtil.hexDump(byteBuf).toUpperCase()); + + List pointValues = new ArrayList<>(); + Long deviceId; + try { + deviceId = nettyTcpServerHandler.driverContext.getDeviceIdByName(deviceName); + } catch (Exception ignored) { + log.info("Auto register device : {}", deviceName); + try { + autoRegister(deviceName); + } catch (IOException e) { + log.error("Auto register device({}) error {}", deviceName, e.getMessage(), e); + return; + } + deviceId = nettyTcpServerHandler.driverContext.getDeviceIdByName(deviceName); + } + + Map> pointInfoMap = nettyTcpServerHandler.driverContext.getDevicePointInfoMap().get(deviceId); + for (Long pointId : pointInfoMap.keySet()) { + PointValue pointValue = pointValueDecode(deviceId, pointId, pointInfoMap.get(pointId), byteBuf); + pointValues.add(pointValue); + } + PointValue pointValue = new PointValue(deviceId, pointValues, 1, TimeUnit.HOURS); + nettyTcpServerHandler.driverService.multiPointValueSender(pointValue); + } + + /** + * 解析 Point Value 数据 + * + * @param deviceId Device Id + * @param pointId Point Id + * @param infoMap Point Info Map + * @param byteBuf ByteBuf + * @return PointValue + */ + public PointValue pointValueDecode(long deviceId, long pointId, Map infoMap, ByteBuf byteBuf) { + String type = DriverUtils.value(infoMap.get("type").getType(), infoMap.get("type").getValue()); + int start = DriverUtils.value(infoMap.get("start").getType(), infoMap.get("start").getValue()); + int length = DriverUtils.value(infoMap.get("length").getType(), infoMap.get("length").getValue()); + + String rawValue, value; + switch (type.toLowerCase()) { + case Common.ValueType.HEX: + rawValue = ByteBufUtil.hexDump(byteBuf.retainedSlice(start, length)).toUpperCase(); + value = nettyTcpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + case Common.ValueType.SHORT: + rawValue = String.valueOf(byteBuf.getShortLE(start)); + value = nettyTcpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + case Common.ValueType.INT: + rawValue = String.valueOf(DriverUtils.bytesToIntLE(ByteBufUtil.getBytes(byteBuf, start, length))); + value = nettyTcpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + default: + throw new IllegalStateException("Unexpected value: " + type.toLowerCase()); + } + value = customDecode(start, value); + log.info("DecodePointValue: hex({}),rawValue({}),convertValue({})", ByteBufUtil.hexDump(byteBuf, start, length).toUpperCase(), rawValue, value); + return new PointValue(pointId, rawValue, value); + } + + /** + * 自定义报文解析,用于处理特殊位号数据 + * + * @return PointValue + */ + public String customDecode(int start, String value) { + //信号强度额外处理 + if (start == 163) { + int csq = (int) Double.parseDouble(value); + if (csq > 0) { + csq -= 200; + } + value = String.valueOf(csq); + } + return value; + } + +} \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/application.yml b/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/application.yml new file mode 100644 index 000000000..d6f5b7239 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/application.yml @@ -0,0 +1,43 @@ +driver: + name: Water188BTcpDriver + description: @project.description@ + custom: + tcp: + port: 9270 + schedule: + read: + enable: false + corn: '0/30 * * * * ?' + custom: + enable: false + corn: '0/5 * * * * ?' + point-attribute: + - displayName: 起始字节 + name: start + type: int + value: 0 + description: 起始字节,包含该字节 + - displayName: 长度 + name: length + type: int + value: 8 + description: 字节长度 + - displayName: 类型 + name: type + type: string + value: int + description: 解析类型,short、int、long、float、double、boolean、string + +server: + port: 8702 + +spring: + application: + name: @project.artifactId@ + +logging: + level: + com.dc3.common.sdk: DEBUG + com.dc3: DEBUG + file: + name: dc3/logs/driver/water/188b/tcp/${spring.application.name}.log \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/import/batch-import-188b-tcp-template.json b/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/import/batch-import-188b-tcp-template.json new file mode 100644 index 000000000..a31a248e5 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-tcp/src/main/resources/import/batch-import-188b-tcp-template.json @@ -0,0 +1,650 @@ +[ + { + "serviceName": "dc3-driver-water-188b-tcp", + "profiles": [ + { + "name": "Water_188B_Tcp_Profile", + "share": true, + "points": [ + { + "name": "数据标识", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计水量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "剩余金额", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "状态", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "充值识别码", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-0点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-1点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-2点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-3点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-4点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-5点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-6点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-7点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-8点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-9点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-10点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-11点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-12点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-13点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-14点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-15点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-16点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-17点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-18点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-19点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-20点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-21点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-22点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-23点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "信号强度", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + } + ], + "pointConfig": { + "数据标识": { + "start": 15, + "length": 2, + "type": "hex" + }, + "正向累计量单位": { + "start": 17, + "length": 1, + "type": "hex" + }, + "反向累计量单位": { + "start": 18, + "length": 1, + "type": "hex" + }, + "瞬时流量单位": { + "start": 19, + "length": 1, + "type": "hex" + }, + "水压单位": { + "start": 20, + "length": 1, + "type": "hex" + }, + "正向累计水量": { + "start": 21, + "length": 4, + "type": "int" + }, + "剩余金额": { + "start": 25, + "length": 4, + "type": "int" + }, + "状态": { + "start": 29, + "length": 4, + "type": "hex" + }, + "充值识别码": { + "start": 33, + "length": 1, + "type": "hex" + }, + "反向累计流量": { + "start": 34, + "length": 4, + "type": "int" + }, + "瞬时流量": { + "start": 38, + "length": 3, + "type": "int" + }, + "水压": { + "start": 41, + "length": 2, + "type": "short" + }, + "正向累计流量-0点": { + "start": 43, + "length": 4, + "type": "int" + }, + "正向累计流量-1点": { + "start": 48, + "length": 4, + "type": "int" + }, + "正向累计流量-2点": { + "start": 53, + "length": 4, + "type": "int" + }, + "正向累计流量-3点": { + "start": 58, + "length": 4, + "type": "int" + }, + "正向累计流量-4点": { + "start": 63, + "length": 4, + "type": "int" + }, + "正向累计流量-5点": { + "start": 68, + "length": 4, + "type": "int" + }, + "正向累计流量-6点": { + "start": 73, + "length": 4, + "type": "int" + }, + "正向累计流量-7点": { + "start": 78, + "length": 4, + "type": "int" + }, + "正向累计流量-8点": { + "start": 83, + "length": 4, + "type": "int" + }, + "正向累计流量-9点": { + "start": 88, + "length": 4, + "type": "int" + }, + "正向累计流量-10点": { + "start": 93, + "length": 4, + "type": "int" + }, + "正向累计流量-11点": { + "start": 98, + "length": 4, + "type": "int" + }, + "正向累计流量-12点": { + "start": 103, + "length": 4, + "type": "int" + }, + "正向累计流量-13点": { + "start": 108, + "length": 4, + "type": "int" + }, + "正向累计流量-14点": { + "start": 113, + "length": 4, + "type": "int" + }, + "正向累计流量-15点": { + "start": 118, + "length": 4, + "type": "int" + }, + "正向累计流量-16点": { + "start": 123, + "length": 4, + "type": "int" + }, + "正向累计流量-17点": { + "start": 128, + "length": 4, + "type": "int" + }, + "正向累计流量-18点": { + "start": 133, + "length": 4, + "type": "int" + }, + "正向累计流量-19点": { + "start": 138, + "length": 4, + "type": "int" + }, + "正向累计流量-20点": { + "start": 143, + "length": 4, + "type": "int" + }, + "正向累计流量-21点": { + "start": 148, + "length": 4, + "type": "int" + }, + "正向累计流量-22点": { + "start": 153, + "length": 4, + "type": "int" + }, + "正向累计流量-23点": { + "start": 158, + "length": 4, + "type": "int" + }, + "信号强度": { + "start": 163, + "length": 2, + "type": "short" + } + }, + "groups": [ + { + "name": "Water_188B_Tcp_Group", + "devices": [] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-udp/Dockerfile b/dc3-driver/dc3-driver-water-188b-udp/Dockerfile new file mode 100644 index 000000000..e031973d5 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/Dockerfile @@ -0,0 +1,32 @@ +# +# Copyright 2018-2020 Pnoker. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM pnoker/alpine-java:1.8.251 +MAINTAINER pnoker + +ENV JAVA_OPS -server -Xms128m -Xmx512m -XX:CompressedClassSpaceSize=128m -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=200m + +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && mkdir -p /dc3-driver/dc3-driver-water-188b-udp + +WORKDIR /dc3-driver/dc3-driver-water-188b-udp + +ADD ./target/dc3-driver-water-188b-udp.jar ./ + +EXPOSE 8703 +EXPOSE 9271 + +CMD java ${JAVA_OPS} -Djava.security.egd=file:/dev/./urandom -jar dc3-driver-water-188b-udp.jar diff --git a/dc3-driver/dc3-driver-water-188b-udp/pom.xml b/dc3-driver/dc3-driver-water-188b-udp/pom.xml new file mode 100644 index 000000000..00772edac --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + + com.dc3 + dc3-driver + 1.0.0 + + + dc3-driver-water-188b-udp + jar + + IOT DC3 平台 188B UDP协议驱动。 + + + 4.1.46.Final + + + + + + + io.netty + netty-all + ${netty.version} + + + + + \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/Water188BUdpDriverApplication.java b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/Water188BUdpDriverApplication.java new file mode 100644 index 000000000..523e71055 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/Water188BUdpDriverApplication.java @@ -0,0 +1,35 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver; + +import org.springframework.boot.SpringApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cloud.client.SpringCloudApplication; + +/** + * @author pnoker + */ +@EnableCaching +@SpringCloudApplication +public class Water188BUdpDriverApplication { + + public static void main(String[] args) { + SpringApplication.run(Water188BUdpDriverApplication.class, args); + } + +} + diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java new file mode 100644 index 000000000..3b1b1bbac --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/impl/CustomDriverServiceImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.impl; + +import com.dc3.common.model.Device; +import com.dc3.common.model.Point; +import com.dc3.common.sdk.bean.AttributeInfo; +import com.dc3.common.sdk.service.CustomDriverService; +import com.dc3.driver.service.netty.NettyUdpServer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author pnoker + */ +@Slf4j +@Service +public class CustomDriverServiceImpl implements CustomDriverService { + + @Value("${driver.custom.udp.port}") + private Integer port; + + @Resource + private NettyUdpServer nettyUdpServer; + @Resource + private ThreadPoolExecutor threadPoolExecutor; + + @Override + public void initial() { + threadPoolExecutor.execute(() -> { + log.debug("Water 188B Udp Driver Starting(::{}) incoming data listener", port); + nettyUdpServer.start(port); + }); + } + + @Override + public String read(Map driverInfo, Map pointInfo, Device device, Point point) throws Exception { + return "nil"; + } + + @Override + public Boolean write(Map driverInfo, Map pointInfo, Device device, AttributeInfo value) throws Exception { + return false; + } + + @Override + public void schedule() { + log.info("schedule not implemented"); + } + +} diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServer.java b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServer.java new file mode 100644 index 000000000..fd05d9d01 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServer.java @@ -0,0 +1,61 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.handler.timeout.WriteTimeoutHandler; +import lombok.SneakyThrows; +import org.springframework.stereotype.Component; + +import java.net.InetSocketAddress; + +/** + * @author pnoker + */ +@Component +public class NettyUdpServer { + + @SneakyThrows + public void start(int port) { + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(group) + .channel(NioDatagramChannel.class) + .localAddress(new InetSocketAddress(port)) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(Channel channel) { + channel.pipeline().addLast( + new WriteTimeoutHandler(30), + new NettyUdpServerHandler() + ); + } + }); + ChannelFuture future = bootstrap.bind().sync(); + future.channel().closeFuture().sync(); + } finally { + group.shutdownGracefully().sync(); + } + } +} \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServerHandler.java b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServerHandler.java new file mode 100644 index 000000000..f54b0f2e4 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/java/com/dc3/driver/service/netty/NettyUdpServerHandler.java @@ -0,0 +1,232 @@ +/* + * Copyright 2018-2020 Pnoker. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dc3.driver.service.netty; + +import com.alibaba.fastjson.JSON; +import com.dc3.common.bean.batch.BatchDevice; +import com.dc3.common.bean.batch.BatchDriver; +import com.dc3.common.bean.driver.PointValue; +import com.dc3.common.constant.Common; +import com.dc3.common.exception.ServiceException; +import com.dc3.common.sdk.bean.AttributeInfo; +import com.dc3.common.sdk.bean.DriverContext; +import com.dc3.common.sdk.service.rabbit.DriverService; +import com.dc3.common.sdk.util.DriverUtils; +import com.dc3.common.utils.Dc3Util; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.socket.DatagramPacket; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 报文说明 + * FEFEFE + * 68 + * 10 + * 03221018200673 表号 + * 0081 + * 96 长度 + * 15: 905F 数据标识DI(90 5F) + * 17: 2B2B3600 正向累计量单位(2B),反向累计量单位(2B),瞬时流量单位(36),水压单位(00) + * 21: 18690100 当前正向累计水量 92.440 + * 25: 00000000 当前剩余金额 + * 29: 00000000 当前状态 + * 33: 00 充值识别码 + * 34: 00000000 当前反向累计流量 + * 38: 000000 当前瞬时流量 + * 41: 0000 当前水压 + * 43: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 48: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 53: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 58: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 63: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 68: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 73: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 78: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 83: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 88: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 93: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 98: 0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 103:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 108:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 113:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 118:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 123:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 128:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 133:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 138:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 143:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 148:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 153:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 158:0A68010073 正向累计流量(0A680100)累加和(73) 92.17 + * 163:B700 信号强度 + * A9 校验和 + * 16 帧尾 + *

+ * ----0--1--2--3--4--5--6--7--8--9--10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51 + * lg:[FE FE FE 68 10 03 22 10 18 20 06 73 00 81 96 90 5F 2B 2B 36 00 18 69 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 0A 68 01 00 73 B7 00 A9 16] + * lg:[FE FE FE 68 10 06 02 01 07 20 06 36 00 81 96 90 5F 2B 2B 35 00 0E 01 00 00 00 00 00 00 00 00 00 24 00 00 00 00 00 00 00 00 00 00 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F 0E 01 00 00 0F A3 00 1B 16] + * + * @author pnoker + */ +@Slf4j +@Component +public class NettyUdpServerHandler extends SimpleChannelInboundHandler { + private static final String START_TAG = "fefefe"; + + private static NettyUdpServerHandler nettyUdpServerHandler; + + @PostConstruct + public void init() { + nettyUdpServerHandler = this; + } + + @Resource + private DriverService driverService; + @Resource + private DriverContext driverContext; + + @Override + protected void channelRead0(ChannelHandlerContext context, DatagramPacket msg) { + ByteBuf byteBuf = msg.content(); + decode(context, byteBuf); + } + + @Override + public void exceptionCaught(ChannelHandlerContext context, Throwable throwable) { + log.error(throwable.getMessage(), throwable); + context.close(); + } + + /** + * 自注册设备 + * + * @param deviceName + * @throws IOException + */ + private void autoRegister(String deviceName) throws IOException { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("import/batch-import-188b-udp-template.json"); + if (null == inputStream) { + inputStream = this.getClass().getResourceAsStream("import/batch-import-188b-udp-template.json"); + } + List batchDrivers = JSON.parseArray( + Dc3Util.inputStreamToString(inputStream), + BatchDriver.class + ); + BatchDevice batchDevice = new BatchDevice(); + batchDevice.setName(deviceName); + batchDrivers.get(0).getProfiles().get(0).getGroups().get(0).getDevices().add(batchDevice); + nettyUdpServerHandler.driverService.batchImportBatchDriver(batchDrivers); + } + + public void decode(ChannelHandlerContext context, ByteBuf byteBuf) { + if (!START_TAG.equals(ByteBufUtil.hexDump(byteBuf, 0, 3))) { + throw new ServiceException("Start Tag Invalid"); + } + String deviceName = ByteBufUtil.hexDump(byteBuf, 5, 7); + log.info("Receive Device({})[{}] Bytes -> {}", deviceName, context.channel().remoteAddress(), ByteBufUtil.hexDump(byteBuf).toUpperCase()); + + List pointValues = new ArrayList<>(); + Long deviceId; + try { + deviceId = nettyUdpServerHandler.driverContext.getDeviceIdByName(deviceName); + } catch (Exception ignored) { + log.info("Auto register device : {}", deviceName); + try { + autoRegister(deviceName); + } catch (IOException e) { + log.error("Auto register device({}) error {}", deviceName, e.getMessage(), e); + return; + } + deviceId = nettyUdpServerHandler.driverContext.getDeviceIdByName(deviceName); + } + + Map> pointInfoMap = nettyUdpServerHandler.driverContext.getDevicePointInfoMap().get(deviceId); + for (Long pointId : pointInfoMap.keySet()) { + PointValue pointValue = pointValueDecode(deviceId, pointId, pointInfoMap.get(pointId), byteBuf); + pointValues.add(pointValue); + } + PointValue pointValue = new PointValue(deviceId, pointValues, 1, TimeUnit.HOURS); + nettyUdpServerHandler.driverService.multiPointValueSender(pointValue); + } + + /** + * 解析 Point Value 数据 + * + * @param deviceId Device Id + * @param pointId Point Id + * @param infoMap Point Info Map + * @param byteBuf ByteBuf + * @return PointValue + */ + private PointValue pointValueDecode(long deviceId, long pointId, Map infoMap, ByteBuf byteBuf) { + String type = DriverUtils.value(infoMap.get("type").getType(), infoMap.get("type").getValue()); + int start = DriverUtils.value(infoMap.get("start").getType(), infoMap.get("start").getValue()); + int length = DriverUtils.value(infoMap.get("length").getType(), infoMap.get("length").getValue()); + + String rawValue, value; + switch (type.toLowerCase()) { + case Common.ValueType.HEX: + rawValue = ByteBufUtil.hexDump(byteBuf.retainedSlice(start, length)).toUpperCase(); + value = nettyUdpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + case Common.ValueType.SHORT: + rawValue = String.valueOf(byteBuf.getShortLE(start)); + value = nettyUdpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + case Common.ValueType.INT: + rawValue = String.valueOf(DriverUtils.bytesToIntLE(ByteBufUtil.getBytes(byteBuf, start, length))); + value = nettyUdpServerHandler.driverService.convertValue(deviceId, pointId, rawValue); + break; + default: + throw new IllegalStateException("Unexpected value: " + type.toLowerCase()); + } + value = customDecode(start, value); + log.info("DecodePointValue: hex({}),rawValue({}),convertValue({})", ByteBufUtil.hexDump(byteBuf, start, length).toUpperCase(), rawValue, value); + return new PointValue(pointId, rawValue, value); + } + + /** + * 自定义报文解析,用于处理特殊位号数据 + * + * @return PointValue + */ + private String customDecode(int start, String value) { + //信号强度额外处理 + if (start == 163) { + int csq = (int) Double.parseDouble(value); + if (csq > 0) { + csq -= 200; + } + value = String.valueOf(csq); + } + return value; + } + +} \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/application.yml b/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/application.yml new file mode 100644 index 000000000..00e444752 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/application.yml @@ -0,0 +1,43 @@ +driver: + name: Water188BUdpDriver + description: @project.description@ + custom: + udp: + port: 9271 + schedule: + read: + enable: false + corn: '0/30 * * * * ?' + custom: + enable: false + corn: '0/5 * * * * ?' + point-attribute: + - displayName: 起始字节 + name: start + type: int + value: 0 + description: 起始字节,包含该字节 + - displayName: 长度 + name: length + type: int + value: 8 + description: 字节长度 + - displayName: 类型 + name: type + type: string + value: int + description: 解析类型,short、int、long、float、double、boolean、string + +server: + port: 8703 + +spring: + application: + name: @project.artifactId@ + +logging: + level: + com.dc3.common.sdk: DEBUG + com.dc3: DEBUG + file: + name: dc3/logs/driver/water/188b/udp/${spring.application.name}.log \ No newline at end of file diff --git a/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/import/batch-import-188b-udp-template.json b/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/import/batch-import-188b-udp-template.json new file mode 100644 index 000000000..5af0882c2 --- /dev/null +++ b/dc3-driver/dc3-driver-water-188b-udp/src/main/resources/import/batch-import-188b-udp-template.json @@ -0,0 +1,650 @@ +[ + { + "serviceName": "dc3-driver-water-188b-udp", + "profiles": [ + { + "name": "Water_188B_Udp_Profile", + "share": true, + "points": [ + { + "name": "数据标识", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计水量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "剩余金额", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "状态", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "充值识别码", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-0点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-1点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-2点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-3点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-4点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-5点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-6点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-7点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-8点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-9点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-10点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-11点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-12点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-13点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-14点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-15点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-16点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-17点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-18点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-19点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-20点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-21点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-22点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-23点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "信号强度", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + } + ], + "pointConfig": { + "数据标识": { + "start": 15, + "length": 2, + "type": "hex" + }, + "正向累计量单位": { + "start": 17, + "length": 1, + "type": "hex" + }, + "反向累计量单位": { + "start": 18, + "length": 1, + "type": "hex" + }, + "瞬时流量单位": { + "start": 19, + "length": 1, + "type": "hex" + }, + "水压单位": { + "start": 20, + "length": 1, + "type": "hex" + }, + "正向累计水量": { + "start": 21, + "length": 4, + "type": "int" + }, + "剩余金额": { + "start": 25, + "length": 4, + "type": "int" + }, + "状态": { + "start": 29, + "length": 4, + "type": "hex" + }, + "充值识别码": { + "start": 33, + "length": 1, + "type": "hex" + }, + "反向累计流量": { + "start": 34, + "length": 4, + "type": "int" + }, + "瞬时流量": { + "start": 38, + "length": 3, + "type": "int" + }, + "水压": { + "start": 41, + "length": 2, + "type": "short" + }, + "正向累计流量-0点": { + "start": 43, + "length": 4, + "type": "int" + }, + "正向累计流量-1点": { + "start": 48, + "length": 4, + "type": "int" + }, + "正向累计流量-2点": { + "start": 53, + "length": 4, + "type": "int" + }, + "正向累计流量-3点": { + "start": 58, + "length": 4, + "type": "int" + }, + "正向累计流量-4点": { + "start": 63, + "length": 4, + "type": "int" + }, + "正向累计流量-5点": { + "start": 68, + "length": 4, + "type": "int" + }, + "正向累计流量-6点": { + "start": 73, + "length": 4, + "type": "int" + }, + "正向累计流量-7点": { + "start": 78, + "length": 4, + "type": "int" + }, + "正向累计流量-8点": { + "start": 83, + "length": 4, + "type": "int" + }, + "正向累计流量-9点": { + "start": 88, + "length": 4, + "type": "int" + }, + "正向累计流量-10点": { + "start": 93, + "length": 4, + "type": "int" + }, + "正向累计流量-11点": { + "start": 98, + "length": 4, + "type": "int" + }, + "正向累计流量-12点": { + "start": 103, + "length": 4, + "type": "int" + }, + "正向累计流量-13点": { + "start": 108, + "length": 4, + "type": "int" + }, + "正向累计流量-14点": { + "start": 113, + "length": 4, + "type": "int" + }, + "正向累计流量-15点": { + "start": 118, + "length": 4, + "type": "int" + }, + "正向累计流量-16点": { + "start": 123, + "length": 4, + "type": "int" + }, + "正向累计流量-17点": { + "start": 128, + "length": 4, + "type": "int" + }, + "正向累计流量-18点": { + "start": 133, + "length": 4, + "type": "int" + }, + "正向累计流量-19点": { + "start": 138, + "length": 4, + "type": "int" + }, + "正向累计流量-20点": { + "start": 143, + "length": 4, + "type": "int" + }, + "正向累计流量-21点": { + "start": 148, + "length": 4, + "type": "int" + }, + "正向累计流量-22点": { + "start": 153, + "length": 4, + "type": "int" + }, + "正向累计流量-23点": { + "start": 158, + "length": 4, + "type": "int" + }, + "信号强度": { + "start": 163, + "length": 2, + "type": "short" + } + }, + "groups": [ + { + "name": "Water_188B_Udp_Group", + "devices": [] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/dc3-driver/pom.xml b/dc3-driver/pom.xml index 33023be44..827c89feb 100644 --- a/dc3-driver/pom.xml +++ b/dc3-driver/pom.xml @@ -36,6 +36,8 @@ dc3-driver-opc-ua dc3-driver-mqtt dc3-driver-modbus-tcp + dc3-driver-water-188b-tcp + dc3-driver-water-188b-udp diff --git a/dc3/api/files/batch-import-188b-tcp-template.json b/dc3/api/files/batch-import-188b-tcp-template.json new file mode 100644 index 000000000..76193609e --- /dev/null +++ b/dc3/api/files/batch-import-188b-tcp-template.json @@ -0,0 +1,660 @@ +[ + { + "serviceName": "dc3-driver-water-188b-tcp", + "profiles": [ + { + "name": "Water188B_Tcp_Profile", + "share": true, + "points": [ + { + "name": "数据标识", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计水量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "剩余金额", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "状态", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "充值识别码", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-0点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-1点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-2点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-3点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-4点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-5点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-6点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-7点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-8点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-9点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-10点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-11点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-12点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-13点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-14点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-15点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-16点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-17点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-18点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-19点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-20点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-21点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-22点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-23点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "信号强度", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + } + ], + "pointConfig": { + "数据标识": { + "start": 15, + "length": 2, + "type": "hex" + }, + "正向累计量单位": { + "start": 17, + "length": 1, + "type": "hex" + }, + "反向累计量单位": { + "start": 18, + "length": 1, + "type": "hex" + }, + "瞬时流量单位": { + "start": 19, + "length": 1, + "type": "hex" + }, + "水压单位": { + "start": 20, + "length": 1, + "type": "hex" + }, + "正向累计水量": { + "start": 21, + "length": 4, + "type": "int" + }, + "剩余金额": { + "start": 25, + "length": 4, + "type": "int" + }, + "状态": { + "start": 29, + "length": 4, + "type": "hex" + }, + "充值识别码": { + "start": 33, + "length": 1, + "type": "hex" + }, + "反向累计流量": { + "start": 34, + "length": 4, + "type": "int" + }, + "瞬时流量": { + "start": 38, + "length": 3, + "type": "int" + }, + "水压": { + "start": 41, + "length": 2, + "type": "short" + }, + "正向累计流量-0点": { + "start": 43, + "length": 4, + "type": "int" + }, + "正向累计流量-1点": { + "start": 48, + "length": 4, + "type": "int" + }, + "正向累计流量-2点": { + "start": 53, + "length": 4, + "type": "int" + }, + "正向累计流量-3点": { + "start": 58, + "length": 4, + "type": "int" + }, + "正向累计流量-4点": { + "start": 63, + "length": 4, + "type": "int" + }, + "正向累计流量-5点": { + "start": 68, + "length": 4, + "type": "int" + }, + "正向累计流量-6点": { + "start": 73, + "length": 4, + "type": "int" + }, + "正向累计流量-7点": { + "start": 78, + "length": 4, + "type": "int" + }, + "正向累计流量-8点": { + "start": 83, + "length": 4, + "type": "int" + }, + "正向累计流量-9点": { + "start": 88, + "length": 4, + "type": "int" + }, + "正向累计流量-10点": { + "start": 93, + "length": 4, + "type": "int" + }, + "正向累计流量-11点": { + "start": 98, + "length": 4, + "type": "int" + }, + "正向累计流量-12点": { + "start": 103, + "length": 4, + "type": "int" + }, + "正向累计流量-13点": { + "start": 108, + "length": 4, + "type": "int" + }, + "正向累计流量-14点": { + "start": 113, + "length": 4, + "type": "int" + }, + "正向累计流量-15点": { + "start": 118, + "length": 4, + "type": "int" + }, + "正向累计流量-16点": { + "start": 123, + "length": 4, + "type": "int" + }, + "正向累计流量-17点": { + "start": 128, + "length": 4, + "type": "int" + }, + "正向累计流量-18点": { + "start": 133, + "length": 4, + "type": "int" + }, + "正向累计流量-19点": { + "start": 138, + "length": 4, + "type": "int" + }, + "正向累计流量-20点": { + "start": 143, + "length": 4, + "type": "int" + }, + "正向累计流量-21点": { + "start": 148, + "length": 4, + "type": "int" + }, + "正向累计流量-22点": { + "start": 153, + "length": 4, + "type": "int" + }, + "正向累计流量-23点": { + "start": 158, + "length": 4, + "type": "int" + }, + "信号强度": { + "start": 163, + "length": 2, + "type": "short" + } + }, + "groups": [ + { + "name": "Water_Tcp_Group", + "devices": [ + { + "name": "06020107200636" + }, + { + "name": "03221018200673" + }, + { + "name": "09451018200637" + } + ] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/dc3/api/files/batch-import-188b-udp-template.json b/dc3/api/files/batch-import-188b-udp-template.json new file mode 100644 index 000000000..258658137 --- /dev/null +++ b/dc3/api/files/batch-import-188b-udp-template.json @@ -0,0 +1,660 @@ +[ + { + "serviceName": "dc3-driver-water-188b-udp", + "profiles": [ + { + "name": "Water188B_Udp_Profile", + "share": true, + "points": [ + { + "name": "数据标识", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压单位", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计水量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "剩余金额", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "状态", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "充值识别码", + "type": "string", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "反向累计流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "瞬时流量", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "水压", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-0点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-1点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-2点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-3点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-4点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-5点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-6点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-7点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-8点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-9点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-10点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-11点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-12点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-13点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-14点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-15点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-16点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-17点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-18点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-19点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-20点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-21点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-22点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "正向累计流量-23点", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 0.001, + "accrue": false, + "format": "%.3f", + "unit": "-" + }, + { + "name": "信号强度", + "type": "float", + "rw": 0, + "base": 0, + "minimum": -999999, + "maximum": 999999, + "multiple": 1, + "accrue": false, + "format": "%.3f", + "unit": "-" + } + ], + "pointConfig": { + "数据标识": { + "start": 15, + "length": 2, + "type": "hex" + }, + "正向累计量单位": { + "start": 17, + "length": 1, + "type": "hex" + }, + "反向累计量单位": { + "start": 18, + "length": 1, + "type": "hex" + }, + "瞬时流量单位": { + "start": 19, + "length": 1, + "type": "hex" + }, + "水压单位": { + "start": 20, + "length": 1, + "type": "hex" + }, + "正向累计水量": { + "start": 21, + "length": 4, + "type": "int" + }, + "剩余金额": { + "start": 25, + "length": 4, + "type": "int" + }, + "状态": { + "start": 29, + "length": 4, + "type": "hex" + }, + "充值识别码": { + "start": 33, + "length": 1, + "type": "hex" + }, + "反向累计流量": { + "start": 34, + "length": 4, + "type": "int" + }, + "瞬时流量": { + "start": 38, + "length": 3, + "type": "int" + }, + "水压": { + "start": 41, + "length": 2, + "type": "short" + }, + "正向累计流量-0点": { + "start": 43, + "length": 4, + "type": "int" + }, + "正向累计流量-1点": { + "start": 48, + "length": 4, + "type": "int" + }, + "正向累计流量-2点": { + "start": 53, + "length": 4, + "type": "int" + }, + "正向累计流量-3点": { + "start": 58, + "length": 4, + "type": "int" + }, + "正向累计流量-4点": { + "start": 63, + "length": 4, + "type": "int" + }, + "正向累计流量-5点": { + "start": 68, + "length": 4, + "type": "int" + }, + "正向累计流量-6点": { + "start": 73, + "length": 4, + "type": "int" + }, + "正向累计流量-7点": { + "start": 78, + "length": 4, + "type": "int" + }, + "正向累计流量-8点": { + "start": 83, + "length": 4, + "type": "int" + }, + "正向累计流量-9点": { + "start": 88, + "length": 4, + "type": "int" + }, + "正向累计流量-10点": { + "start": 93, + "length": 4, + "type": "int" + }, + "正向累计流量-11点": { + "start": 98, + "length": 4, + "type": "int" + }, + "正向累计流量-12点": { + "start": 103, + "length": 4, + "type": "int" + }, + "正向累计流量-13点": { + "start": 108, + "length": 4, + "type": "int" + }, + "正向累计流量-14点": { + "start": 113, + "length": 4, + "type": "int" + }, + "正向累计流量-15点": { + "start": 118, + "length": 4, + "type": "int" + }, + "正向累计流量-16点": { + "start": 123, + "length": 4, + "type": "int" + }, + "正向累计流量-17点": { + "start": 128, + "length": 4, + "type": "int" + }, + "正向累计流量-18点": { + "start": 133, + "length": 4, + "type": "int" + }, + "正向累计流量-19点": { + "start": 138, + "length": 4, + "type": "int" + }, + "正向累计流量-20点": { + "start": 143, + "length": 4, + "type": "int" + }, + "正向累计流量-21点": { + "start": 148, + "length": 4, + "type": "int" + }, + "正向累计流量-22点": { + "start": 153, + "length": 4, + "type": "int" + }, + "正向累计流量-23点": { + "start": 158, + "length": 4, + "type": "int" + }, + "信号强度": { + "start": 163, + "length": 2, + "type": "short" + } + }, + "groups": [ + { + "name": "Water_Udp_Group", + "devices": [ + { + "name": "06020107200636" + }, + { + "name": "03221018200673" + }, + { + "name": "09451018200637" + } + ] + } + ] + } + ] + } +] \ No newline at end of file