feat(data): 新增mqtt电表数据解析和写入,新增opcua电表和温湿度计数据解析和写入
已添加10个文件
已修改9个文件
1606 ■■■■■ 文件已修改
pom.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/MQTTGatewayApplication.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/config/opc/OpcConfig.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/controller/OpcController.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/handler/MqttMessageHandler.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/handler/OpcDataHandler.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/influxdb/InfluxdbRepository.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/model/entity/DeviceData.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/model/entity/OpcData.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/model/entity/PowerEntity.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/redis/RedisCache.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/service/IDataService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/service/IOpcService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/service/impl/DataServiceImpl.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/service/impl/OpcServiceImpl.java 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zhitan/util/PowerDataMapper.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -15,13 +15,14 @@
    </parent>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <integration.version>3.4.3</integration.version>
        <druid.version>1.2.20</druid.version>
        <mybatis-plus.version>3.5.6</mybatis-plus.version>
        <influxdb-client.version>6.6.0</influxdb-client.version>
        <milo.version>0.6.13</milo.version>
    </properties>
    <dependencies>
@@ -93,7 +94,37 @@
            <version>26.0.2</version>
            <scope>compile</scope>
        </dependency>
        <!-- Eclipse Milo OPC UA å®¢æˆ·ç«¯ -->
        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>sdk-client</artifactId>
            <version>${milo.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>stack-core</artifactId>
            <version>${milo.version}</version>
        </dependency>
    </dependencies>
    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <build.profile.id>dev</build.profile.id>
                <profileActive>dev</profileActive>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <build.profile.id>prod</build.profile.id>
                <profileActive>prod</profileActive>
            </properties>
        </profile>
    </profiles>
    <repositories>
        <repository>
@@ -136,6 +167,14 @@
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>9</source>
                    <target>9</target>
                </configuration>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>
src/main/java/com/zhitan/MQTTGatewayApplication.java
@@ -3,11 +3,13 @@
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
 * application
 */
@SpringBootApplication
@EnableScheduling
@MapperScan(basePackages = {"com.zhitan.mapper"})
public class MQTTGatewayApplication {
    public static void main(String[] args) {
src/main/java/com/zhitan/config/opc/OpcConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.zhitan.config.opc;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * OPC UA配置类
 */
@Data
@Component
@ConfigurationProperties(prefix = "opc")
public class OpcConfig {
    /**
     * OPC UA服务器地址
     */
    private String serverUrl;
    /**
     * ç”¨æˆ·å
     */
    private String username;
    /**
     * å¯†ç 
     */
    private String password;
    /**
     * æ˜¯å¦å¯ç”¨
     */
    private boolean enable;
    /**
     * é‡‡é›†é—´éš”(毫秒)
     */
    private long scanRate = 5000;
    /**
     * è¿žæŽ¥è¶…æ—¶æ—¶é—´(毫秒)
     */
    private int connectionTimeout = 10000;
    /**
     * èŠ‚ç‚¹åˆ—è¡¨ï¼Œæ ¼å¼ä¸ºï¼šåç§°=节点ID
     */
    private String[] nodes;
}
src/main/java/com/zhitan/controller/OpcController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.zhitan.controller;
import com.zhitan.model.entity.OpcData;
import com.zhitan.service.IOpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * OPC UA控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/opc")
public class OpcController {
    private final IOpcService opcService;
    @Autowired
    public OpcController(IOpcService opcService) {
        this.opcService = opcService;
    }
    /**
     * èŽ·å–OPC UA连接状态
     */
    @GetMapping("/status")
    public boolean getConnectionStatus() {
        return opcService.isConnected();
    }
    /**
     * æ‰‹åŠ¨è¿žæŽ¥OPC UA服务器
     */
    @PostMapping("/connect")
    public boolean connect() {
        return opcService.connect();
    }
    /**
     * æ–­å¼€OPC UA连接
     */
    @PostMapping("/disconnect")
    public void disconnect() {
        opcService.disconnect();
    }
    /**
     * å¯åŠ¨æ•°æ®é‡‡é›†
     */
    @PostMapping("/start")
    public void startCollection() {
        opcService.startDataCollection();
    }
    /**
     * åœæ­¢æ•°æ®é‡‡é›†
     */
    @PostMapping("/stop")
    public void stopCollection() {
        opcService.stopDataCollection();
    }
    /**
     * è¯»å–所有节点数据
     */
    @GetMapping("/data")
    public List<OpcData> readAllData() {
        return opcService.readAllNodes();
    }
}
src/main/java/com/zhitan/handler/MqttMessageHandler.java
@@ -1,13 +1,19 @@
package com.zhitan.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhitan.model.entity.DeviceData;
import com.zhitan.model.entity.ElectricPower;
import com.zhitan.model.entity.PowerEntity;
import com.zhitan.service.IDataService;
import com.zhitan.util.PowerDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import java.util.ArrayList;
import java.util.List;
/**
 * mqtt æ¶ˆæ¯å¤„理类
@@ -31,8 +37,13 @@
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // å°† JSON å­—符串转换为 SensorData å¯¹è±¡
            ElectricPower electricPower = objectMapper.readValue(payload, ElectricPower.class);
            dataService.writeTimeSeriesData(electricPower);
            //ElectricPower electricPower = objectMapper.readValue(payload, ElectricPower.class);
            DeviceData data = objectMapper.readValue(payload, DeviceData.class);
            List<PowerEntity> powerMeters = PowerDataMapper.mapToEntities(data);
            for (PowerEntity powerMeter : powerMeters) {
                dataService.writeTimeSeriesData(powerMeter);
            }
            // dataService.writeTimeSeriesData(electricPower)
        } catch (Exception e) {
            log.error(e.getMessage());
        }
src/main/java/com/zhitan/handler/OpcDataHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.zhitan.handler;
import com.zhitan.model.entity.OpcData;
import com.zhitan.service.IDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * OPC UA数据处理器
 */
@Slf4j
@Component
public class OpcDataHandler {
    private final IDataService dataService;
    public OpcDataHandler(IDataService dataService) {
        this.dataService = dataService;
    }
    /**
     * å¤„理OPC UA数据
     *
     * @param dataList OPC UA数据列表
     */
    public void handleOpcData(List<OpcData> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return;
        }
        for (OpcData data : dataList) {
            if (data.getValue() != null) {
                // æž„建JSON格式数据
                String jsonData = String.format("{\"%s\":%f}", data.getName(), data.getValue());
                // ä½¿ç”¨çŽ°æœ‰çš„æ•°æ®æœåŠ¡å†™å…¥æ—¶åºæ•°æ®
                dataService.writeTimeSeriesData(jsonData);
                log.debug("处理OPC UA数据: {} = {}", data.getName(), data.getValue());
            } else if (data.getErrorMessage() != null) {
                log.warn("OPC UA数据处理失败: {} - {}", data.getName(), data.getErrorMessage());
            }
        }
    }
}
src/main/java/com/zhitan/influxdb/InfluxdbRepository.java
@@ -5,6 +5,8 @@
import com.influxdb.client.InfluxDBClientFactory;
import com.influxdb.client.WriteApiBlocking;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import com.zhitan.config.influxdb.InfluxdbConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -73,4 +75,32 @@
        WriteApiBlocking writeApi = client.getWriteApiBlocking();
        writeApi.writePoints(points);
    }
    public double getLastPoint(String measurement, String tag, String s) {
        if (client == null || !config.isEnable()) {
            log.warn("InfluxDB client is not initialized or disabled.");
            return 0;
        }
        String query = String.format("from(bucket: \"%s\") " +
                "|> range(start: -1h) " +
                "|> filter(fn: (r) => r._measurement == \"%s\" and r._field == \"value\") " +
                "|> filter(fn: (r) => r.tag == \"%s\") " +
                "|> last()", config.getBucket(), measurement, s);
        List<FluxTable> tables = client.getQueryApi().query(query, config.getOrg());
        if (tables != null && !tables.isEmpty()) {
            List<FluxRecord> records = tables.get(0).getRecords();
            if (records != null && !records.isEmpty()) {
                FluxRecord record = records.get(0);
                double value = (double) record.getValue();
                return value;
            }
        }
        log.warn("No data found for measurement: {}, tag: {}, field: {}", measurement, tag, s);
        return 0;
    }
}
src/main/java/com/zhitan/model/entity/DeviceData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package com.zhitan.model.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
public class DeviceData {
    @JsonProperty("params")
    private Params params;
    @Data
    public static class Params {
        @JsonProperty("dir")
        private String dir;
        @JsonProperty("id")
        private String id;
        @JsonProperty("sys_sn")
        private String sysSn;
        @JsonProperty("sys_imei")
        private String sysImei;
        @JsonProperty("sys_time")
        private Long sysTime; // æ—¶é—´æˆ³ç”¨Long类型
        @JsonProperty("r_data")
        private List<RDataItem> rData;
    }
    @Data
    public static class RDataItem {
        @JsonProperty("name")
        private String name;
        @JsonProperty("value")
        private String value; // æ ¹æ®å®žé™…数据格式选择String/Double
        @JsonProperty("err")
        private String error;
    }
}
src/main/java/com/zhitan/model/entity/OpcData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.zhitan.model.entity;
import lombok.Data;
import java.time.Instant;
/**
 * OPC UA数据模型
 */
