Browse Source

完善opc

hfxc226 2 years ago
parent
commit
9507f7d1f5

+ 1 - 2
platform-dao/src/main/resources/application-daoDev.yml

@@ -142,5 +142,4 @@ quartz:
 logging:
   level:
     com.platform.dao.mapper: DEBUG
-    org.activiti: ERROR
-    org.activiti.engine.impl.persistence.entity: DEBUG
+    org.activiti: DEBUG

+ 9 - 5
platform-dao/src/main/resources/application-daoProd.yml

@@ -3,7 +3,7 @@ spring:
     druid:
       master:
         driver-class-name: com.mysql.cj.jdbc.Driver
-        url: jdbc:mysql://192.168.16.222:3306/hitch-sb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&allowMultiQueries=true&removeAbandoned=true&removeAbandonedTimeout=60&logAbandoned=true
+        url: jdbc:mysql://192.168.16.222:3306/hitch-sb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&allowMultiQueries=true&removeAbandoned=true&removeAbandonedTimeout=60&logAbandoned=true
         username: root
         password: mydm888
         filters: wall,stat
@@ -32,8 +32,9 @@ spring:
         validation-query: SELECT 'x'
       slave:
         driver-class-name: com.mysql.cj.jdbc.Driver
-        url: jdbc:mysql://localhost:3306/hitch-sb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&allowMultiQueries=true
+        url: jdbc:mysql://localhost:3306/hitch-sb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&allowMultiQueries=true
         username: root
+        #password: mysql?123!@MYSQL
         password: mydm888
         filters: wall,stat
         filter:
@@ -88,6 +89,9 @@ spring:
         #间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
         time-between-eviction-runs-millis: 60000
         validation-query: SELECT 'x'
+        stat-view-servlet:
+          login-password: platform8888
+          login-username: root
       stat-view-servlet:
         login-password: platform8888
         login-username: root
@@ -97,6 +101,7 @@ spring:
         temp:
           use_jdbc_metadata_defaults: false
         dialect: org.hibernate.dialect.MySQLDialect
+
 # mybaits配置  tk
 mybatis:
   mapper-locations: classpath:mapper/**/*.xml
@@ -131,6 +136,5 @@ quartz:
 
 logging:
   level:
-    com.platform.dao.mapper: DEBUG
-    org.activiti: ERROR
-    org.activiti.engine.impl.persistence.entity: DEBUG
+    com.platform: INFO
+    org.activiti: INFO

+ 2 - 3
platform-dao/src/main/resources/application-daoTest.yml

@@ -136,6 +136,5 @@ quartz:
 
 logging:
   level:
-    com.platform.dao.mapper: DEBUG
-    org.activiti: ERROR
-    org.activiti.engine.impl.persistence.entity: DEBUG
+    com.platform: INFO
+    org.activiti: INFO

+ 2 - 1
platform-opc/src/main/java/com/platform/opc/OpcApplication.java

@@ -1,7 +1,6 @@
 package com.platform.opc;
 
 import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
-import com.platform.opc.util.OpcDAClient;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.SpringApplication;
@@ -11,6 +10,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import java.util.TimeZone;
 
 /**
+ *
+ * 不启动quartz :防止和设备定时任务冲突
  * @Description
  * @Author chenli
  * @Date 2019/7/22

+ 80 - 19
platform-opc/src/main/java/com/platform/opc/servie/OpcInitService.java

@@ -1,13 +1,17 @@
 package com.platform.opc.servie;
 
+import com.alibaba.fastjson.JSON;
 import com.platform.common.util.RedisUtils;
+import com.platform.common.util.StringUtils;
 import com.platform.dao.entity.remote.RemoteOpc;
 import com.platform.dao.enums.YesNoEnum;
 import com.platform.dao.mapper.remote.RemoteOpcMapper;
+import com.platform.opc.entity.OpcResult;
 import com.platform.opc.util.OpcDAClient;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.openscada.opc.lib.da.AddFailedException;
+import org.openscada.opc.lib.da.Group;
 import org.openscada.opc.lib.da.Item;
 import org.springframework.context.annotation.DependsOn;
 import org.springframework.scheduling.annotation.EnableScheduling;
@@ -18,9 +22,12 @@ import tk.mybatis.mapper.weekend.Weekend;
 import tk.mybatis.mapper.weekend.WeekendCriteria;
 
 import javax.annotation.PostConstruct;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @Service("opcInitService")
@@ -44,26 +51,79 @@ public class OpcInitService {
      */
     @PostConstruct
     public void initAddAllItem() {
+        RedisUtils.del(OpcDAClient.redis_ok);
         RedisUtils.del(OpcDAClient.redis_opc_item_values);
         log.info("开始初始化分组");
         addGroupAndItems(findAllItems(true, null));
+        log.info("开始执行分组任务-拉取数据");
+        startFetchDataByGroupLine();
     }
 
