Selaa lähdekoodia

add 网络泵协议

18339543638 4 vuotta sitten
vanhempi
commit
c25a254aaa

+ 153 - 0
jetlinks-components/network-component/network-core/src/main/java/org/jetlinks/community/netpump/DataUtils.java

@@ -0,0 +1,153 @@
+package org.jetlinks.community.netpump;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.*;
+
+/**
+ * 数据处理与判断
+ * Create by fanfan
+ * Date: 2020-05-12 8:34
+ */
+public class DataUtils {
+    // 取出泵的数据转换成 10 进制
+    public static Integer resultValue(String content){
+        List<String> list = new ArrayList<>();
+        for(int i = 0 ; i< content.length(); i+=2){
+            list.add(content.substring(i,i+2));
+        }
+        Collections.reverse(list);
+        String str = String.join("",list);
+        return Integer.valueOf(Integer.valueOf(str,16).toString(),10);
+    }
+
+    // 取出数据
+    public static String getContent(String content,Integer startIndex, Integer toIndex){
+        return StrUtil.sub(content,startIndex,toIndex);
+    }
+
+    /**
+     * 字节数组转hex字符串
+     *
+     * @param bytes 待转换的字节数组
+     * @return 返回的hex字符串
+     */
+    public static String byteArrToHexString(byte[] bytes) {
+        StringBuffer sb = new StringBuffer();
+        int size = bytes.length;
+        for (int i = 0; i < size; i++) {
+            String hex = Integer.toHexString(bytes[i] & 0xFF);
+            if (hex.length() < 2) {
+                sb.append(0);
+            }
+            sb.append(hex.toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    // 设置 长包 接收数据
+    public static String getLongContent(String content,Map<String, Object> propertiesMap ,Map<String, Object> eventsMap){
+        // 泵号   [2-9]字节
+        String pumpCode = getContent(content,4,20);
+        propertiesMap.put("pumpCode",pumpCode);
+        // 住院号
+        String patientCode = resultValue(getContent(content,20,28)).toString();
+        propertiesMap.put("patientCode",patientCode);
+        // 持续量
+        Double continueQuantity = resultValue(getContent(content,28,32)) * 0.1;
+        propertiesMap.put("continueQuantity",continueQuantity);
+        //总量
+        Integer allQuantity = resultValue(getContent(content,32,36));
+        propertiesMap.put("allQuantity",allQuantity);
+        //已输入量
+        Double inputQuantity = resultValue(getContent(content,36,40)) * 0.1;
+        propertiesMap.put("inputQuantity",inputQuantity);
+
+        // 第20个字节
+        Integer pumpStatus20 = resultValue(getContent(content,40,42));
+
+        // 第30个字节,优先级低
+        Integer pumpStatus21 = resultValue(getContent(content,42,44));
+
+        if ((pumpStatus21 & 0b00001111) == 0x01)// 电机失控
+        {
+            eventsMap.put("abnormal","电机失控");
+        }
+        else if ((pumpStatus21 & 0b00001111) == 0x02)//电机故障
+        {
+            eventsMap.put("abnormal","电机故障");
+        }
+
+        if ((pumpStatus21 & 0b11110000) == 0x00)// 关机状态
+        {
+            propertiesMap.put("state","off");
+        }
+        else if ((pumpStatus21 & 0b11110000) == 0x10)// 开机状态
+        {
+            propertiesMap.put("state","on");
+        }
+        else if ((pumpStatus21 & 0b11110000) == 0x20)// 运行状态
+        {
+            propertiesMap.put("state","run");
+        }
+        else if ((pumpStatus21 & 0b11110000) == 0x30)// 暂停状态
+        {
+            propertiesMap.put("state","pause");
+        }
+        else if ((pumpStatus21 & 0b11110000) == 0x40)// 待机状态
+        {
+            propertiesMap.put("state","waiting");
+        }
+        // 电池状态 第22个字节
+        Integer batteryState = resultValue(getContent(content,44,46));
+        propertiesMap.put("batteryState",batteryState);
+        // 有效次数
+        Integer validNum = resultValue(getContent(content,46,48));
+        propertiesMap.put("validNum",validNum);
+        // 无效次数
+        Integer invalidNum = resultValue(getContent(content,48,50));
+        propertiesMap.put("invalidNum",invalidNum);
+
+        // 解析第29个字节, 优先级高,可覆盖上面
+        if ((pumpStatus20 & 0b00000011) == 0b00000011)// 未装药盒状态
+        {
+            eventsMap.put("abnormal","未装药盒");
+        }
+        else if ((pumpStatus20 & 0b00000001) == 0b00000001)// 气泡或无液状态
+        {
+            eventsMap.put("abnormal","气泡无液");
+        }
+        else if ((pumpStatus20 & 0b00000010) == 0b00000010)// 堵塞状态
+        {
+            eventsMap.put("abnormal","堵塞");
+        }
+        if ((pumpStatus20 & 0b00000100) == 0b00000100)// 输入总量报警
+        {
+            eventsMap.put("abnormal","输入总量报警");
+        }
+        if ((pumpStatus20 & 0b00001000) == 0b00001000)// 极限
+        {
+            eventsMap.put("abnormal","极限");
+        }
+        if ((pumpStatus20 & 0b00010000) == 0b00010000)// 输液将结束
+        {
+            eventsMap.put("abnormal","输液将结束");
+        }
+        if ((pumpStatus20 & 0b00100000) == 0b00100000)// 输液结束
+        {
+            eventsMap.put("abnormal","输液结束");
+        }
+        if ((pumpStatus20 & 0b01000000) == 0b01000000)//电量耗尽
+        {
+            eventsMap.put("abnormal","电量耗尽");
+        }
+        if ((pumpStatus20 & 0b10000000) == 0b10000000)// 电量偏低预报
+        {
+            eventsMap.put("abnormal","电量偏低预报");
+        }
+        return pumpCode;
+    }
+
+}

+ 73 - 0
jetlinks-components/network-component/network-core/src/main/java/org/jetlinks/community/netpump/NetPumpDeviceMetadataCodec.java

@@ -0,0 +1,73 @@
+package org.jetlinks.community.netpump;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jetlinks.core.message.DeviceMessage;
+import org.jetlinks.core.message.codec.*;
+import org.jetlinks.core.message.event.EventMessage;
+import org.jetlinks.core.message.property.ReportPropertyMessage;
+import org.jetlinks.core.utils.IdUtils;
+import org.reactivestreams.Publisher;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import javax.annotation.Nonnull;
+import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName NetPumpDeviceMetadataCodec.java
+ * @Description TODO
+ * @createTime 2022年01月03日 10:20:00
+ */
+@Slf4j
+public class NetPumpDeviceMetadataCodec implements DeviceMessageCodec {
+
+    @Override
+    public Transport getSupportTransport() {
+        return DefaultTransport.MQTT;
+    }
+
+    @Nonnull
+    @Override
+    public Publisher<DeviceMessage> decode(@Nonnull MessageDecodeContext context) {
+        byte[] bytes = context.getMessage().getPayload().array();
+        String value = DataUtils.byteArrToHexString(bytes);
+
+        return decodeLong(value);
+    }
+
+    @Nonnull
+    @Override
+    public Publisher<? extends EncodedMessage> encode(@Nonnull MessageEncodeContext context) {
+        return Mono.error(new UnsupportedOperationException("该协议不支持数据下行"));
+    }
+
+
+    private Flux<DeviceMessage> decodeLong(String  value){
+        Map<String, Object> propertiesMap=new HashMap<>();
+        Map<String, Object> eventsMap=new HashMap<>();
+        String pumpCode = DataUtils.getLongContent(value, propertiesMap, eventsMap);
+
+        List<DeviceMessage> result = new ArrayList<>();
+        ReportPropertyMessage reportPropertyMessage = new ReportPropertyMessage();
+        reportPropertyMessage.setProperties(propertiesMap);
+        reportPropertyMessage.setDeviceId(pumpCode);
+        reportPropertyMessage.setTimestamp(System.currentTimeMillis());
+        reportPropertyMessage.setMessageId(IdUtils.newUUID());
+        result.add(reportPropertyMessage);
+        Object abnormal = eventsMap.get("abnormal");
+        if(abnormal!=null){
+            EventMessage eventMessage = new EventMessage();
+            eventMessage.setDeviceId(pumpCode);
+            eventMessage.setData(abnormal);
+            eventMessage.setEvent("abnormal");
+            eventMessage.setMessageId(IdUtils.newUUID());
+            eventMessage.setTimestamp(System.currentTimeMillis());
+            result.add(eventMessage);
+        }
+
+        return Flux.fromStream(result.stream());
+    }
+}

+ 42 - 0
jetlinks-components/network-component/network-core/src/main/java/org/jetlinks/community/netpump/NetPumpProtocolSupportProvider.java

@@ -0,0 +1,42 @@
+package org.jetlinks.community.netpump;
+
+import org.jetlinks.community.support.JetLinksExtendMqttDeviceMessageCodec;
+import org.jetlinks.core.ProtocolSupport;
+import org.jetlinks.core.defaults.CompositeProtocolSupport;
+import org.jetlinks.core.message.codec.DefaultTransport;
+import org.jetlinks.core.spi.ProtocolSupportProvider;
+import org.jetlinks.core.spi.ServiceContext;
+import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName NetPumpProtocalSupportProvider.java
+ * @Description TODO
+ * @createTime 2022年01月03日 09:57:00
+ */
+public class NetPumpProtocolSupportProvider implements ProtocolSupportProvider {
+    @Override
+    public Mono<? extends ProtocolSupport> create(ServiceContext context) {
+        return Mono.defer(() -> {
+            CompositeProtocolSupport support = new CompositeProtocolSupport();
+
+            support.setId("netPump V1.0");
+            support.setName("网络泵1.0版本(PC+云端版)");
+            support.setDescription("PC+云端版,此版本为向下兼容版本");
+
+            support.setMetadataCodec(new JetLinksDeviceMetadataCodec());
+
+
+            support.addMessageCodecSupport(new NetPumpDeviceMetadataCodec());
+
+            return Mono.just(support);
+        });
+    }
+
+    @Override
+    public void dispose() {
+
+    }
+}