@Data
public class OpcData {
    /**
     * èŠ‚ç‚¹åç§°
     */
    private String name;
    /**
     * èŠ‚ç‚¹ID
     */
    private String nodeId;
    /**
     * æ•°æ®å€¼
     */
    private Double value;
    /**
     * æ•°æ®ç±»åž‹
     */
    private String dataType;
    /**
     * æ—¶é—´æˆ³
     */
    private Instant timestamp;
    /**
     * çŠ¶æ€ç 
     */
    private Integer statusCode;
    /**
     * é”™è¯¯ä¿¡æ¯
     */
    private String errorMessage;
}
src/main/java/com/zhitan/model/entity/PowerEntity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.zhitan.model.entity;
import lombok.Data;
@Data
public class PowerEntity {
    // sys_sn
    private String sn;
    //sys_imei
    private String imei;
    //sys_time
    private Long time;
    // Uab
    private Double uab;
    // Ubc
    private Double ubc;
    // Uca
    private Double uca;
    // Ua
    private Double ua;
    // Ub
    private Double ub;
    // Uc
    private Double uc;
    // Ia
    private Double ia;
    // Ib
    private Double ib;
    // Ic
    private Double ic;
    // é›¶åºç”µæµ Io
    private Double io;
    // æ€»åŠŸçŽ‡å› æ•° PF
    private Double pf;
    // æ€»æœ‰åŠŸåŠŸçŽ‡ psum
    private Double psum;
    // æ€»æœ‰åŠŸç”µèƒ½ eps
    private Double eps;
    // æ€»æ— åŠŸç”µèƒ½ eqs
    private Double eqs;
    // æ­£å‘总有功电能 epsp
    private Double epsp;
    // åå‘总有功电能 epsn
    private Double epsn;
    // æ­£å‘总无功电能 eqsp
    private Double eqsp;
    // åå‘总无功电能 eqsn
    private Double eqsn;
}
src/main/java/com/zhitan/redis/RedisCache.java
@@ -80,22 +80,29 @@
    }
    /**
     * ç¼“å­˜List数据
     *
     * @param key      ç¼“存的键值
     * @param dataList å¾…缓存的List数据
     * @return ç¼“存的对象
     */
    public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {
        ListOperations listOperation = redisTemplate.opsForList();
        if (null != dataList) {
            int size = dataList.size();
            for (int i = 0; i < size; i++) {
                listOperation.leftPush(key, dataList.get(i));
            }
 * ç¼“å­˜List数据,并设置过期时间
 *
 * @param key      ç¼“存的键值
 * @param dataList å¾…缓存的List数据
 * @param timeout  è¿‡æœŸæ—¶é—´
 * @param timeUnit æ—¶é—´å•位
 * @return ç¼“存的对象
 */
public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList, Integer timeout, TimeUnit timeUnit) {
    ListOperations listOperation = redisTemplate.opsForList();
    if (null != dataList) {
        int size = dataList.size();
        for (int i = 0; i < size; i++) {
            listOperation.leftPush(key, dataList.get(i));
        }
        return listOperation;
    }
    // è®¾ç½®è¿‡æœŸæ—¶é—´
    if (timeout > 0) {
        redisTemplate.expire(key, timeout, timeUnit);
    }
    return listOperation;
}
    /**
     * èŽ·å¾—ç¼“å­˜çš„list对象
src/main/java/com/zhitan/service/IDataService.java
@@ -1,6 +1,7 @@
package com.zhitan.service;
import com.zhitan.model.entity.ElectricPower;
import com.zhitan.model.entity.PowerEntity;
import org.jetbrains.annotations.NotNull;
/**
@@ -21,4 +22,11 @@
     * @param electricPower å›ºå®šæ ¼å¼çš„æ•°æ®
     */
    void writeTimeSeriesData(@NotNull ElectricPower electricPower);
    /**
     * å†™å…¥ç”µåŠ›ç›¸å…³æ•°æ®-固定格式,可自定义修改
     *
     * @param powerEntity å›ºå®šæ ¼å¼çš„æ•°æ®
     */
    void writeTimeSeriesData(@NotNull PowerEntity powerEntity);
}
src/main/java/com/zhitan/service/IOpcService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.zhitan.service;
import com.zhitan.model.entity.OpcData;
import java.util.List;
/**
 * OPC UA服务接口
 */