-    /**
-     * 1: 新增的数据添加到分组里面
-     * a: 之前已经新增,但是server里面没配置,现在server刚配置(修改createdFlag = 1)
-     * b: 新增的点位,在server里面也配置了,createdFlag = 1
-     * c: 新增的点位,设置了createdFlag = 1,但是加入到分组的时候,server里面就没配置,这个时候需要更新:createdFlag = 0
-     * d: 之前点位配置到线路1,但是现在修改到了线路2,需要重新添加到分组,要从原有分组进行删除,不然2个组都获取到了数据*
-     * <p>
-     * 注意:获取的时候写入一个key,用于标识正在读,这个时候,不进行点位新增* * *
-     */
-    /*@Scheduled(fixedDelay = 300000)  //间隔5分钟,300秒查询,需要同步新增的点位。
-    public void addItems() {
-        RedisUtils.setString(OpcDAClient.redis_opc_update_flag, "1");
-        addGroupAndItems(findAllItems(true, null));
-        RedisUtils.del(OpcDAClient.redis_opc_update_flag);
-    }*/
+    private void  startFetchDataByGroupLine() {
+        // 创建核心线程数量为分组数量的线程池
+        // 先判断是否分组完毕
+        String ok = RedisUtils.getString(OpcDAClient.redis_ok);
+        if(StringUtils.isNotBlank(ok)){
+            initAddAllItem();
+            return;
+        }
+        ScheduledExecutorService pool = Executors.newScheduledThreadPool(OpcDAClient.groupList.size());
+        for (int i = 0; i < OpcDAClient.groupList.size(); i++) {
+            Group group = OpcDAClient.groupList.get(i);
+            pool.scheduleAtFixedRate(new TimerTask() {
+                @Override
+                public void run() {
+                    try {
+                        log.info(Thread.currentThread().getName() + "-线程-" + group.getName() + new Date());
+                        saveValue(OpcDAClient.getItemValuesList(group));
+                    } catch (Exception e) {
+                        // 关闭线程池
+                        pool.shutdown();
+                        e.printStackTrace();
+                        log.error("批量获取数据异常:", e);
+                    }
+                }
+            }, 1, 2, TimeUnit.SECONDS);
+        }
+        /*// 任务1,延迟1秒执行,每5秒循环一次
+        pool.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                System.out.println(Thread.currentThread().getName() + "线程A" + new Date());
+            }
+        }, 1, 1, TimeUnit.SECONDS);
+
+        // 任务2,延迟3秒执行,每5秒循环一次
+        pool.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                System.out.println(Thread.currentThread().getName() + "线程B" + new Date());
+            }
+        }, 1, 1, TimeUnit.SECONDS);*/
+        // 关闭线程池
+
+    }
+
+    private void saveValue(List<OpcResult> resultList){
+        if (!CollectionUtils.isEmpty(resultList)) {
+            log.info("拉取数量:" + resultList.size());
+            RedisUtils.setString(OpcDAClient.redis_opc_item_values, JSON.toJSONString(resultList));
+            // 更新数据库实时数据
+            List<RemoteOpc> remoteOpcList = new ArrayList<>();
+            LocalDateTime localDateTime = LocalDateTime.now();
+            for (OpcResult result : resultList) {
+                RemoteOpc remoteOpc = new RemoteOpc();
+                remoteOpc.setResult(new BigDecimal(result.getValue()).setScale(2));
+                remoteOpc.setPositionNum(result.getId());
+                remoteOpc.setUpdateTime(localDateTime);
+                remoteOpcList.add(remoteOpc);
+            }
+            remoteOpcMapper.updateBatch(remoteOpcList);
+        } else {
+            log.info("初始化启动分组错误,等待下次重新启动分组");
+        }
+
+    }
 
     /**
      * 立即新增点位:在新增点位后,点击立即生效按钮,这个时间不能再执行上面的addItems()方法
@@ -137,6 +197,7 @@ public class OpcInitService {
         List<RemoteOpc> remoteOpcFailList = new ArrayList<>();
         AddFailedException exception = OpcDAClient.addGroupList(listMap);
         if (exception != null) {
+            RedisUtils.setString(OpcDAClient.redis_ok, "0");
             Map<String, Integer> failedItems = exception.getErrors();
             Map<String, Item> addItems = exception.getItems();
             if (failedItems != null) {// 有不存在的item,需要更新对应的点位信息
@@ -157,7 +218,7 @@ public class OpcInitService {
                     remoteOpc.setPositionNum(entry.getKey());
                     remoteOpc.setCreatedFlag(1);
                     remoteOpc.setRemark("opc server已配置,AV/DV配置正确");
-                    log.error("opc server已配置。key: " + remoteOpc.getPositionNum() + ", value: " + entry.getValue());
+                    // log.error("opc server已配置。key: " + remoteOpc.getPositionNum() + ", value: " + entry.getValue());
                     remoteOpcFailList.add(remoteOpc);
                 }
             }

+ 3 - 1
platform-opc/src/main/java/com/platform/opc/servie/OpcTaskService.java

@@ -41,6 +41,7 @@ public class OpcTaskService {
      */
     @Scheduled(fixedDelay = 2000)  //间隔2秒
     public void getValue() {
+        log.info("启动拉取");
         String key = RedisUtils.getString(OpcDAClient.redis_opc_update_flag);
         if(StringUtils.isBlank(key)){
             log.info("开始拉取数据");
@@ -53,7 +54,7 @@ public class OpcTaskService {
                 LocalDateTime localDateTime = LocalDateTime.now();
                 for (OpcResult result : resultList) {
                     RemoteOpc remoteOpc = new RemoteOpc();
-                    remoteOpc.setResult(new BigDecimal(result.getValue()));
+                    remoteOpc.setResult(new BigDecimal(result.getValue()).setScale(2));
                     remoteOpc.setPositionNum(result.getId());
                     remoteOpc.setUpdateTime(localDateTime);
                     remoteOpcList.add(remoteOpc);
@@ -75,6 +76,7 @@ public class OpcTaskService {
      */
     @Scheduled(fixedDelay = 300000)  //间隔300秒,5分钟保存一次数据到数据库,确保每天不超过700万数据
     public void saveValue() {
+        log.info("启动保存");
         String key = RedisUtils.getString(OpcDAClient.redis_opc_update_flag);
         if(StringUtils.isBlank(key)){
             log.info("开始保存点位");

+ 39 - 3
platform-opc/src/main/java/com/platform/opc/util/OpcDAClient.java

@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 @Slf4j
 public class OpcDAClient {
 
+    public static String redis_ok = "redis_ok";
     public static String redis_opc_item_values = "redis_opc_item_values";
     public static String redis_opc_update_flag = "redis_opc_update_flag";
     // 待采集点位列表
@@ -42,7 +43,7 @@ public class OpcDAClient {
     public static String progId = "Hollysys.HOLLiASiComm.1";
     public static String tag_prefix = "Channel1.Device1.";
     private static Server server;
-    private static List<Group> groupList = new ArrayList<>();
+    public static List<Group> groupList = new ArrayList<>();
     // private static Item[][] itemArrList = null;
     private static Map<String, List<Item>> itemArrList = new HashMap<>();
 
@@ -184,7 +185,9 @@ public class OpcDAClient {
             // 将不存在的点位信息保存到数据库,
             Map<String, Integer> errorsItemMap = e.getErrors();
             // e.printStackTrace();
-            log.error("添加点位出错,有不存在的地位,等待下次启动添加", e);
+            log.error("添加点位出错,有不存在的点位,等待下次启动添加", e);
+            groupList = new ArrayList<>();
+            itemArrList = new HashMap<>();
             return e;
         } catch (DuplicateGroupException e) {
             e.printStackTrace();
@@ -235,7 +238,7 @@ public class OpcDAClient {
                         log.info("取消前数量:" + items.size());
                         log.info("取消后数量:" + itemResults.size());
                         // 如果该分组下面没有点位了,则删除该分组
-                        if(CollectionUtils.isEmpty(itemResults) || itemResults.size()==0){
+                        if (CollectionUtils.isEmpty(itemResults) || itemResults.size() == 0) {
                             groupList.remove(group);
                             itemArrList.remove(entry.getKey() + "");
                         }
@@ -279,6 +282,39 @@ public class OpcDAClient {
                     }
                 }
             }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("批量获取数据异常:", e);
+            return null;
+        }
+        return resultList;
+    }
+
+    /**
+     * 获取单个组数据
+     * 根据车间id来获取
+     *
+     * @param group:
+     * @return
+     */
+    public static List<OpcResult> getItemValuesList(Group group) {
+        List<OpcResult> resultList = new ArrayList<>();
+        try {
+            log.info("获取分组的数据: 组名:" + group.getName());
+            Item[] items = itemArrList.get(group.getName()).toArray(new Item[0]);
+            log.info("获取分组的数据数量:" + items.length);
+            Map<Item, ItemState> resultMap = group.read(true, items);
+            //log.info("数据获取完成。数量:", resultMap.size() + ", 组序号:" + i);
+            for (Item item : resultMap.keySet()) {
+                OpcResult result = new OpcResult();
+                ItemState itemMap = resultMap.get(item);
+                String value = getVal(itemMap.getValue());
+                result.setId(item.getId());
+                result.setValue(value);
+                result.setTime(DateUtils.dateToString(itemMap.getTimestamp().getTime()));
+                // log.info("id: " + item.getId() + ", value: " + value + ", timestamp: " + itemMap.getTimestamp());
+                resultList.add(result);
+            }
         } catch (Exception e) {
             e.printStackTrace();
             log.error("批量获取数据异常:", e);

+ 1 - 1
platform-opc/src/main/resources/logback-spring.xml

@@ -91,7 +91,7 @@
     <!-- 开发环境 -->
     <springProfile name="dev">
         <logger name="com.platform" level="INFO"/>
-        <logger name="com.platform.dao.mapper.upms.SysLogMapper" level="ERROR"/>
+        <logger name="com.platform.dao.mapper.upms.SysLogMapper" level="INFO"/>
 
         <root level="INFO">
             <appender-ref ref="stdout"/>

+ 1 - 1
platform-rest/src/main/java/com/platform/rest/controller/remote/RemoteOpcController.java

@@ -99,7 +99,7 @@ public class RemoteOpcController {
     @PreAuthorize("@pms.hasPermission('remote-opcs-edit')")
     public R addGroup(@PathVariable("positionNum") String positionNum) {
         RedisUtils.setListOne(redis_opc_wait_add_list, positionNum);
-        return new R<>("已加入待撤销列表,10秒后自动采集");
+        return new R<>("已加入待采集列表,10秒后自动采集");
     }
 
     /**

+ 1 - 1
platform-service/src/main/java/com/platform/service/bean/ScheduleUtils.java

@@ -37,7 +37,7 @@ public class ScheduleUtils {
         try {
             return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
         } catch (SchedulerException e) {
-            throw new BusinessException("获取定时任务CronTrigger出现异常");
+            throw new BusinessException("获取定时任务CronTrigger出现异常, jobId:" + jobId);
         }
     }
 

+ 3 - 3
platform-service/src/main/java/com/platform/service/repair/impl/RepairApplicationFormServiceImpl.java

@@ -1441,7 +1441,7 @@ public class RepairApplicationFormServiceImpl extends BaseServiceImpl<RepairAppl
         }
 
         // 选择非计划性的订单
-        repairApplicationFormDTO.setCategory(RepairApplicationFormCategoryEnum.PLAN_NOT.getValue());
+        // repairApplicationFormDTO.setCategory(RepairApplicationFormCategoryEnum.PLAN_NOT.getValue());
         repairApplicationFormDTO.setSearchStartTime(searchStartTime);
         repairApplicationFormDTO.setSearchEndTime(searchEndTime);
         List<RepairApplicationFormVO> list = mapper.selectPageList(repairApplicationFormDTO);
@@ -1454,7 +1454,7 @@ public class RepairApplicationFormServiceImpl extends BaseServiceImpl<RepairAppl
             vo.setYear(map.get("searchStartTimeMonth").getYear());
             vo.setMonth(map.get("searchStartTimeMonth").getMonthValue());
             for (RepairApplicationFormVO repairApplicationForm : list) {
-                if (repairApplicationForm.getDealMinutes() == null) {
+                /*if (repairApplicationForm.getDealMinutes() == null) {
                     continue;
                 }
                 if (type == 1) {
@@ -1462,7 +1462,7 @@ public class RepairApplicationFormServiceImpl extends BaseServiceImpl<RepairAppl
                     if (minutes < 24.0) {
                         continue;
                     }
-                }
+                }*/
                 if (repairApplicationForm.getApplyTime().isAfter(map.get("searchStartTimeMonth")) && repairApplicationForm.getApplyTime().isBefore(map.get("searchEndTimeMonth"))) {
                     i++;
                     detailList.add(repairApplicationForm);