干燥机配套车间生产管理系统/云平台服务端
bsw215583320
2024-04-09 ae2d52827d289dd985014a63c08b0913d083b215
去掉opc相关业务
已添加4个文件
已修改10个文件
1698 ■■■■■ 文件已修改
jeecg-module-dry/jeecg-module-dry-api/pom.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/JeecgSystemApi.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/fallback/JeecgSystemFallback.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/common/OPCUA.java 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/util/HerbUtil.java 340 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryOpcDeviceController.java 410 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryRealTimeDataController.java 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/OpcController.java 132 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/listener/InitListener.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/runner/OpcCustomRunner.java 116 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/websocket/DrySocket1.java 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-start/src/main/test/java/com/lanbao/AiTest.java 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/pom.xml
@@ -42,11 +42,11 @@
<!--            <artifactId>bcprov-jdk15on</artifactId>-->
<!--            <version>1.70</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.kangaroohy</groupId>
            <artifactId>milo-spring-boot-starter</artifactId>
            <version>3.0.4</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.kangaroohy</groupId>-->
<!--            <artifactId>milo-spring-boot-starter</artifactId>-->
<!--            <version>3.0.4</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-engine</artifactId>
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/JeecgSystemApi.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package org.jeecg.modules.dry.api;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dry.api.fallback.JeecgSystemFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "ichd-system", fallbackFactory = JeecgSystemFallback.class)
@Component
public interface JeecgSystemApi {
    @GetMapping(value = "/sys/dict/getDictText/{dictCode}/{key}")
    Result<String> getDictText(@PathVariable("dictCode") String dictCode, @PathVariable("key") String key);
}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/fallback/JeecgSystemFallback.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package org.jeecg.modules.dry.api.fallback;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.dry.api.DryHelloApi;
import org.jeecg.modules.dry.api.JeecgSystemApi;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
 * @author JeecgBoot
 */