public interface IOpcService {
    /**
     * è¿žæŽ¥åˆ°OPC UA服务器
     *
     * @return æ˜¯å¦è¿žæŽ¥æˆåŠŸ
     */
    boolean connect();
    /**
     * æ–­å¼€ä¸ŽOPC UA服务器的连接
     */
    void disconnect();
    /**
     * è¯»å–单个节点的数据
     *
     * @param nodeId èŠ‚ç‚¹ID
     * @param name èŠ‚ç‚¹åç§°
     * @return OPC数据
     */
    OpcData readNode(String nodeId, String name);
    /**
     * è¯»å–所有配置的节点数据
     *
     * @return OPC数据列表
     */
    List<OpcData> readAllNodes();
    /**
     * å¯åŠ¨æ•°æ®é‡‡é›†
     */
    void startDataCollection();
    /**
     * åœæ­¢æ•°æ®é‡‡é›†
     */
    void stopDataCollection();
    /**
     * æ£€æŸ¥è¿žæŽ¥çŠ¶æ€
     *
     * @return æ˜¯å¦å·²è¿žæŽ¥
     */
    boolean isConnected();
}
src/main/java/com/zhitan/service/impl/DataServiceImpl.java
@@ -11,6 +11,7 @@
import com.zhitan.model.entity.ElectricPower;
import com.zhitan.influxdb.InfluxdbRepository;
import com.zhitan.mapper.CommonMapper;
import com.zhitan.model.entity.PowerEntity;
import com.zhitan.redis.RedisCache;
import com.zhitan.service.IDataService;
import lombok.extern.slf4j.Slf4j;
@@ -23,6 +24,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * æ•°æ®service
@@ -118,6 +120,61 @@
        repository.writePoints(points);
    }
    /**
     * å†™å…¥ç”µåŠ›ç›¸å…³æ•°æ®-固定格式,可自定义修改
     *
     * @param powerEntity å›ºå®šæ ¼å¼çš„æ•°æ®
     */
    @Override
    public void writeTimeSeriesData(@NotNull PowerEntity powerEntity) {
        List<IndexTemplate> templates = getIndexTemplate();
        // èŽ·å–ç±»ä¸­æ‰€æœ‰å£°æ˜Žçš„å­—æ®µ
        Field[] fields = powerEntity.getClass().getDeclaredFields();
        List<Point> points = new ArrayList<>();
        for (Field field : fields) {
            IndexTemplate indexTemplate = templates.stream().filter(template ->
                            field.getName().equalsIgnoreCase(template.getGatewayKey()))
                    .findFirst().orElse(null);
            if (indexTemplate != null) {
                Point point = Point
                        .measurement(influxdbConfig.getMeasurement())
                        .addTag(TAG, powerEntity.getSn() + "_" + indexTemplate.getCode())
                        .time(Instant.now(), WritePrecision.S);
                // è®¾ç½®å­—段可访问,允许访问私有字段
                field.setAccessible(true);
                if (Number.class.isAssignableFrom(field.getType()) || field.getType().isPrimitive()) {
                    try {
                        // èŽ·å–å­—æ®µå€¼
                        Object o = field.get(powerEntity);
                        if (o==null) {
                            // æŸ¥è¯¢å‡ºæœ€åŽä¸€æ¬¡å†™å…¥influxdb的数据
                            double lastValue = repository.getLastPoint(influxdbConfig.getMeasurement(),
                                    TAG, powerEntity.getSn() + "_" + indexTemplate.getCode());
                            if (lastValue>0) {
                                log.info("查询出最后一次写入influxdb的数据:{}", lastValue);
                            }
                            point.addField(FIELD_VALUE, lastValue);
                        } else {
                            // å®‰å…¨ç±»åž‹è½¬æ¢
                            if (o instanceof Number) {
                                double value = ((Number) o).doubleValue();
                                point.addField(FIELD_VALUE, value);
                                // ä½¿ç”¨ value...
                            } else {
                                log.error("字段 {} ç±»åž‹éžæ³•: {}", field.getName(), o.getClass());
                            }
                        }
                        points.add(point);
                    } catch (IllegalAccessException e) {
                        log.error("获取属性值失败:{}", e.getMessage());
                    }
                }
            }
        }
        repository.writePoints(points);
    }
    /**
     * èŽ·å–ç‚¹ä½æ¨¡æ¿
     */
@@ -126,7 +183,7 @@
        List<IndexTemplate> result = redisCache.getCacheList(TEMPLATE_KEY);
        if (result == null || result.isEmpty()) {
            result = commonMapper.getIndexTemplate();
            redisCache.setCacheList(TEMPLATE_KEY, result);
            redisCache.setCacheList(TEMPLATE_KEY, result, 120, TimeUnit.SECONDS);
        }
        return result;
    }
src/main/java/com/zhitan/service/impl/OpcServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,392 @@
package com.zhitan.service.impl;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.zhitan.config.influxdb.InfluxdbConfig;
import com.zhitan.config.opc.OpcConfig;
import com.zhitan.handler.OpcDataHandler;
import com.zhitan.influxdb.InfluxdbRepository;
import com.zhitan.model.entity.OpcData;
import com.zhitan.service.IOpcService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.UaException;
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.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.eclipse.milo.opcua.stack.core.types.structured.ReadResponse;
import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.text.ParseException;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
 * OPC UA服务实现类
 */
@Slf4j
@Service
public class OpcServiceImpl implements IOpcService {
    private final OpcConfig opcConfig;
    private final InfluxdbRepository influxdbRepository;
    private final InfluxdbConfig influxdbConfig;
    private final OpcDataHandler opcDataHandler;
    private OpcUaClient client;
    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    private final Map<String, String> nodeMap = new HashMap<>();
    private final String TAG = "tag";
    private final String FIELD_VALUE = "value";
    @Autowired
    public OpcServiceImpl(OpcConfig opcConfig, InfluxdbRepository influxdbRepository,
                         InfluxdbConfig influxdbConfig, OpcDataHandler opcDataHandler) {
        this.opcConfig = opcConfig;
        this.influxdbRepository = influxdbRepository;
        this.influxdbConfig = influxdbConfig;
        this.opcDataHandler = opcDataHandler;
        parseNodeConfig();
    }
    /**
     * è§£æžèŠ‚ç‚¹é…ç½®
     */
    private void parseNodeConfig() {
        if (opcConfig.getNodes() != null) {
            for (String nodeConfig : opcConfig.getNodes()) {
                String[] parts = nodeConfig.split("=", 2);
                if (parts.length == 2) {
                    String name = parts[0];
                    String nodeId = parts[1];
                    nodeMap.put(nodeId, name);
                    log.info("已配置OPC UA节点: {} -> {}", name, nodeId);
                }
            }
        }
    }
    /**
     * åº”用启动时自动连接并开始数据采集
     */
    @PostConstruct
    public void init() {
        if (opcConfig.isEnable()) {
            log.info("正在初始化OPC UA客户端...");
            if (connect()) {
                startDataCollection();
            }
        } else {
            log.info("OPC UA客户端已禁用");
        }
    }
    /**
     * åº”用关闭时断开连接
     */
    @PreDestroy
    public void destroy() {
        stopDataCollection();
        disconnect();
    }
    @Override
    public boolean connect() {
        if (client != null && isConnected()) {
            log.info("OPC UA客户端已连接");
            return true;
        }
        try {
            log.info("正在连接OPC UA服务器: {}", opcConfig.getServerUrl());
            // å‘现端点
            List<EndpointDescription> endpoints = DiscoveryClient.getEndpoints(opcConfig.getServerUrl()).get();
            EndpointDescription endpoint = endpoints.stream()
                    .findFirst()
                    .orElseThrow(() -> new Exception("未找到可用的OPC UA端点"));
            // é…ç½®å®¢æˆ·ç«¯
            OpcUaClientConfigBuilder configBuilder = OpcUaClientConfig.builder()
                    .setEndpoint(endpoint)
                    .setRequestTimeout(UInteger.valueOf(opcConfig.getConnectionTimeout()));
            // è®¾ç½®è®¤è¯æ–¹å¼
            if (opcConfig.getUsername() != null && !opcConfig.getUsername().isEmpty()) {
                configBuilder.setIdentityProvider(new UsernameProvider(
                        opcConfig.getUsername(),
                        opcConfig.getPassword()
                ));
            } else {
                configBuilder.setIdentityProvider(new AnonymousProvider());
            }
            // åˆ›å»ºå®¢æˆ·ç«¯å¹¶è¿žæŽ¥
            client = OpcUaClient.create(configBuilder.build());
            client.connect().get();
            List<String> namespaceUris = Arrays.asList(client.getNamespaceTable().toArray());
            for (int i = 0; i < namespaceUris.size(); i++) {
                System.out.println("Namespace Index: " + i + ", URI: " + namespaceUris.get(i));
            }
            log.info("OPC UA客户端连接成功");
            return true;
        } catch (Exception e) {
            log.error("OPC UA客户端连接失败: {}", e.getMessage(), e);
            return false;
        }
    }
    @Override
    public void disconnect() {
        if (client != null) {
            try {
                client.disconnect().get();
                log.info("OPC UA客户端已断开连接");
            } catch (Exception e) {
                log.error("OPC UA客户端断开连接失败: {}", e.getMessage(), e);
            } finally {
                client = null;
            }
        }
    }
    @Override
    public OpcData readNode(String nodeId, String name) {
        log.info("正在读取节点: {},名称: {}", nodeId, name);
        OpcData data = new OpcData();
        data.setNodeId(nodeId);
        data.setName(name);
        data.setTimestamp(Instant.now());
        if (client == null || !isConnected()) {
            data.setErrorMessage("OPC UA客户端未连接");
            return data;
        }
        try {
            // åˆ›å»ºè¯»å–请求
            ReadValueId readValueId = new ReadValueId(
                    NodeId.parse(nodeId),
                    AttributeId.Value.uid(),
                    null,
                    QualifiedName.NULL_VALUE
            );
            // æ‰§è¡Œè¯»å–
            ReadResponse response = client.read(
                    0.0,
                    TimestampsToReturn.Both,
                    List.of(readValueId)
            ).get();
            // å¤„理结果
            DataValue[] results = response.getResults();
            if (results == null || results.length == 0) {
                data.setStatusCode(-1);
                data.setErrorMessage("读取失败: å“åº”中无结果数据");
                return data;
            }
            DataValue value = results[0];
            data.setStatusCode((int) value.getStatusCode().getValue());
            if (value.getStatusCode().isGood()) {
                Variant variant = value.getValue();
                if (variant != null && variant.getValue() != null) {
                    Object rawValue = variant.getValue();
                    data.setDataType(rawValue.getClass().getSimpleName());
                    // è½¬æ¢ä¸ºDouble
                    if (rawValue instanceof Number) {
                        data.setValue(((Number) rawValue).doubleValue());
                    } else if (rawValue instanceof Boolean) {
                        data.setValue((Boolean) rawValue ? 1.0 : 0.0);
                    } else {
                        data.setValue(null);
                        data.setErrorMessage("不支持的数据类型: " + rawValue.getClass().getName());
                    }
                }
            } else {
                data.setErrorMessage("读取失败: " + value.getStatusCode().toString());
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // æ¢å¤ä¸­æ–­çŠ¶æ€
            data.setErrorMessage("读取异常: " + e.getMessage());
            log.error("读取OPC UA节点 {} è¢«ä¸­æ–­: {}", nodeId, e.getMessage(), e);
        } catch (ExecutionException e) {
            data.setErrorMessage("读取异常: " + e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
            log.error("读取OPC UA节点 {} å¤±è´¥: {}", nodeId, e.getMessage(), e);
        } catch (Exception e) {
            data.setErrorMessage("未知异常: " + e.getMessage());
            log.error("读取OPC UA节点 {} å‘生未知异常", nodeId, e);
        }
        return data;
    }
    @Override
    public List<OpcData> readAllNodes() {
        List<OpcData> results = new ArrayList<>();
        log.info("开始读取所有节点时间: {}", Instant.now());
        if (nodeMap.isEmpty()) {
            log.warn("没有配置OPC UA节点");
            return results;
        }
        try {
            // æž„建批量读取请求
            List<ReadValueId> readValueIds = new ArrayList<>();
            Map<Integer, Map.Entry<String, String>> indexMap = new HashMap<>();
            int index = 0;
            for (Map.Entry<String, String> entry : nodeMap.entrySet()) {
                ReadValueId readValueId = new ReadValueId(
                    NodeId.parse(entry.getKey()),
                    AttributeId.Value.uid(),
                    null,
                    QualifiedName.NULL_VALUE
                );
                readValueIds.add(readValueId);
                indexMap.put(index++, entry);
            }
            // æ‰§è¡Œæ‰¹é‡è¯»å–
            ReadResponse response = client.read(0.0, TimestampsToReturn.Both, readValueIds).get();
            DataValue[] dataValues = response.getResults();
            if (dataValues == null || dataValues.length != readValueIds.size()) {
                log.error("批量读取失败: è¿”回结果数量不匹配");
                return results;
            }
            // å¤„理响应数据
            for (int i = 0; i < dataValues.length; i++) {
                Map.Entry<String, String> entry = indexMap.get(i);
                String nodeId = entry.getKey();
                String name = entry.getValue();
                DataValue value = dataValues[i];
                OpcData data = new OpcData();
                data.setNodeId(nodeId);
                data.setName(name);
                data.setTimestamp(Instant.now());
                if (value.getStatusCode().isGood() && value.getValue() != null) {
                    Variant variant = value.getValue();
                    Object rawValue = variant.getValue();
                    data.setDataType(rawValue.getClass().getSimpleName());
                    data.setStatusCode((int) value.getStatusCode().getValue());
                    if (rawValue instanceof Number) {
                        data.setValue(((Number) rawValue).doubleValue());
                    } else if (rawValue instanceof Boolean) {
                        data.setValue((Boolean) rawValue ? 1.0 : 0.0);
                    } else {
                        data.setValue(null);
                        data.setErrorMessage("不支持的数据类型: " + rawValue.getClass().getName());
                    }
                } else {
                    data.setStatusCode((int) value.getStatusCode().getValue());
                    data.setErrorMessage("读取失败: " + value.getStatusCode().toString());
                }
                results.add(data);
            }
        } catch (Exception e) {
            log.error("批量读取OPC UA节点失败", e);
        }
        log.info("读取所有节点完成, å…±è®¡ {} ä¸ªèŠ‚ç‚¹, æ—¶é—´: {}", results.size(), Instant.now());
        return results;
    }
    @Override
    public void startDataCollection() {
        if (isRunning.compareAndSet(false, true)) {
            log.info("OPC UA数据采集已启动");
        }
    }
    @Override
    public void stopDataCollection() {
        if (isRunning.compareAndSet(true, false)) {
            log.info("OPC UA数据采集已停止");
        }
    }
    @Override
    public boolean isConnected() {
        if (client == null) {
            return false;
        }
        try {
            return client.getSession().get() != null;
        } catch (Exception e) {
            log.warn("获取OPC UA会话失败: {}", e.getMessage());
            return false;
        }
    }
    /**
     * å®šæ—¶é‡‡é›†æ•°æ®å¹¶å†™å…¥InfluxDB
     */
    @Scheduled(fixedDelayString = "${opc.scan-rate}")
    public void collectAndStoreData() {
        if (!opcConfig.isEnable() || !isRunning.get()) {
            return;
        }
        if (!isConnected() && !connect()) {
            log.warn("OPC UA客户端未连接,无法采集数据");
            return;
        }
        try {
            List<OpcData> dataList = readAllNodes();
            List<Point> points = new ArrayList<>();
            // ä½¿ç”¨ä¸¤ç§æ–¹å¼å­˜å‚¨æ•°æ®
            // 1. ç›´æŽ¥é€šè¿‡InfluxDB存储库写入
            for (OpcData data : dataList) {
                if (data.getValue() != null) {
                    Point point = Point
                            .measurement(influxdbConfig.getMeasurement())
                            .addTag(TAG, data.getName())
                            .addField(FIELD_VALUE, data.getValue())
                            .time(data.getTimestamp(), WritePrecision.NS);
                    points.add(point);
                    log.debug("采集OPC UA数据: {} = {}", data.getName(), data.getValue());
                } else if (data.getErrorMessage() != null) {
                    log.warn("采集OPC UA数据失败: {} - {}", data.getName(), data.getErrorMessage());
                }
            }
            if (!points.isEmpty()) {
                influxdbRepository.writePoints(points);
                log.info("成功写入 {} æ¡OPC UA数据到InfluxDB", points.size());
            }
            // 2. é€šè¿‡æ•°æ®å¤„理器使用现有的数据服务接口写入
            opcDataHandler.handleOpcData(dataList);
        } catch (Exception e) {
            log.error("OPC UA数据采集异常: {}", e.getMessage(), e);
        }
    }
}
src/main/java/com/zhitan/util/PowerDataMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
package com.zhitan.util;
import com.zhitan.model.entity.DeviceData;
import com.zhitan.model.entity.PowerEntity;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PowerDataMapper {
    public static List<PowerEntity> mapToEntities(DeviceData deviceData) {
        List<PowerEntity> meters = IntStream.rangeClosed(1, 8)
                .mapToObj(i -> createBaseEntity(deviceData, i))
                .collect(Collectors.toList());
        for (DeviceData.RDataItem item : deviceData.getParams().getRData()) {
            // ç¤ºä¾‹ï¼šå°† "Ia1" æ‹†åˆ†ä¸º "Ia" å’Œ "1"
            String[] parts = item.getName().split("(?<=\\D)(?=\\d)");
            if (parts.length != 2) continue;
            String fieldCode = parts[0]; // å¦‚ "Ia"
            int meterIndex = Integer.parseInt(parts[1]) - 1; // è½¬æ•°ç»„下标
            if (meterIndex >= 0 && meterIndex < 8) {
                setMeterField(meters.get(meterIndex), fieldCode, item.getValue());
            }
            // Uab1 Ubc1 Uca1是8个电表共用的字段,如果item.getName是Uab1 Ubc1 Uca1则遍历所有电表并赋值
            if ("Uab Ubc Uca Ua Ub Uc".contains(fieldCode)) {
                for (int i = 0; i < 8; i++) {
                    setMeterField(meters.get(i), fieldCode, item.getValue());
                }
            }
        }
        return meters;
    }
    private static PowerEntity createBaseEntity(DeviceData data, int meterNumber) {
        PowerEntity entity = new PowerEntity();
        entity.setSn(data.getParams().getSysSn() + "_" + meterNumber);
        entity.setImei(data.getParams().getSysImei());
        entity.setTime(data.getParams().getSysTime());
        return entity;
    }
    private static void setMeterField(PowerEntity entity, String fieldCode, String value) {
        try {
            switch (fieldCode.toUpperCase()) {
                case "UAB":
                    entity.setUab(parseDouble(value));
                    break;
                case "UBC":
                    entity.setUbc(parseDouble(value));
                    break;
                case "UCA":
                    entity.setUca(parseDouble(value));
                    break;
                case "UA":
                    entity.setUa(parseDouble(value));
                    break;
                case "UB":
                    entity.setUb(parseDouble(value));
                    break;
                case "UC":
                    entity.setUc(parseDouble(value));
                    break;
                case "IA":
                    entity.setIa(parseDouble(value));
                    break;
                case "IB":
                    entity.setIb(parseDouble(value));
                    break;
                case "IC":
                    entity.setIc(parseDouble(value));
                    break;
                case "IO":
                    entity.setIo(parseDouble(value));
                    break;
                case "PF":
                    entity.setPf(parseDouble(value));
                    break;
                case "PSUM":
                    entity.setPsum(parseDouble(value));
                    break;
                case "EPS":
                    entity.setEps(parseDouble(value));
                    break;
                case "EQS":
                    entity.setEqs(parseDouble(value));
                    break;
                case "EPSP":
                    entity.setEpsp(parseDouble(value));
                    break;
                case "EPSN":
                    entity.setEpsn(parseDouble(value));
                    break;
                case "EQSP":
                    entity.setEqsp(parseDouble(value));
                    break;
                case "EQSN":
                    entity.setEqsn(parseDouble(value));
                    break;
            }
        } catch (NumberFormatException e) {
            // å¤„理数值转换异常
        }
    }
    private static Double parseDouble(String s) {
        return s != null ? Double.parseDouble(s) : null;
    }
}
src/main/resources/application-dev.yml
@@ -4,9 +4,9 @@
    driverClassName: org.postgresql.Driver
    druid:
      master:
        url: jdbc:postgresql://localhost:5432/energy
        url: jdbc:postgresql://192.168.0.24:5432/postgres
        username: postgres
        password: postgres
        password: 123456
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
@@ -52,13 +52,13 @@
            multi-statement-allow: true
  mqtt:
    # è‡ªå®šä¹‰
    client-id: 202503181042
    client-id: 2025031810421
    # å…¬å…±MQTT服务器,生产环境需要替换为自己的
    broker-url: tcp://broker.emqx.io
    username:
    password:
    broker-url: tcp://lanpucloud.cn:1883
    username: youren
    password: 123456
    #默认订阅的主题
    default-topic: zhitan
    default-topic: lanbao/nygl/device/up
    timeout: 30
    keep-alive: 60
  redis:
@@ -67,12 +67,232 @@
    port: 6379
    password:
influxdb:
  host: "http://localhost:8086"
  host: "http://192.168.0.24:8086"
  #修改为自己的时序库访问org
  org: "org"
  org: "lanbao"
  #修改为自己的时序库bucket
  bucket: "bucket"
  bucket: "nygl"
  #修改为自己的时序库访问token
  token: "token"
  token: "i8WwVZz3RvkEVF3qGaY8uIDXTFEe2PzjgrKebDzcxlYGKnR-kOK5Hf1S5G4z3p-lc9UO7MQS4qKGL4lIeHSw1A=="
  measurement: data
  enable: true
  enable: true
# OPC UA配置
opc:
  # OPC UA服务器地址
  server-url: "opc.tcp://192.168.254.195:49320"
  # ç”¨æˆ·å
  username: ""
  # å¯†ç 
  password: ""
  # æ˜¯å¦å¯ç”¨
  enable: true
  # é‡‡é›†é—´éš”(毫秒)
  scan-rate: 30000
  # è¿žæŽ¥è¶…æ—¶æ—¶é—´(毫秒)
  connection-timeout: 10000
  # èŠ‚ç‚¹åˆ—è¡¨ï¼Œæ ¼å¼ä¸ºï¼šåç§°=节点ID
  nodes:
    # ç»„调线 LeftWorkshop
    - "1-1#yijidiankonggui_1_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_1_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_1_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_1_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag7"
    - "1-1#yijidiankonggui_1_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag8"
    - "1-1#yijidiankonggui_1_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag9"
    - "1-1#yijidiankonggui_1_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag10"
    - "1-1#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag13"
    - "1-1#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag16"
    - "1-1#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag14"
    - "1-1#yijidiankonggui_1_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag15"
    - "1-1#yijidiankonggui_1_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag17"
    # å°ç½é—´ CanSeamerRoom
    - "1-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag21"
    - "1-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag22"
    - "1-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag23"
    - "1-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag24"
    - "1-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag27"
    - "1-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag30"
    - "1-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag28"
    - "1-1#yijidiankonggui_2_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag29"
    - "1-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag31"
    # æˆå“åº“ FinishedStore
    - "1-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag35"
    - "1-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag36"
    - "1-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag37"
    - "1-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag38"
    - "1-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag41"
    - "1-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag44"
    - "1-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag42"
    - "1-1#yijidiankonggui_3_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag43"
    - "1-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag45"
    # æ¸…æ´—é—´ RightWorkshop
    - "1-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag49"
    - "1-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag50"
    - "1-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag51"
    - "1-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag52"
    - "1-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag55"
    - "1-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag58"
    - "1-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag56"
    - "1-1#yijidiankonggui_4_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag57"
    - "1-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag59"
    #维修室动力 MaintenanceRoom
    - "1-2#yijidiankonggui_1_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_1_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_1_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_1_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag7"
    - "1-2#yijidiankonggui_1_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag8"
    - "1-2#yijidiankonggui_1_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag9"
    - "1-2#yijidiankonggui_1_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag10"
    - "1-2#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag13"
    - "1-2#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag16"
    - "1-2#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag14"
    - "1-2#yijidiankonggui_1_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag15"
    - "1-2#yijidiankonggui_1_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag17"
    # åŽŸææ–™ä»“åº“ RawMaterialWarehouse
    - "1-2#yijidiankonggui_2_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_2_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_2_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_2_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag21"
    - "1-2#yijidiankonggui_2_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag22"
    - "1-2#yijidiankonggui_2_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag23"
    - "1-2#yijidiankonggui_2_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag24"
    - "1-2#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag27"
    - "1-2#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag30"
    - "1-2#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag28"
    - "1-2#yijidiankonggui_2_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag29"
    - "1-2#yijidiankonggui_2_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag31"
    # æ’温室 ThermostaticChamber
    - "1-2#yijidiankonggui_3_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_3_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_3_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_3_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag35"
    - "1-2#yijidiankonggui_3_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag36"
    - "1-2#yijidiankonggui_3_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag37"
    - "1-2#yijidiankonggui_3_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag38"
    - "1-2#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag41"
    - "1-2#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag44"
    - "1-2#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag42"
    - "1-2#yijidiankonggui_3_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag43"
    - "1-2#yijidiankonggui_3_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag45"
    # åŒ…胶间 PackGlueRoom
    - "1-2#yijidiankonggui_4_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_4_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_4_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_4_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag49"
    - "1-2#yijidiankonggui_4_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag50"
    - "1-2#yijidiankonggui_4_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag51"
    - "1-2#yijidiankonggui_4_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag52"
    - "1-2#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag55"
    - "1-2#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag58"
    - "1-2#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag56"
    - "1-2#yijidiankonggui_4_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag57"
    - "1-2#yijidiankonggui_4_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag59"
    # å·¦è½¦é—´ç©ºè°ƒ leftWkshopVRVS
    - "2-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag21"
    - "2-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag22"
    - "2-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag23"
    - "2-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag24"
    - "2-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag27"
    - "2-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag30"
    - "2-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag28"
    - "2-1#yijidiankonggui_2_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag29"
    - "2-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag31"
    # è½¦é—´åŠžå…¬å®¤ WorkshopOffice
    - "2-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag35"
    - "2-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag36"
    - "2-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag37"
    - "2-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag38"
    - "2-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag41"
    - "2-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag44"
    - "2-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag42"
    - "2-1#yijidiankonggui_3_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag43"
    - "2-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag45"
    # 1、2楼东办公室 EastOffice
    - "2-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag49"
    - "2-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag50"
    - "2-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag51"
    - "2-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag52"
    - "2-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag55"
    - "2-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag58"
    - "2-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag56"
    - "2-1#yijidiankonggui_4_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag57"
    - "2-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag59"
    #照明 Lighting
    - "3-1#yijidiankonggui_1_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_1_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_1_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_1_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag7"
    - "3-1#yijidiankonggui_1_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag8"
    - "3-1#yijidiankonggui_1_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag9"
    - "3-1#yijidiankonggui_1_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag10"
    - "3-1#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag13"
    - "3-1#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag16"
    - "3-1#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag14"
    - "3-1#yijidiankonggui_1_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag15"
    - "3-1#yijidiankonggui_1_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag17"
    # è½¦é—´2楼 SecondFloorWorkshop
    - "3-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag21"
    - "3-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag22"
    - "3-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag23"
    - "3-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag24"
    - "3-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag27"
    - "3-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag30"
    - "3-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag28"
    - "3-1#yijidiankonggui_2_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag29"
    - "3-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag31"
    # ç”Ÿäº§åŠžå…¬å®¤ ProductionOffice
    - "3-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag35"
    - "3-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag36"
    - "3-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag37"
    - "3-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag38"
    - "3-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag41"
    - "3-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag44"
    - "3-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag42"
    - "3-1#yijidiankonggui_3_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag43"
    - "3-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag45"
    # é«˜ä½Žæ¸©è¯•验区 HLTempTest
    - "3-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag49"
    - "3-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag50"
    - "3-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag51"
    - "3-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag52"
    - "3-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag55"
    - "3-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag58"
    - "3-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag56"
    - "3-1#yijidiankonggui_4_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag57"
    - "3-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag59"
    # æˆå“ä»“库温湿度 chengpincangku
    - "chengpincangku_WD=ns=2;s=_AdvancedTags.cpk_wd"
    - "chengpincangku_SD=ns=2;s=_AdvancedTags.cpk_sd"
    # ç”Ÿäº§è½¦é—´ shengchanchejian
    - "shengchanchejian_WD=ns=2;s=_AdvancedTags.sccj_wd"
    - "shengchanchejian_SD=ns=2;s=_AdvancedTags.sccj_sd"
    # åŽŸæ–™ä»“åº“ yuliaocangku
    - "yuliaocangku_WD=ns=2;s=_AdvancedTags.ylk_wd"
    - "yuliaocangku_SD=ns=2;s=_AdvancedTags.ylk_sd"
src/main/resources/application-prod.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,298 @@
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: org.postgresql.Driver
    druid:
      master:
        url: jdbc:postgresql://192.168.0.24:5432/postgres
        username: postgres
        password: 123456
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: admin
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  mqtt:
    # è‡ªå®šä¹‰
    client-id: 202503181042
    # å…¬å…±MQTT服务器,生产环境需要替换为自己的
    broker-url: tcp://lanpucloud.cn:1883
    username: youren
    password: 123456
    #默认订阅的主题
    default-topic: lanbao/nygl/device/up
    timeout: 30
    keep-alive: 60
  redis:
    database: 0
    host: localhost
    port: 6379
    password:
influxdb:
  host: "http://192.168.0.24:8086"
  #修改为自己的时序库访问org
  org: "lanbao"
  #修改为自己的时序库bucket
  bucket: "nygl"
  #修改为自己的时序库访问token
  token: "i8WwVZz3RvkEVF3qGaY8uIDXTFEe2PzjgrKebDzcxlYGKnR-kOK5Hf1S5G4z3p-lc9UO7MQS4qKGL4lIeHSw1A=="
  measurement: data
  enable: true
# OPC UA配置
opc:
  # OPC UA服务器地址
  server-url: "opc.tcp://192.168.254.195:49320"
  # ç”¨æˆ·å
  username: ""
  # å¯†ç 
  password: ""
  # æ˜¯å¦å¯ç”¨
  enable: true
  # é‡‡é›†é—´éš”(毫秒)
  scan-rate: 30000
  # è¿žæŽ¥è¶…æ—¶æ—¶é—´(毫秒)
  connection-timeout: 10000
  # èŠ‚ç‚¹åˆ—è¡¨ï¼Œæ ¼å¼ä¸ºï¼šåç§°=节点ID
  nodes:
    # ç»„调线 LeftWorkshop
    - "1-1#yijidiankonggui_1_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_1_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_1_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_1_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag7"
    - "1-1#yijidiankonggui_1_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag8"
    - "1-1#yijidiankonggui_1_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag9"
    - "1-1#yijidiankonggui_1_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag10"
    - "1-1#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag13"
    - "1-1#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag16"
    - "1-1#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag14"
    - "1-1#yijidiankonggui_1_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag15"
    - "1-1#yijidiankonggui_1_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag17"
    # å°ç½é—´ CanSeamerRoom
    - "1-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag21"
    - "1-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag22"
    - "1-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag23"
    - "1-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag24"
    - "1-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag27"
    - "1-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag30"
    - "1-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag28"
    - "1-1#yijidiankonggui_2_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag29"
    - "1-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag31"
    # æˆå“åº“ FinishedStore
    - "1-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag35"
    - "1-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag36"
    - "1-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag37"
    - "1-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag38"
    - "1-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag41"
    - "1-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag44"
    - "1-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag42"
    - "1-1#yijidiankonggui_3_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag43"
    - "1-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag45"
    # æ¸…æ´—é—´ RightWorkshop
    - "1-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.1-1#yijidiankonggui.tag1"
    - "1-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.1-1#yijidiankonggui.tag2"
    - "1-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.1-1#yijidiankonggui.tag3"
    - "1-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.1-1#yijidiankonggui.tag49"
    - "1-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.1-1#yijidiankonggui.tag50"
    - "1-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.1-1#yijidiankonggui.tag51"
    - "1-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.1-1#yijidiankonggui.tag52"
    - "1-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.1-1#yijidiankonggui.tag55"
    - "1-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.1-1#yijidiankonggui.tag58"
    - "1-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.1-1#yijidiankonggui.tag56"
    - "1-1#yijidiankonggui_4_Exp=ns=2;s=modbus.1-1#yijidiankonggui.tag57"
    - "1-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.1-1#yijidiankonggui.tag59"
    #维修室动力 MaintenanceRoom
    - "1-2#yijidiankonggui_1_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_1_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_1_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_1_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag7"
    - "1-2#yijidiankonggui_1_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag8"
    - "1-2#yijidiankonggui_1_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag9"
    - "1-2#yijidiankonggui_1_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag10"
    - "1-2#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag13"
    - "1-2#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag16"
    - "1-2#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag14"
    - "1-2#yijidiankonggui_1_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag15"
    - "1-2#yijidiankonggui_1_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag17"
    # åŽŸææ–™ä»“åº“ RawMaterialWarehouse
    - "1-2#yijidiankonggui_2_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_2_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_2_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_2_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag21"
    - "1-2#yijidiankonggui_2_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag22"
    - "1-2#yijidiankonggui_2_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag23"
    - "1-2#yijidiankonggui_2_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag24"
    - "1-2#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag27"
    - "1-2#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag30"
    - "1-2#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag28"
    - "1-2#yijidiankonggui_2_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag29"
    - "1-2#yijidiankonggui_2_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag31"
    # æ’温室 ThermostaticChamber
    - "1-2#yijidiankonggui_3_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_3_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_3_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_3_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag35"
    - "1-2#yijidiankonggui_3_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag36"
    - "1-2#yijidiankonggui_3_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag37"
    - "1-2#yijidiankonggui_3_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag38"
    - "1-2#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag41"
    - "1-2#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag44"
    - "1-2#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag42"
    - "1-2#yijidiankonggui_3_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag43"
    - "1-2#yijidiankonggui_3_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag45"
    # åŒ…胶间 PackGlueRoom
    - "1-2#yijidiankonggui_4_VoltageA=ns=2;s=modbus.1-2#yijidiankonggui.tag1"
    - "1-2#yijidiankonggui_4_VoltageB=ns=2;s=modbus.1-2#yijidiankonggui.tag2"
    - "1-2#yijidiankonggui_4_VoltageC=ns=2;s=modbus.1-2#yijidiankonggui.tag3"
    - "1-2#yijidiankonggui_4_CurrentA=ns=2;s=modbus.1-2#yijidiankonggui.tag49"
    - "1-2#yijidiankonggui_4_CurrentB=ns=2;s=modbus.1-2#yijidiankonggui.tag50"
    - "1-2#yijidiankonggui_4_CurrentC=ns=2;s=modbus.1-2#yijidiankonggui.tag51"
    - "1-2#yijidiankonggui_4_ActivePow=ns=2;s=modbus.1-2#yijidiankonggui.tag52"
    - "1-2#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.1-2#yijidiankonggui.tag55"
    - "1-2#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.1-2#yijidiankonggui.tag58"
    - "1-2#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.1-2#yijidiankonggui.tag56"
    - "1-2#yijidiankonggui_4_Exp=ns=2;s=modbus.1-2#yijidiankonggui.tag57"
    - "1-2#yijidiankonggui_4_ExpZN=ns=2;s=modbus.1-2#yijidiankonggui.tag59"
    # å·¦è½¦é—´ç©ºè°ƒ leftWkshopVRVS
    - "2-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag21"
    - "2-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag22"
    - "2-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag23"
    - "2-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag24"
    - "2-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag27"
    - "2-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag30"
    - "2-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag28"
    - "2-1#yijidiankonggui_2_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag29"
    - "2-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag31"
    # è½¦é—´åŠžå…¬å®¤ WorkshopOffice
    - "2-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag35"
    - "2-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag36"
    - "2-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag37"
    - "2-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag38"
    - "2-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag41"
    - "2-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag44"
    - "2-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag42"
    - "2-1#yijidiankonggui_3_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag43"
    - "2-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag45"
    # 1、2楼东办公室 EastOffice
    - "2-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.2-1#yijidiankonggui.tag1"
    - "2-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.2-1#yijidiankonggui.tag2"
    - "2-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.2-1#yijidiankonggui.tag3"
    - "2-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.2-1#yijidiankonggui.tag49"
    - "2-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.2-1#yijidiankonggui.tag50"
    - "2-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.2-1#yijidiankonggui.tag51"
    - "2-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.2-1#yijidiankonggui.tag52"
    - "2-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.2-1#yijidiankonggui.tag55"
    - "2-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.2-1#yijidiankonggui.tag58"
    - "2-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.2-1#yijidiankonggui.tag56"
    - "2-1#yijidiankonggui_4_Exp=ns=2;s=modbus.2-1#yijidiankonggui.tag57"
    - "2-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.2-1#yijidiankonggui.tag59"
    #照明 Lighting
    - "3-1#yijidiankonggui_1_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_1_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_1_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_1_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag7"
    - "3-1#yijidiankonggui_1_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag8"
    - "3-1#yijidiankonggui_1_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag9"
    - "3-1#yijidiankonggui_1_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag10"
    - "3-1#yijidiankonggui_1_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag13"
    - "3-1#yijidiankonggui_1_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag16"
    - "3-1#yijidiankonggui_1_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag14"
    - "3-1#yijidiankonggui_1_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag15"
    - "3-1#yijidiankonggui_1_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag17"
    # è½¦é—´2楼 SecondFloorWorkshop
    - "3-1#yijidiankonggui_2_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_2_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_2_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_2_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag21"
    - "3-1#yijidiankonggui_2_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag22"
    - "3-1#yijidiankonggui_2_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag23"
    - "3-1#yijidiankonggui_2_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag24"
    - "3-1#yijidiankonggui_2_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag27"
    - "3-1#yijidiankonggui_2_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag30"
    - "3-1#yijidiankonggui_2_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag28"
    - "3-1#yijidiankonggui_2_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag29"
    - "3-1#yijidiankonggui_2_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag31"
    # ç”Ÿäº§åŠžå…¬å®¤ ProductionOffice
    - "3-1#yijidiankonggui_3_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_3_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_3_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_3_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag35"
    - "3-1#yijidiankonggui_3_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag36"
    - "3-1#yijidiankonggui_3_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag37"
    - "3-1#yijidiankonggui_3_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag38"
    - "3-1#yijidiankonggui_3_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag41"
    - "3-1#yijidiankonggui_3_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag44"
    - "3-1#yijidiankonggui_3_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag42"
    - "3-1#yijidiankonggui_3_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag43"
    - "3-1#yijidiankonggui_3_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag45"
    # é«˜ä½Žæ¸©è¯•验区 HLTempTest
    - "3-1#yijidiankonggui_4_VoltageA=ns=2;s=modbus.3-1#yijidiankonggui.tag1"
    - "3-1#yijidiankonggui_4_VoltageB=ns=2;s=modbus.3-1#yijidiankonggui.tag2"
    - "3-1#yijidiankonggui_4_VoltageC=ns=2;s=modbus.3-1#yijidiankonggui.tag3"
    - "3-1#yijidiankonggui_4_CurrentA=ns=2;s=modbus.3-1#yijidiankonggui.tag49"
    - "3-1#yijidiankonggui_4_CurrentB=ns=2;s=modbus.3-1#yijidiankonggui.tag50"
    - "3-1#yijidiankonggui_4_CurrentC=ns=2;s=modbus.3-1#yijidiankonggui.tag51"
    - "3-1#yijidiankonggui_4_ActivePow=ns=2;s=modbus.3-1#yijidiankonggui.tag52"
    - "3-1#yijidiankonggui_4_PowFactorT=ns=2;s=modbus.3-1#yijidiankonggui.tag55"
    - "3-1#yijidiankonggui_4_ActiveZN=ns=2;s=modbus.3-1#yijidiankonggui.tag58"
    - "3-1#yijidiankonggui_4_ActiveZT=ns=2;s=modbus.3-1#yijidiankonggui.tag56"
    - "3-1#yijidiankonggui_4_Exp=ns=2;s=modbus.3-1#yijidiankonggui.tag57"
    - "3-1#yijidiankonggui_4_ExpZN=ns=2;s=modbus.3-1#yijidiankonggui.tag59"
    # æˆå“ä»“库温湿度 chengpincangku
    - "chengpincangku_WD=ns=2;s=_AdvancedTags.cpk_wd"
    - "chengpincangku_SD=ns=2;s=_AdvancedTags.cpk_sd"
    # ç”Ÿäº§è½¦é—´ shengchanchejian
    - "shengchanchejian_WD=ns=2;s=_AdvancedTags.sccj_wd"
    - "shengchanchejian_SD=ns=2;s=_AdvancedTags.sccj_sd"
    # åŽŸæ–™ä»“åº“ yuliaocangku
    - "yuliaocangku_WD=ns=2;s=_AdvancedTags.ylk_wd"
    - "yuliaocangku_SD=ns=2;s=_AdvancedTags.ylk_sd"
src/main/resources/application.yml
@@ -1,3 +1,7 @@
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 8089
spring:
  profiles:
    active: dev