@Slf4j
@Component
public class JeecgSystemFallback implements FallbackFactory<JeecgSystemApi> {
    @Setter
    private Throwable cause;
    @Override
    public JeecgSystemApi create(Throwable throwable) {
        log.error("微服务接口调用失败: {}", cause);
        return null;
    }
}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/common/OPCUA.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,273 @@
//package org.jeecg.modules.dry.common;
//
//import lombok.extern.slf4j.Slf4j;
//import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
//import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
//import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
//import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager;
//import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
//import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedDataItem;
//import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
//import org.eclipse.milo.opcua.stack.core.AttributeId;
//import org.eclipse.milo.opcua.stack.core.Identifiers;
//import org.eclipse.milo.opcua.stack.core.UaException;
//import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
//import org.eclipse.milo.opcua.stack.core.types.builtin.*;
//import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
//import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
//import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
//import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
//import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
//import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
//
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Objects;
//import java.util.concurrent.CountDownLatch;
//import java.util.concurrent.atomic.AtomicInteger;
//
//
//@Slf4j
//public class OPCUA {
//
//    private static AtomicInteger atomic = new AtomicInteger(1);
//    // å®šä¹‰æœåŠ¡ç«¯åœ°å€
//    private final static String endPointUrl = "opc.tcp://127.0.0.1:49320";
//
//
//    /**
//     * åˆ›å»ºOPC UA客户端
//     * @return
//     * @throws Exception
//     */
//    public static OpcUaClient createClient() throws Exception {
//
//        Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
//        Files.createDirectories(securityTempDir);
//        if (!Files.exists(securityTempDir)) {
//            throw new Exception("unable to create security dir: " + securityTempDir);
//        }
//        return OpcUaClient.create(endPointUrl,
//            endpoints ->
//                endpoints.stream()
//                    .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
//                    .findFirst(),
//            configBuilder ->
//                configBuilder
//                    .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
//                    .setApplicationUri("urn:eclipse:milo:examples:client")
//                    //访问方式
//                    .setIdentityProvider(new AnonymousProvider())
//                    .setRequestTimeout(UInteger.valueOf(5000))
//                    .build()
//        );
//    }
//
//    /**
//     * éåŽ†æ ‘å½¢èŠ‚ç‚¹
//     *
//     * @param client OPC UA客户端
//     * @param uaNode èŠ‚ç‚¹
//     * @throws Exception
//     */
//    public static void browseNode(OpcUaClient client, UaNode uaNode) throws Exception {
//        List<? extends UaNode> nodes;
//        if (uaNode == null) {
//            nodes = client.getAddressSpace().browseNodes(Identifiers.ObjectsFolder);
//        } else {
//            nodes = client.getAddressSpace().browseNodes(uaNode);
//        }
//        for (UaNode nd : nodes) {
//            //排除系统行性节点,这些系统性节点名称一般都是以"_"开头
//            if (Objects.requireNonNull(nd.getBrowseName().getName()).contains("_")) {
//                continue;
//            }
//            System.out.println("Node= " + nd.getBrowseName().getName());
//            browseNode(client, nd);
//        }
//    }
//
//
//    /**
//     * è¯»å–节点数据
//     *
//     * @param client OPC UA客户端
//     * @throws Exception
//     */
//    public static void readNode(OpcUaClient client) throws Exception {
//        int namespaceIndex = 2;
//        String identifier = "TD-01.SB-01.AG-01";
//        //节点
//        NodeId nodeId = new NodeId(namespaceIndex, identifier);
//        //读取节点数据
//        DataValue value = client.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
//
//        System.out.println(identifier + ": " + String.valueOf(value.getValue().getValue()));
//    }
//
//
//    /**
//     * å†™å…¥èŠ‚ç‚¹æ•°æ®
//     *
//     * @param client
//     * @throws Exception
//     */
//    public static void writeNodeValue(OpcUaClient client) throws Exception {
//        //节点
//        NodeId nodeId = new NodeId(2, "TD-01.SB-01.AG-01");
//        short i = 3;
//        //创建数据对象,此处的数据对象一定要定义类型,不然会出现类型错误,导致无法写入
//        DataValue nowValue = new DataValue(new Variant(i), null, null);
//        //写入节点数据
//        StatusCode statusCode = client.writeValue(nodeId, nowValue).join();
//        System.out.println("结果:" + statusCode.isGood());
//    }
//
//
//    /**
//     * è®¢é˜…(单个)
//     *
//     * @param client
//     * @throws Exception
//     */
//    public static void subscribe(OpcUaClient client) throws Exception {
//        //创建发布间隔1000ms的订阅对象
//        client
//            .getSubscriptionManager()
//            .createSubscription(1000.0)
//            .thenAccept(t -> {
//                //节点
//                NodeId nodeId = new NodeId(2, "TD-01.SB-01.AG-01");
//                ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
//                //创建监控的参数
//                MonitoringParameters parameters = new MonitoringParameters(UInteger.valueOf(atomic.getAndIncrement()), 1000.0, null, UInteger.valueOf(10), true);
//                //创建监控项请求
//                //该请求最后用于创建订阅。
//                MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters);
//                List<MonitoredItemCreateRequest> requests = new ArrayList<>();
//                requests.add(request);
//                //创建监控项,并且注册变量值改变时候的回调函数。
//                t.createMonitoredItems(
//                    TimestampsToReturn.Both,
//                    requests,
//                    (item, id) -> item.setValueConsumer((it, val) -> {
//                        System.out.println("nodeid :" + it.getReadValueId().getNodeId());
//                        System.out.println("value :" + val.getValue().getValue());
//                    })
//                );
//            }).get();
//
//        //持续订阅
//        Thread.sleep(Long.MAX_VALUE);
//    }
//
//
//    /**
//     * æ‰¹é‡è®¢é˜…
//     *
//     * @param client
//     * @throws Exception
//     */
////    private static void managedSubscriptionEvent(OpcUaClient client) throws Exception {
////        final CountDownLatch eventLatch = new CountDownLatch(1);
////
////        //处理订阅业务
////        handlerNode(client);
////
////        //持续监听
////        eventLatch.await();
////    }
//
//    /**
//     * å¤„理订阅业务
//     *
//     * @param client OPC UA客户端
//     */
//    public static void handlerNode(OpcUaClient client) {
//        try {
//            //创建订阅
//            ManagedSubscription subscription = ManagedSubscription.create(client);
//
//            //你所需要订阅的key
//            List<String> key = new ArrayList<>();
//            key.add("通道 1.设备 1.标记 1");
//            key.add("通道 1.设备 1.标记 2");
//
//            List<NodeId> nodeIdList = new ArrayList<>();
//            for (String s : key) {
//                nodeIdList.add(new NodeId(2, s));
//            }
//
//            //监听
//            List<ManagedDataItem> dataItemList = subscription.createDataItems(nodeIdList);
//            for (ManagedDataItem managedDataItem : dataItemList) {
//                managedDataItem.addDataValueListener((t) -> {
//                    System.out.println(managedDataItem.getNodeId().getIdentifier().toString() + ":" + t.getValue().getValue().toString());
//                });
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    /**
//     * è‡ªå®šä¹‰è®¢é˜…监听
//     */
//    public static class CustomSubscriptionListener implements UaSubscriptionManager.SubscriptionListener {
//
//        private OpcUaClient client;
//
//        CustomSubscriptionListener(OpcUaClient client) {
//            this.client = client;
//        }
//
//        public void onKeepAlive(UaSubscription subscription, DateTime publishTime) {
//            log.debug("onKeepAlive");
//        }
//
//        public void onStatusChanged(UaSubscription subscription, StatusCode status) {
//            log.debug("onStatusChanged");
//        }
//
//        public void onPublishFailure(UaException exception) {
//            log.debug("onPublishFailure");
//        }
//
//        public void onNotificationDataLost(UaSubscription subscription) {
//            log.debug("onNotificationDataLost");
//        }
//
//        /**
//         * é‡è¿žæ—¶ å°è¯•恢复之前的订阅失败时 ä¼šè°ƒç”¨æ­¤æ–¹æ³•
//         * @param uaSubscription è®¢é˜…
//         * @param statusCode çŠ¶æ€
//         */
//        public void onSubscriptionTransferFailed(UaSubscription uaSubscription, StatusCode statusCode) {
//            log.debug("恢复订阅失败 éœ€è¦é‡æ–°è®¢é˜…");
//            //在回调方法中重新订阅
//            handlerNode(client);
//        }
//    }
//
//    /**
//     * æ‰¹é‡è®¢é˜…
//     *
//     * @param client
//     * @throws Exception
//     */
//    public static void managedSubscriptionEvent(OpcUaClient client) throws Exception {
//        final CountDownLatch eventLatch = new CountDownLatch(1);
//
//        //添加订阅监听器,用于处理断线重连后的订阅问题
//        client.getSubscriptionManager().addSubscriptionListener(new CustomSubscriptionListener(client));
//
//        //处理订阅业务
//        handlerNode(client);
//
//        //持续监听
//        eventLatch.await();
//    }
//}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/util/HerbUtil.java
@@ -1,170 +1,170 @@
package org.jeecg.modules.dry.util;
import ai.djl.Device;
import ai.djl.Model;
import ai.djl.inference.Predictor;
import ai.djl.modality.Classifications;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.transform.*;
import ai.djl.modality.cv.translator.ImageClassificationTranslator;
import ai.djl.translate.Translator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class HerbUtil {
    //规定输入尺寸
    private static final int INPUT_SIZE = 224;
    private static final int TARGET_SIZE = 256;
    //标签文件 ä¸€ç§ç±»åˆ«åå­—占一行
    private List<String> herbNames;
    //用于识别
    Predictor<Image, Classifications> predictor;
    //模型
    private Model model;
    public HerbUtil() {
        //加载标签到herbNames中
        this.loadHerbNames();
        //初始化模型工作
        this.init();
    }
    public List<Classifications.Classification> predict(InputStream inputStream) {
        List<Classifications.Classification> result = new ArrayList<>();
        Image input = this.resizeImage(inputStream);
        try {
            Classifications output = predictor.predict(input);
            System.out.println("推测为:" + output.best().getClassName()
                    + ", æ¦‚率:" + output.best().getProbability());
            System.out.println(output);
            result = output.topK();
        } catch (Exception e) {
            log.error("药材识别异常!!");
            log.error(input.toString());
            log.error(predictor.toString());
            e.printStackTrace();
        }
        return result;
    }
    private void loadHerbNames() {
        BufferedReader reader = null;
        herbNames = new ArrayList<>();
        try {
            InputStream in = HerbUtil.class.getClassLoader().getResourceAsStream("class.txt");
            reader = new BufferedReader(new InputStreamReader(in));
            String name = null;
            while ((name = reader.readLine()) != null) {
                herbNames.add(name);
            }
            System.out.println(herbNames);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    private void init() {
        Translator<Image, Classifications> translator = ImageClassificationTranslator.builder()
                //下面的transform根据自己的改
                .addTransform(new CenterCrop(INPUT_SIZE,INPUT_SIZE))
                .addTransform(new ToTensor())
                .addTransform(new Normalize(
                        new float[] {0.485f, 0.456f, 0.406f},
                        new float[] {0.229f, 0.224f, 0.225f}))
                //载入所有标签进去
                .optSynset(herbNames)
                //最终显示概率最高的5个
                .optTopK(5)
                .build();
        //随便起名
        Model model = Model.newInstance("model", Device.cpu());
        try {
//            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//            Resource[] resources = resolver.getResources("../pytorch/model34.pt");
            //            Resource resource = resources[0];
            File f = new File("../pytorch/model34.pt");
            InputStream inputStream = new FileInputStream(f);
           // InputStream inputStream = HerbUtil.class.getClassLoader().getResourceAsStream("model34.pt");
            if (inputStream == null) {
                throw new RuntimeException("找不到模型文件");
            }
            model.load(inputStream);
            predictor = model.newPredictor(translator);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private Image resizeImage(InputStream inputStream) {
        BufferedImage input = null;
        try {
            input = ImageIO.read(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        int iw = input.getWidth(), ih = input.getHeight();
        int w = 256, h = 256;
        double scale = Math.max(1. *  w / iw, 1. * h / ih);
        int nw = (int) (iw * scale), nh = (int) (ih * scale);
        java.awt.Image img;
        //只有太长或太宽才会保留横纵比,填充颜色
       // boolean needResize = 1. * iw / ih > 1.4 || 1. * ih / iw > 1.4;
      //  if (needResize) {
            img = input.getScaledInstance(nw, nh, BufferedImage.SCALE_SMOOTH);
      //  } else {
       //     img = input.getScaledInstance(INPUT_SIZE, INPUT_SIZE, BufferedImage.SCALE_SMOOTH);
      //  }
        BufferedImage out = new BufferedImage(nw, nh, BufferedImage.TYPE_INT_RGB);
        Graphics g = out.getGraphics();
        //先将整个224*224区域填充128 128 128颜色
        g.setColor(new Color(255, 255, 255));
        g.fillRect(0, 0, nw, nh);
        out.getGraphics().drawImage(img, 0, 0, null);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream);
            ImageIO.write(out, "jpg", imageOutputStream);
            //去D盘看效果
            ImageIO.write(out, "jpg", new File("E:\\out.jpg"));
            InputStream is = new ByteArrayInputStream(outputStream.toByteArray());
            return ImageFactory.getInstance().fromInputStream(is);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("图片转换失败");
        }
    }
}
//package org.jeecg.modules.dry.util;
//
//import ai.djl.Device;
//import ai.djl.Model;
//import ai.djl.inference.Predictor;
//import ai.djl.modality.Classifications;
//import ai.djl.modality.cv.Image;
//import ai.djl.modality.cv.ImageFactory;
//import ai.djl.modality.cv.transform.*;
//import ai.djl.modality.cv.translator.ImageClassificationTranslator;
//import ai.djl.translate.Translator;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.core.io.Resource;
//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
//import org.springframework.core.io.support.ResourcePatternResolver;
//import org.springframework.stereotype.Component;
//
//import javax.imageio.ImageIO;
//import javax.imageio.stream.ImageOutputStream;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.io.*;
//import java.util.ArrayList;
//import java.util.List;
//
//@Slf4j
//@Component
//public class HerbUtil {
//
//    //规定输入尺寸
//    private static final int INPUT_SIZE = 224;
//
//    private static final int TARGET_SIZE = 256;
//
//    //标签文件 ä¸€ç§ç±»åˆ«åå­—占一行
//    private List<String> herbNames;
//
//    //用于识别
//    Predictor<Image, Classifications> predictor;
//
//    //模型
//    private Model model;
//
//    public HerbUtil() {
//        //加载标签到herbNames中
//        this.loadHerbNames();
//        //初始化模型工作
//        this.init();
//
//
//
//    }
//
//    public List<Classifications.Classification> predict(InputStream inputStream) {
//        List<Classifications.Classification> result = new ArrayList<>();
//        Image input = this.resizeImage(inputStream);
//        try {
//            Classifications output = predictor.predict(input);
//            System.out.println("推测为:" + output.best().getClassName()
//                    + ", æ¦‚率:" + output.best().getProbability());
//            System.out.println(output);
//            result = output.topK();
//        } catch (Exception e) {
//            log.error("药材识别异常!!");
//            log.error(input.toString());
//            log.error(predictor.toString());
//            e.printStackTrace();
//        }
//        return result;
//    }
//
//    private void loadHerbNames() {
//        BufferedReader reader = null;
//        herbNames = new ArrayList<>();
//        try {
//            InputStream in = HerbUtil.class.getClassLoader().getResourceAsStream("class.txt");
//            reader = new BufferedReader(new InputStreamReader(in));
//            String name = null;
//            while ((name = reader.readLine()) != null) {
//                herbNames.add(name);
//            }
//            System.out.println(herbNames);
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            if (reader != null) {
//                try {
//                    reader.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    private void init() {
//        Translator<Image, Classifications> translator = ImageClassificationTranslator.builder()
//                //下面的transform根据自己的改
//                .addTransform(new CenterCrop(INPUT_SIZE,INPUT_SIZE))
//
//                .addTransform(new ToTensor())
//                .addTransform(new Normalize(
//                        new float[] {0.485f, 0.456f, 0.406f},
//                        new float[] {0.229f, 0.224f, 0.225f}))
//
//                //载入所有标签进去
//                .optSynset(herbNames)
//                //最终显示概率最高的5个
//                .optTopK(5)
//                .build();
//        //随便起名
//        Model model = Model.newInstance("model", Device.cpu());
//        try {
////            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
////            Resource[] resources = resolver.getResources("../pytorch/model34.pt");
//            //            Resource resource = resources[0];
//            File f = new File("../pytorch/model34.pt");
//
//            InputStream inputStream = new FileInputStream(f);
//           // InputStream inputStream = HerbUtil.class.getClassLoader().getResourceAsStream("model34.pt");
//            if (inputStream == null) {
//                throw new RuntimeException("找不到模型文件");
//            }
//            model.load(inputStream);
//
//            predictor = model.newPredictor(translator);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    private Image resizeImage(InputStream inputStream) {
//        BufferedImage input = null;
//        try {
//            input = ImageIO.read(inputStream);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        int iw = input.getWidth(), ih = input.getHeight();
//        int w = 256, h = 256;
//        double scale = Math.max(1. *  w / iw, 1. * h / ih);
//        int nw = (int) (iw * scale), nh = (int) (ih * scale);
//        java.awt.Image img;
//        //只有太长或太宽才会保留横纵比,填充颜色
//       // boolean needResize = 1. * iw / ih > 1.4 || 1. * ih / iw > 1.4;
//      //  if (needResize) {
//            img = input.getScaledInstance(nw, nh, BufferedImage.SCALE_SMOOTH);
//      //  } else {
//       //     img = input.getScaledInstance(INPUT_SIZE, INPUT_SIZE, BufferedImage.SCALE_SMOOTH);
//      //  }
//        BufferedImage out = new BufferedImage(nw, nh, BufferedImage.TYPE_INT_RGB);
//        Graphics g = out.getGraphics();
//        //先将整个224*224区域填充128 128 128颜色
//        g.setColor(new Color(255, 255, 255));
//        g.fillRect(0, 0, nw, nh);
//        out.getGraphics().drawImage(img, 0, 0, null);
//        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        try {
//            ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream);
//            ImageIO.write(out, "jpg", imageOutputStream);
//            //去D盘看效果
//            ImageIO.write(out, "jpg", new File("E:\\out.jpg"));
//            InputStream is = new ByteArrayInputStream(outputStream.toByteArray());
//            return ImageFactory.getInstance().fromInputStream(is);
//        } catch (IOException e) {
//            e.printStackTrace();
//            throw new RuntimeException("图片转换失败");
//        }
//    }
//}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryOpcDeviceController.java
@@ -1,205 +1,205 @@
package org.jeecg.modules.dry.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.dry.entity.DryOpcDevice;
import org.jeecg.modules.dry.service.IDryOpcDeviceService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
 /**
 * @Description: dry_opc_device
 * @Author: jeecg-boot
 * @Date:   2023-11-28
 * @Version: V1.0
 */
@Api(tags="dry_opc_device")
@RestController
@RequestMapping("/dry/dryOpcDevice")
@Slf4j
public class DryOpcDeviceController extends JeecgController<DryOpcDevice, IDryOpcDeviceService> {
    @Autowired
    private IDryOpcDeviceService dryOpcDeviceService;
    @Autowired
    private MiloService miloService;
    /**
     * åˆ†é¡µåˆ—表查询
     *
     * @param dryOpcDevice
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "dry_opc_device-分页列表查询")
    @ApiOperation(value="dry_opc_device-分页列表查询", notes="dry_opc_device-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<DryOpcDevice>> queryPageList(DryOpcDevice dryOpcDevice,
                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap());
        Page<DryOpcDevice> page = new Page<DryOpcDevice>(pageNo, pageSize);
        IPage<DryOpcDevice> pageList = dryOpcDeviceService.page(page, queryWrapper);
        return Result.OK(pageList);
    }
     @GetMapping(value = "/listAll")
     public Result<List<DryOpcDevice>> queryList(DryOpcDevice dryOpcDevice,
                                                      HttpServletRequest req) {
         QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap());
         queryWrapper.orderByAsc("sort_order");
         List<DryOpcDevice> list = dryOpcDeviceService.list(queryWrapper);
        list.forEach(item -> {
            try {
                ReadWriteEntity readWriteEntity = miloService.readFromOpcUa(item.getIdentifier());
                item.setValue((Boolean) readWriteEntity.getValue());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
         return Result.OK(list);
     }
    /**
     *   æ·»åŠ 
     *
     * @param dryOpcDevice
     * @return
     */
    @AutoLog(value = "dry_opc_device-添加")
    @ApiOperation(value="dry_opc_device-添加", notes="dry_opc_device-添加")
    @RequiresPermissions("dry:dry_opc_device:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody DryOpcDevice dryOpcDevice) {
        dryOpcDeviceService.save(dryOpcDevice);
        return Result.OK("添加成功!");
    }
    /**
     *  ç¼–辑
     *
     * @param dryOpcDevice
     * @return
     */
    @AutoLog(value = "dry_opc_device-编辑")
    @ApiOperation(value="dry_opc_device-编辑", notes="dry_opc_device-编辑")
    @RequiresPermissions("dry:dry_opc_device:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> edit(@RequestBody DryOpcDevice dryOpcDevice) {
        dryOpcDeviceService.updateById(dryOpcDevice);
        return Result.OK("编辑成功!");
    }
    /**
     *   é€šè¿‡id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "dry_opc_device-通过id删除")
    @ApiOperation(value="dry_opc_device-通过id删除", notes="dry_opc_device-通过id删除")
    @RequiresPermissions("dry:dry_opc_device:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name="id",required=true) String id) {
        dryOpcDeviceService.removeById(id);
        return Result.OK("删除成功!");
    }
    /**
     *  æ‰¹é‡åˆ é™¤
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "dry_opc_device-批量删除")
    @ApiOperation(value="dry_opc_device-批量删除", notes="dry_opc_device-批量删除")
    @RequiresPermissions("dry:dry_opc_device:deleteBatch")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
        this.dryOpcDeviceService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }
    /**
     * é€šè¿‡id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "dry_opc_device-通过id查询")
    @ApiOperation(value="dry_opc_device-通过id查询", notes="dry_opc_device-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<DryOpcDevice> queryById(@RequestParam(name="id",required=true) String id) {
        DryOpcDevice dryOpcDevice = dryOpcDeviceService.getById(id);
        if(dryOpcDevice==null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(dryOpcDevice);
    }
    /**
    * å¯¼å‡ºexcel
    *
    * @param request
    * @param dryOpcDevice
    */
    @RequiresPermissions("dry:dry_opc_device:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, DryOpcDevice dryOpcDevice) {
        return super.exportXls(request, dryOpcDevice, DryOpcDevice.class, "dry_opc_device");
    }
    /**
      * é€šè¿‡excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequiresPermissions("dry:dry_opc_device:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, DryOpcDevice.class);
    }
}
//package org.jeecg.modules.dry.controller;
//
//import java.util.Arrays;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//import java.io.IOException;
//import java.io.UnsupportedEncodingException;
//import java.net.URLDecoder;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//
//import com.kangaroohy.milo.model.ReadWriteEntity;
//import com.kangaroohy.milo.service.MiloService;
//import org.jeecg.common.api.vo.Result;
//import org.jeecg.common.system.query.QueryGenerator;
//import org.jeecg.common.util.oConvertUtils;
//import org.jeecg.modules.dry.entity.DryOpcDevice;
//import org.jeecg.modules.dry.service.IDryOpcDeviceService;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import lombok.extern.slf4j.Slf4j;
//
//import org.jeecgframework.poi.excel.ExcelImportUtil;
//import org.jeecgframework.poi.excel.def.NormalExcelConstants;
//import org.jeecgframework.poi.excel.entity.ExportParams;
//import org.jeecgframework.poi.excel.entity.ImportParams;
//import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
//import org.jeecg.common.system.base.controller.JeecgController;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//import org.springframework.web.multipart.MultipartHttpServletRequest;
//import org.springframework.web.servlet.ModelAndView;
//import com.alibaba.fastjson.JSON;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.jeecg.common.aspect.annotation.AutoLog;
//import org.apache.shiro.authz.annotation.RequiresPermissions;
//
// /**
// * @Description: dry_opc_device
// * @Author: jeecg-boot
// * @Date:   2023-11-28
// * @Version: V1.0
// */
//@Api(tags="dry_opc_device")
//@RestController
//@RequestMapping("/dry/dryOpcDevice")
//@Slf4j
//public class DryOpcDeviceController extends JeecgController<DryOpcDevice, IDryOpcDeviceService> {
//    @Autowired
//    private IDryOpcDeviceService dryOpcDeviceService;
//
//
//    @Autowired
//    private MiloService miloService;
//
//
//    /**
//     * åˆ†é¡µåˆ—表查询
//     *
//     * @param dryOpcDevice
//     * @param pageNo
//     * @param pageSize
//     * @param req
//     * @return
//     */
//    //@AutoLog(value = "dry_opc_device-分页列表查询")
//    @ApiOperation(value="dry_opc_device-分页列表查询", notes="dry_opc_device-分页列表查询")
//    @GetMapping(value = "/list")
//    public Result<IPage<DryOpcDevice>> queryPageList(DryOpcDevice dryOpcDevice,
//                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
//                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
//                                   HttpServletRequest req) {
//        QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap());
//        Page<DryOpcDevice> page = new Page<DryOpcDevice>(pageNo, pageSize);
//        IPage<DryOpcDevice> pageList = dryOpcDeviceService.page(page, queryWrapper);
//        return Result.OK(pageList);
//    }
//
//     @GetMapping(value = "/listAll")
//     public Result<List<DryOpcDevice>> queryList(DryOpcDevice dryOpcDevice,
//
//                                                      HttpServletRequest req) {
//         QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap());
//         queryWrapper.orderByAsc("sort_order");
//         List<DryOpcDevice> list = dryOpcDeviceService.list(queryWrapper);
//        list.forEach(item -> {
//            try {
//                ReadWriteEntity readWriteEntity = miloService.readFromOpcUa(item.getIdentifier());
//                item.setValue((Boolean) readWriteEntity.getValue());
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        });
//         return Result.OK(list);
//     }
//
//
//    /**
//     *   æ·»åŠ 
//     *
//     * @param dryOpcDevice
//     * @return
//     */
//    @AutoLog(value = "dry_opc_device-添加")
//    @ApiOperation(value="dry_opc_device-添加", notes="dry_opc_device-添加")
//    @RequiresPermissions("dry:dry_opc_device:add")
//    @PostMapping(value = "/add")
//    public Result<String> add(@RequestBody DryOpcDevice dryOpcDevice) {
//        dryOpcDeviceService.save(dryOpcDevice);
//        return Result.OK("添加成功!");
//    }
//
//    /**
//     *  ç¼–辑
//     *
//     * @param dryOpcDevice
//     * @return
//     */
//    @AutoLog(value = "dry_opc_device-编辑")
//    @ApiOperation(value="dry_opc_device-编辑", notes="dry_opc_device-编辑")
//    @RequiresPermissions("dry:dry_opc_device:edit")
//    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
//    public Result<String> edit(@RequestBody DryOpcDevice dryOpcDevice) {
//        dryOpcDeviceService.updateById(dryOpcDevice);
//        return Result.OK("编辑成功!");
//    }
//
//    /**
//     *   é€šè¿‡id删除
//     *
//     * @param id
//     * @return
//     */
//    @AutoLog(value = "dry_opc_device-通过id删除")
//    @ApiOperation(value="dry_opc_device-通过id删除", notes="dry_opc_device-通过id删除")
//    @RequiresPermissions("dry:dry_opc_device:delete")
//    @DeleteMapping(value = "/delete")
//    public Result<String> delete(@RequestParam(name="id",required=true) String id) {
//        dryOpcDeviceService.removeById(id);
//        return Result.OK("删除成功!");
//    }
//
//    /**
//     *  æ‰¹é‡åˆ é™¤
//     *
//     * @param ids
//     * @return
//     */
//    @AutoLog(value = "dry_opc_device-批量删除")
//    @ApiOperation(value="dry_opc_device-批量删除", notes="dry_opc_device-批量删除")
//    @RequiresPermissions("dry:dry_opc_device:deleteBatch")
//    @DeleteMapping(value = "/deleteBatch")
//    public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
//        this.dryOpcDeviceService.removeByIds(Arrays.asList(ids.split(",")));
//        return Result.OK("批量删除成功!");
//    }
//
//    /**
//     * é€šè¿‡id查询
//     *
//     * @param id
//     * @return
//     */
//    //@AutoLog(value = "dry_opc_device-通过id查询")
//    @ApiOperation(value="dry_opc_device-通过id查询", notes="dry_opc_device-通过id查询")
//    @GetMapping(value = "/queryById")
//    public Result<DryOpcDevice> queryById(@RequestParam(name="id",required=true) String id) {
//        DryOpcDevice dryOpcDevice = dryOpcDeviceService.getById(id);
//        if(dryOpcDevice==null) {
//            return Result.error("未找到对应数据");
//        }
//        return Result.OK(dryOpcDevice);
//    }
//
//    /**
//    * å¯¼å‡ºexcel
//    *
//    * @param request
//    * @param dryOpcDevice
//    */
//    @RequiresPermissions("dry:dry_opc_device:exportXls")
//    @RequestMapping(value = "/exportXls")
//    public ModelAndView exportXls(HttpServletRequest request, DryOpcDevice dryOpcDevice) {
//        return super.exportXls(request, dryOpcDevice, DryOpcDevice.class, "dry_opc_device");
//    }
//
//    /**
//      * é€šè¿‡excel导入数据
//    *
//    * @param request
//    * @param response
//    * @return
//    */
//    @RequiresPermissions("dry:dry_opc_device:importExcel")
//    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
//    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
//        return super.importExcel(request, response, DryOpcDevice.class);
//    }
//
//}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryRealTimeDataController.java
@@ -12,7 +12,7 @@
import org.jeecg.modules.dry.entity.DryHerbInfo;
import org.jeecg.modules.dry.service.*;
import org.jeecg.modules.dry.util.HerbUtil;
//import org.jeecg.modules.dry.util.HerbUtil;
import org.jeecg.modules.dry.vo.CommandMessageVo;
import org.jeecg.modules.dry.vo.DryHerbInfoVo;
import org.jeecg.modules.dry.vo.RealTimeDataVo;
@@ -36,8 +36,8 @@
    @Autowired
    private IDryRealTimeDataService dryRealTimeDataService;
    @Autowired
    private HerbUtil herbUtil;
//    @Autowired
//    private HerbUtil herbUtil;
    @Autowired
    private IDryHerbInfoService herbInfoService;
@@ -85,43 +85,43 @@
        return dryRealTimeDataService.sendSocketMsg(msgVo);
    }
    @ApiOperation(value = "药材识别")
    @PostMapping("/identify")
    public Result<?> identify(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            if (file.isEmpty()) {
                throw new RuntimeException("上传文件不能为空");
            }
            InputStream inputStream = file.getInputStream();
            List<Classifications.Classification> predict = herbUtil.predict(inputStream);
            if(predict.size()>0) {
                Map<String, Double> collect = predict.stream().collect(Collectors.toMap(Classifications.Classification::getClassName, Classifications.Classification::getProbability));
                List<DryHerbInfoVo> voList = new ArrayList<>();
                Set<String> strings = collect.keySet();
                List<DryHerbInfo> list = herbInfoService.list(new LambdaQueryWrapper<DryHerbInfo>().in(DryHerbInfo::getPinyin, strings));
                list.forEach(item -> {
                    DryHerbInfoVo dryHerbInfoVo = new DryHerbInfoVo();
                    BeanUtil.copyProperties(item, dryHerbInfoVo);
                    dryHerbInfoVo.setProbabily(collect.get(item.getPinyin()));
                    voList.add(dryHerbInfoVo);
                });
                List<DryHerbInfoVo> collect1 = voList.stream().sorted(Comparator.comparing(DryHerbInfoVo::getProbabily, Comparator.reverseOrder())).
                        collect(Collectors.toList());
                return Result.ok(collect1);
            } else {
                return Result.error("AI识别服务异常");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("AI识别服务异常");
        }
    }
//
//    @ApiOperation(value = "药材识别")
//    @PostMapping("/identify")
//    public Result<?> identify(@RequestParam("file") MultipartFile file) throws Exception {
//        try {
//            if (file.isEmpty()) {
//                throw new RuntimeException("上传文件不能为空");
//            }
//            InputStream inputStream = file.getInputStream();
//            List<Classifications.Classification> predict = herbUtil.predict(inputStream);
//
//            if(predict.size()>0) {
//                Map<String, Double> collect = predict.stream().collect(Collectors.toMap(Classifications.Classification::getClassName, Classifications.Classification::getProbability));
//
//
//                List<DryHerbInfoVo> voList = new ArrayList<>();
//                Set<String> strings = collect.keySet();
//                List<DryHerbInfo> list = herbInfoService.list(new LambdaQueryWrapper<DryHerbInfo>().in(DryHerbInfo::getPinyin, strings));
//                list.forEach(item -> {
//                    DryHerbInfoVo dryHerbInfoVo = new DryHerbInfoVo();
//                    BeanUtil.copyProperties(item, dryHerbInfoVo);
//                    dryHerbInfoVo.setProbabily(collect.get(item.getPinyin()));
//                    voList.add(dryHerbInfoVo);
//                });
//
//                List<DryHerbInfoVo> collect1 = voList.stream().sorted(Comparator.comparing(DryHerbInfoVo::getProbabily, Comparator.reverseOrder())).
//                        collect(Collectors.toList());
//
//                return Result.ok(collect1);
//            } else {
//                return Result.error("AI识别服务异常");
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//            return Result.error("AI识别服务异常");
//        }
//    }
}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/OpcController.java
@@ -1,66 +1,66 @@
package org.jeecg.modules.dry.controller;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dry.entity.DryOpcDevice;
import org.jeecg.modules.dry.service.IDryOpcDeviceService;
import org.jeecg.modules.dry.vo.CommandMessageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
 * opc控制器,用于控制现场摄像头电源,灯的开关
 */
@Api(tags="OPC控制器")
@RestController
@RequestMapping("/dry/opc")
@Slf4j
public class OpcController {
    @Autowired
    private MiloService miloService;
    @Autowired
    private IDryOpcDeviceService opcDeviceService;
    @ApiOperation(value="发送控制指令", notes="向服务端发送控制指令,由服务端转发给控制模块")
    @PostMapping("/sendWriteCommand")
    public Result<?> sendWriteCommand(@RequestBody CommandMessageVo msgVo) throws Exception {
        miloService.writeToOpcUa(ReadWriteEntity.builder()
                .identifier(msgVo.getCode())
                //Kep中是Boolean类型
                .value(Boolean.valueOf(msgVo.getMsg()))
                .build());
        return Result.OK();
    }
    @ApiOperation(value="发送控制指令", notes="向服务端发送控制指令,由服务端转发给控制模块")
    @PostMapping("/initDevice")
    public Result<?> initDevice() throws Exception {
        List<DryOpcDevice> list = opcDeviceService.list();
        list.forEach(item -> {
        });
        return Result.OK();
    }
}
//package org.jeecg.modules.dry.controller;
//
//import com.kangaroohy.milo.model.ReadWriteEntity;
//import com.kangaroohy.milo.service.MiloService;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
//import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
//import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
//import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
//import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
//import org.jeecg.common.api.vo.Result;
//import org.jeecg.modules.dry.entity.DryOpcDevice;
//import org.jeecg.modules.dry.service.IDryOpcDeviceService;
//import org.jeecg.modules.dry.vo.CommandMessageVo;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import java.util.List;
//import java.util.concurrent.ExecutionException;
//
///**
// * opc控制器,用于控制现场摄像头电源,灯的开关
// */
//
//@Api(tags="OPC控制器")
//@RestController
//@RequestMapping("/dry/opc")
//@Slf4j
//public class OpcController {
//
//    @Autowired
//    private MiloService miloService;
//
//    @Autowired
//    private IDryOpcDeviceService opcDeviceService;
//
//
//    @ApiOperation(value="发送控制指令", notes="向服务端发送控制指令,由服务端转发给控制模块")
//    @PostMapping("/sendWriteCommand")
//    public Result<?> sendWriteCommand(@RequestBody CommandMessageVo msgVo) throws Exception {
//
//        miloService.writeToOpcUa(ReadWriteEntity.builder()
//                .identifier(msgVo.getCode())
//                //Kep中是Boolean类型
//                .value(Boolean.valueOf(msgVo.getMsg()))
//                .build());
//        return Result.OK();
//    }
//
//    @ApiOperation(value="发送控制指令", notes="向服务端发送控制指令,由服务端转发给控制模块")
//    @PostMapping("/initDevice")
//    public Result<?> initDevice() throws Exception {
//        List<DryOpcDevice> list = opcDeviceService.list();
//
//        list.forEach(item -> {
//
//        });
//
//        return Result.OK();
//    }
//}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/listener/InitListener.java
@@ -1,21 +1,12 @@
package org.jeecg.modules.dry.listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.io.ByteStreams;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.jeecg.modules.dry.common.CacheConstants;
import org.jeecg.modules.dry.common.CommonDict;
import org.jeecg.modules.dry.vo.DryFault;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//@Component
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/runner/OpcCustomRunner.java
@@ -1,58 +1,58 @@
package org.jeecg.modules.dry.runner;
import com.alibaba.fastjson.JSON;
import com.kangaroohy.milo.service.MiloService;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.dry.entity.DryOpcDevice;
import org.jeecg.modules.dry.service.IDryOpcDeviceService;
import org.jeecg.modules.dry.vo.DryOpcMsgVo;
import org.jeecg.modules.dry.websocket.DrySocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@Slf4j
public class OpcCustomRunner implements ApplicationRunner {
    @Autowired
    private MiloService miloService;
    @Autowired
    private IDryOpcDeviceService dryOpcDeviceService;
    @Autowired
    private DrySocket drySocket;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        subscript();
    }
    private void subscript() throws Exception {
        List<String> ids = new ArrayList<>();
        List<DryOpcDevice> list = dryOpcDeviceService.list();
        list.forEach(item -> {
            ids.add(item.getIdentifier());
        });
//        ids.add("通道 1.设备 1.标记 1");
//        ids.add("通道 1.设备 1.标记 2");
//        ids.add("channel1.device1.tag1");
//        ids.add("channel1.device1.tag2");
//        ids.add("channel1.device1.tag3");
//        ids.add("channel1.device1.tag4");
//        ids.add("channel1.device1.tag5");
//        ids.add("channel1.device1.tag6");
        miloService.subscriptionFromOpcUa(ids, (id,value)->{
            log.info("subscription ç‚¹ä½ï¼š{} è®¢é˜…到消息:{}", id, value);
            DryOpcMsgVo dryOpcMsgVo = new DryOpcMsgVo(id, (Boolean) value);
            drySocket.pushMessage("1003", JSON.toJSONString(dryOpcMsgVo));
        } );
    }
}
//package org.jeecg.modules.dry.runner;
//
//import com.alibaba.fastjson.JSON;
//import com.kangaroohy.milo.service.MiloService;
//import lombok.extern.slf4j.Slf4j;
//import org.jeecg.modules.dry.entity.DryOpcDevice;
//import org.jeecg.modules.dry.service.IDryOpcDeviceService;
//import org.jeecg.modules.dry.vo.DryOpcMsgVo;
//import org.jeecg.modules.dry.websocket.DrySocket;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.ApplicationArguments;
//import org.springframework.boot.ApplicationRunner;
//import org.springframework.stereotype.Component;
//
//import java.util.ArrayList;
//import java.util.List;
//
//@Component
//@Slf4j
//public class OpcCustomRunner implements ApplicationRunner {
//    @Autowired
//    private MiloService miloService;
//
//
//    @Autowired
//    private IDryOpcDeviceService dryOpcDeviceService;
//
//    @Autowired
//    private DrySocket drySocket;
//    @Override
//    public void run(ApplicationArguments args) throws Exception {
//
//        subscript();
//
//    }
//
//    private void subscript() throws Exception {
//        List<String> ids = new ArrayList<>();
//        List<DryOpcDevice> list = dryOpcDeviceService.list();
//        list.forEach(item -> {
//            ids.add(item.getIdentifier());
//        });
////        ids.add("通道 1.设备 1.标记 1");
////        ids.add("通道 1.设备 1.标记 2");
////        ids.add("channel1.device1.tag1");
////        ids.add("channel1.device1.tag2");
////        ids.add("channel1.device1.tag3");
////        ids.add("channel1.device1.tag4");
////        ids.add("channel1.device1.tag5");
////        ids.add("channel1.device1.tag6");
//        miloService.subscriptionFromOpcUa(ids, (id,value)->{
//            log.info("subscription ç‚¹ä½ï¼š{} è®¢é˜…到消息:{}", id, value);
//
//            DryOpcMsgVo dryOpcMsgVo = new DryOpcMsgVo(id, (Boolean) value);
//            drySocket.pushMessage("1003", JSON.toJSONString(dryOpcMsgVo));
//        } );
//    }
//}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/websocket/DrySocket1.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,223 @@
//package org.jeecg.modules.dry.websocket;
//
//import cn.hutool.core.bean.BeanUtil;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import lombok.extern.slf4j.Slf4j;
//import org.jeecg.common.constant.DrySocketConst;
//import org.jeecg.common.util.SpringContextUtils;
//import org.jeecg.modules.dry.service.IDryRealTimeDataService;
//import org.jeecg.modules.dry.vo.RealTimeDataVo;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import javax.websocket.*;
//import javax.websocket.server.PathParam;
//import javax.websocket.server.ServerEndpoint;
//import java.util.Collection;
//import java.util.HashMap;
//import java.util.Map;
//
//@Slf4j
//@Component
//@ServerEndpoint("/drySocket/{tenantId}/{machineId}")
//public class DrySocket {
//
//    /**
//     * å½“前 session
//     */
//    private Session session;
//    /**
//     * å½“前租户id
//     */
//    private String tenantId;
//    /**
//     * è®¾å¤‡id,用于标识同一租户,不同设备的数据
//     */
//    private String machineId;
//    /**
//     * å½“前socket唯一id
//     */
//    private String socketId;
//
//    /**
//     * ç§Ÿæˆ·è¿žæŽ¥æ± ï¼ŒåŒ…含单个租户的所有socket连接;
//     * å› ä¸ºä¸€ä¸ªç§Ÿæˆ·å¯èƒ½æ‰“开多个设备,多个设备就会有多个连接;
//     * key是tenantId,value是Map对象;子Map的key是machineId,value是drySocket对象
//     */
//    private  Map<String, Map<String, DrySocket>> tenantPool = new HashMap<>();
//    /**
//     * è¿žæŽ¥æ± ï¼ŒåŒ…含所有WebSocket连接;
//     * key是socketId,value是drySocket对象
//     */
//    private  Map<String, DrySocket> machinePool = new HashMap<>();
//
//    /**
//     * èŽ·å–æŸä¸ªç§Ÿæˆ·æ‰€æœ‰çš„è®¾å¤‡
//     */
//    public  Map<String, DrySocket> getTenantPool(String tenantId) {
//        return tenantPool.computeIfAbsent(tenantId, k -> new HashMap<>(5));
//    }
//
//    /**
//     * å‘当前租户发送消息
//     *
//     * @param message æ¶ˆæ¯å†…容
//     */
//    public void sendMessage(String message) {
//        try {
//            this.session.getAsyncRemote().sendText(message);
//        } catch (Exception e) {
//            log.error("【drySocket】消息发送失败:" + e.getMessage());
//        }
//    }
//
//    /**
//     * å°è£…消息json
//     *
//     * @param data æ¶ˆæ¯å†…容
//     */
//    public static String packageMessage(String type, Object data) {
//        JSONObject message = new JSONObject();
//        message.put(DrySocketConst.TYPE, type);
//        message.put(DrySocketConst.DATA, data);
//        return message.toJSONString();
//    }
//
//    /**
//     * å‘指定租户的所有设备发送消息
//     *
//     * @param tenantId  æŽ¥æ”¶æ¶ˆæ¯çš„租户ID
//     * @param message æ¶ˆæ¯å†…容
//     */
//    public  void sendMessageTo(String tenantId, String message) {
//        Collection<DrySocket> values = getTenantPool(tenantId).values();
//        if (values.size() > 0) {
//            for (DrySocket socketItem : values) {
//                socketItem.sendMessage(message);
//            }
//        } else {
//            log.warn("【drySocket】消息发送失败:tenantId\"" + tenantId + "\"不存在或未在线!");
//        }
//    }
//
//    /**
//     * å‘指定租户的指定设备发送消息
//     *
//     * @param tenantId  æŽ¥æ”¶æ¶ˆæ¯çš„租户ID
//     * @param message æ¶ˆæ¯å†…容
//     */
//    public  void sendMessageTo(String tenantId, String machineId, String message) {
//        DrySocket socketItem = getTenantPool(tenantId).get(machineId);
//        if (socketItem != null) {
//            socketItem.sendMessage(message);
//        } else {
//            log.warn("【drySocket】消息发送失败:tenantId\"" + tenantId + "\"的machineId\"" + machineId + "\"不存在或未在线!");
//        }
//    }
//
//    /**
//     * å‘多个租户的所有设备发送消息
//     *
//     * @param tenantIds æŽ¥æ”¶æ¶ˆæ¯çš„租户ID数组
//     * @param message æ¶ˆæ¯å†…容
//     */
//    public  void sendMessageTo(String[] tenantIds, String message) {
//        for (String tenantId : tenantIds) {
//            this.sendMessageTo(tenantId, message);
//        }
//    }
//
//    /**
//     * å‘所有租户的所有设备发送消息
//     *
//     * @param message æ¶ˆæ¯å†…容
//     */
//    public  void sendMessageToAll(String message) {
//        for (DrySocket socketItem : machinePool.values()) {
//            socketItem.sendMessage(message);
//        }
//    }
//
//    /**
//     * websocket å¼€å¯è¿žæŽ¥
//     */
//    @OnOpen
//    public void onOpen(Session session, @PathParam("tenantId") String tenantId, @PathParam("machineId") String machineId) {
//        try {
//            this.tenantId = tenantId;
//            this.machineId = machineId;
//            this.socketId = tenantId + machineId;
//            this.session = session;
//
//            machinePool.put(this.socketId, this);
//            getTenantPool(tenantId).put(this.machineId, this);
//
//            log.info("【drySocket】有新的连接,总数为:" + machinePool.size());
//            log.info("ssss"+tenantPool.size());
//        } catch (Exception ignored) {
//        }
//    }
//
//    /**
//     * websocket æ–­å¼€è¿žæŽ¥
//     */
//    @OnClose
//    public void onClose() {
//        try {
//            machinePool.remove(this.socketId);
//            getTenantPool(this.tenantId).remove(this.machineId);
//
//            log.info("【drySocket】连接断开,总数为:" + machinePool.size());
//        } catch (Exception ignored) {
//        }
//    }
//
//    /**
//     * websocket æ”¶åˆ°æ¶ˆæ¯
//     */
//    @OnMessage
//    public void onMessage(String message) {
//        log.info("【drySocket】onMessage:" + message);
//        IDryRealTimeDataService realTimeDataService = SpringContextUtils.getBean(IDryRealTimeDataService.class);
//        JSONObject json;
//        try {
//            json = JSON.parseObject(message);
//        } catch (Exception e) {
//            log.warn("【drySocket】收到不合法的消息:" + message);
//            return;
//        }
//        String type = json.getString(DrySocketConst.TYPE);
//        switch (type) {
//            // å¿ƒè·³æ£€æµ‹
//            case DrySocketConst.TYPE_HB:
//                this.sendMessage(DrySocket.packageMessage(type, true));
//                break;
//            // å®žæ—¶æ•°æ®å¤„理
//            case DrySocketConst.TYPE_RDT:
//                Object o = json.get(DrySocketConst.DATA);
//                RealTimeDataVo realTimeDataVo = BeanUtil.toBean(o, RealTimeDataVo.class);
//                realTimeDataService.realTimeDataHandle(realTimeDataVo);
//                break;
//
//            default:
//                log.warn("【drySocket】收到不识别的消息类型:" + type);
//                break;
//        }
//
//
//    }
//
//    /** * é…ç½®é”™è¯¯ä¿¡æ¯å¤„理 * @param session * @param t */
//    @OnError
//    public void onError(Session session, Throwable t) {
//
////什么都不想打印都去掉就好了
//        log.info("【websocket消息】出现未知错误 ");
////打印错误信息,如果你不想打印错误信息,去掉就好了
////这里打印的也是 java.io.EOFException: null
//        t.printStackTrace();
//    }
//
//
//}
jeecg-module-dry/jeecg-module-dry-start/src/main/test/java/com/lanbao/AiTest.java
@@ -1,27 +1,27 @@
package com.lanbao;
import ai.djl.modality.Classifications;
import org.jeecg.modules.dry.util.HerbUtil;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
public class AiTest {
    @Test
    public void test() {
        try {
            String img = "E:\\testImg\\szp1.jpg";
            HerbUtil herbUtil = new HerbUtil();
            File file = new File(img);
            InputStream is = new FileInputStream(file);
            List<Classifications.Classification> predict = herbUtil.predict(is);
            System.out.println(predict);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}
//package com.lanbao;
//
//import ai.djl.modality.Classifications;
//import org.jeecg.modules.dry.util.HerbUtil;
//import org.junit.Test;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.FileNotFoundException;
//import java.io.InputStream;
//import java.util.List;
//
//public class AiTest {
//    @Test
//    public void test() {
//        try {
//            String img = "E:\\testImg\\szp1.jpg";
//            HerbUtil herbUtil = new HerbUtil();
//            File file = new File(img);
//            InputStream is = new FileInputStream(file);
//            List<Classifications.Classification> predict = herbUtil.predict(is);
//            System.out.println(predict);
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        }
//    }
//}
jeecg-server-cloud/jeecg-cloud-gateway/src/main/resources/application.yml
@@ -27,8 +27,8 @@
            allowedOriginPatterns: "*"
            allowedMethods: "*"
            allowedHeaders: "*"
#    inetutils:
#      preferred-networks: 192.168
    inetutils:
      preferred-networks: 192.168
    #Sentinel配置
    sentinel:
      transport:
jeecg-server-cloud/jeecg-cloud-nacos/src/main/resources/application.yml
@@ -14,7 +14,7 @@
  password:
    '0': ${MYSQL-PWD:123456}
  url:
    '0': jdbc:mysql://${MYSQL-HOST:jeecg-boot-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:nacos}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
    '0': jdbc:mysql://${MYSQL-HOST:localhost}:${MYSQL-PORT:3306}/${MYSQL-DB:nacos-herb}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
  user:
    '0': ${MYSQL-USER:root}
management: