diff --git a/linkage-boot/linkage-module-demo/src/main/java/org/jeecg/modules/demo/ttpouringequip/entity/TtPouringEquip.java b/linkage-boot/linkage-module-demo/src/main/java/org/jeecg/modules/demo/ttpouringequip/entity/TtPouringEquip.java index 5ecbaac..de3fe13 100644 --- a/linkage-boot/linkage-module-demo/src/main/java/org/jeecg/modules/demo/ttpouringequip/entity/TtPouringEquip.java +++ b/linkage-boot/linkage-module-demo/src/main/java/org/jeecg/modules/demo/ttpouringequip/entity/TtPouringEquip.java @@ -1,7 +1,6 @@ package org.jeecg.modules.demo.ttpouringequip.entity; import java.io.Serializable; -import java.io.UnsupportedEncodingException; import java.util.Date; import java.math.BigDecimal; @@ -10,7 +9,6 @@ import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; -import org.jeecg.common.aspect.annotation.Dict; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.EqualsAndHashCode; diff --git a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/CustomRunner.java b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/CustomRunner.java deleted file mode 100644 index c130ddd..0000000 --- a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/CustomRunner.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.jeecg; - -import com.fazecast.jSerialComm.SerialPort; -import lombok.extern.slf4j.Slf4j; -import org.jeecg.rscom.RS485Handler; -import org.jeecg.rscom.enums.DEVICE_TYPE; -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.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; - -@Slf4j -//@Component -public class CustomRunner implements ApplicationRunner { - - private ExecutorService executorService = Executors.newFixedThreadPool(DEVICE_TYPE.values().length); // todo - - - @Override - public void run(ApplicationArguments args) { - System.out.println(args); // 通过启动参数配置 // todo - List comlist = Arrays.stream(DEVICE_TYPE.values()) - .map(DEVICE_TYPE::name) - .collect(Collectors.toList()); - log.info("device sum = {} | list = {}" , comlist.size(), comlist); - Map handlerMap = initCOM(comlist); - Set> entries = handlerMap.entrySet(); - for(Map.Entry entry : entries) { - RS485Handler handler = entry.getValue(); - String com = entry.getKey(); - try { - DEVICE_TYPE deviceType = DEVICE_TYPE.valueOf(com); - Runnable task = () -> { - while (true) { - try { - Thread.sleep(3000); // todo - String str = handler.write(deviceType.getCommand()); -// XhDeviceRecordDO entity = handler.makeRecord(deviceType.getParity(), str); -// xhDeviceRecordService.create(entity); - } catch (Exception exp) { - log.error("task appear error!", exp); - } - } - }; - executorService.submit(task); - } catch (Exception exp) { - try { - handler.closePort(); - } catch (Exception ex) { - ex.printStackTrace(); - } - log.info("handle task error 500", exp); - } - } - } - - // 初始化COM串口表 - private Map initCOM(List comlist) { - Map handlerMap = new HashMap<>(); - for(String com : comlist) { - // 查找指定的串口 - SerialPort serialPort = SerialPort.getCommPort(com); - DEVICE_TYPE deviceType = DEVICE_TYPE.valueOf(com); - // 初始化工作 - RS485Handler handler = new RS485Handler(serialPort); - Boolean isOpen = handler.openPort(deviceType.getParity()); - if (isOpen) { - handlerMap.put(com, handler); - } -// handler.listen(); - } - return handlerMap; - } - - public static void main(String[] args) { - // 查找所有串口 - for(SerialPort port: SerialPort.getCommPorts()){ - System.out.println("Port:" + port.getSystemPortName()); //打印串口名称,如COM4 - System.out.println("PortDesc:" + port.getPortDescription()); //打印串口类型,如USB Serial - System.out.println("PortDesc:" + port.getDescriptivePortName()); //打印串口的完整类型,如USB-SERIAL CH340(COM4) - } - } -} diff --git a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/enums/DEVICE_TYPE.java b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/enums/DEVICE_TYPE.java new file mode 100644 index 0000000..fbe98e4 --- /dev/null +++ b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/enums/DEVICE_TYPE.java @@ -0,0 +1,110 @@ +package org.jeecg.custom.enums; + +import com.fazecast.jSerialComm.SerialPort; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.List; + +// 设备枚举 +public enum DEVICE_TYPE { + + COM1("192.168.10.201", "烘箱1", "", SerialPort.EVEN_PARITY), + COM2("192.168.10.202", "烘箱2", "", 2), + COM3("192.168.10.203", "烘箱3", "", 2), + COM4("192.168.10.204", "烘箱4", "", 2), + COM5("192.168.10.205", "烘箱5", "",2), + COM6("192.168.10.218", "烘箱6", "",2), + COM11("192.168.10.211", "模具1", "",2), + COM12("192.168.10.212", "模具2", "",2), + COM21("192.168.10.215", "罐子1", "",2), + COM22("192.168.10.216", "罐子2", "",2), + COM23("192.168.10.217", "罐子3", "",2), + COM24("192.168.10.229", "罐子4", "",2), + COM31("192.168.10.225", "数字电表1", "1B 03 00 32 00 02 67 FE", SerialPort.NO_PARITY), + COM32("192.168.10.226", "数字电表2", "07 03 00 32 00 02 65 A2", 0), + COM33("192.168.10.227", "数字电表3", "A0 03 00 32 00 02 7C B5",0), + COM34("192.168.10.228", "数字电表4", "1D 03 00 32 00 02 67 98",0); + + + private String hostNum; + private String name; + private String command; + + private Integer parity; + + private static final String tempCmd = "01 03 20 00 00 01 8F CA"; + + private DEVICE_TYPE(String hostNum, String name, String cmd, Integer parity) { + this.hostNum = hostNum; + this.name = name; + this.parity = parity; + this.command = StringUtils.isEmpty(cmd) ? tempCmd : cmd; + } + + public String getHostNum() { + return hostNum; + } + + public String getName() { + return name; + } + + public String getCommand(){ + return command; + } + + public Integer getParity(){ + return parity; + } + + + // 模具设备列表 + public static List getJzjMolds() { + List jzjMolds = Arrays.asList( + DEVICE_TYPE.COM11, + DEVICE_TYPE.COM12 + ); + return jzjMolds; + } + + + // 浇注机设备列表 + public static List getJzjDevice() { + List jzjDevice = Arrays.asList( + DEVICE_TYPE.COM1, + DEVICE_TYPE.COM2, + DEVICE_TYPE.COM3, + DEVICE_TYPE.COM4, + DEVICE_TYPE.COM5, + DEVICE_TYPE.COM6, + DEVICE_TYPE.COM11, + DEVICE_TYPE.COM12 + ); + return jzjDevice; + } + + // 集中供料罐列表 + public static List getGzDevice() { + List gzDevice = Arrays.asList( + DEVICE_TYPE.COM21, + DEVICE_TYPE.COM22, + DEVICE_TYPE.COM23, + DEVICE_TYPE.COM24 + ); + return gzDevice; + } + + + + // 数字电表列表 + public static List getMeterDevice() { + List meterDevice = Arrays.asList( + DEVICE_TYPE.COM31, + DEVICE_TYPE.COM32, + DEVICE_TYPE.COM33, + DEVICE_TYPE.COM34 + ); + return meterDevice; + } +} diff --git a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/task/TtDataCollectTask.java b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/task/TtDataCollectTask.java new file mode 100644 index 0000000..e1b7a5b --- /dev/null +++ b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/task/TtDataCollectTask.java @@ -0,0 +1,211 @@ +package org.jeecg.custom.task; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.fazecast.jSerialComm.SerialPort; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jeecg.custom.enums.DEVICE_TYPE; +import org.jeecg.custom.utils.RS485Handler; +import org.jeecg.modules.demo.ttelectricmeter.entity.TtElectricMeter; +import org.jeecg.modules.demo.ttelectricmeter.service.ITtElectricMeterService; +import org.jeecg.modules.demo.tteqtbase.entity.TtEqtBase; +import org.jeecg.modules.demo.tteqtbase.service.ITtEqtBaseService; +import org.jeecg.modules.demo.ttfeedingequip.entity.TtFeedingEquip; +import org.jeecg.modules.demo.ttfeedingequip.service.ITtFeedingEquipService; +import org.jeecg.modules.demo.ttpouringequip.entity.TtPouringEquip; +import org.jeecg.modules.demo.ttpouringequip.service.ITtPouringEquipService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.support.CronTrigger; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +@Configuration //1.主要用于标记配置类,兼备Component的效果。 +@EnableScheduling // 2.开启定时任务 +@Slf4j +public class TtDataCollectTask implements SchedulingConfigurer { + + private static Map jzjHandlerMap = new HashMap<>(); + private static Map gzHandlerMap = new HashMap<>(); + private static Map meterHandlerMap = new HashMap<>(); + + private ScheduledTaskRegistrar taskRegistrar; + + @Autowired + ITtPouringEquipService pouringEquipService; + + @Autowired + ITtFeedingEquipService feedingEquipService; + + @Autowired + ITtElectricMeterService electricMeterService; + + @Autowired + ITtEqtBaseService iTtEqtBaseService; + + // 初始化 + static { + initDeviceCOM(DEVICE_TYPE.getJzjDevice(),1); + initDeviceCOM(DEVICE_TYPE.getGzDevice(),2); + initDeviceCOM(DEVICE_TYPE.getMeterDevice(),3); + } + + + /** + * 执行定时任务. + */ + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + this.taskRegistrar = taskRegistrar; + this.taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10)); + String cron1 = "0 0/5 * * * ?"; + Map eqtNoIpMap = getEqtNoIpMapping(); + // 获取浇注机模具列表 + List jzjMolds = DEVICE_TYPE.getJzjMolds(); + // 创建浇注设备定时任务 + for(Map.Entry entry : jzjHandlerMap.entrySet()) { + RS485Handler handler = entry.getValue(); + DEVICE_TYPE deviceType = entry.getKey(); + Runnable runnable = () -> { + log.info("5min执行一次浇注设备温度采集:" + LocalDateTime.now().toLocalTime()); + String str = handler.write(deviceType.getCommand()); + String temp = handler.parseData(str, 1); + log.info("device com {} read str = {} | parse temp = {}", deviceType.name(), str, temp); + if (StringUtils.isNotBlank(temp)) { + Integer type = jzjMolds.contains(deviceType) ? 2 : 1; + String eqtIp = deviceType.getHostNum(); + TtPouringEquip ttPouringEquip = new TtPouringEquip(); + ttPouringEquip.setTemperature(new BigDecimal(temp)); + ttPouringEquip.setCreateTime(new Date()); + ttPouringEquip.setType(type); + ttPouringEquip.setEqtNo(Optional.ofNullable(eqtNoIpMap.get(eqtIp)).orElse("0")); + ttPouringEquip.setEqtIp(eqtIp); + pouringEquipService.save(ttPouringEquip); + } + }; + this.addTriggerTask(runnable, cron1); + } + + // 创建集中供料设备定时任务 + for(Map.Entry entry : gzHandlerMap.entrySet()) { + RS485Handler handler = entry.getValue(); + DEVICE_TYPE deviceType = entry.getKey(); + Runnable runnable = () -> { + log.info("5min执行一次供料设备温度采集:" + LocalDateTime.now().toLocalTime()); + String str = handler.write(deviceType.getCommand()); + String temp = handler.parseData(str, 1); + log.info("device com {} read str = {} | parse temp = {}", deviceType.name(), str, temp); + if (StringUtils.isNotBlank(temp)) { + String eqtIp = deviceType.getHostNum(); + TtFeedingEquip ttFeedingEquip = new TtFeedingEquip(); + ttFeedingEquip.setTemperature(new BigDecimal(temp)); + ttFeedingEquip.setCreateTime(new Date()); + ttFeedingEquip.setEqtNo(Optional.ofNullable(eqtNoIpMap.get(eqtIp)).orElse("0")); + ttFeedingEquip.setEqtIp(eqtIp); + feedingEquipService.save(ttFeedingEquip); + } + }; + this.addTriggerTask(runnable, cron1); + } + + +// String cron2 = "0 0 8 * * ?"; + String cron2 = "0/5 * * * * ?"; + // 创建数字电表定时任务 + for(Map.Entry entry : meterHandlerMap.entrySet()) { + RS485Handler handler = entry.getValue(); + DEVICE_TYPE deviceType = entry.getKey(); + Runnable runnable = () -> { + // 电量计算 + log.info("每天8点执行一次数字电表电量采集:" + LocalDateTime.now().toLocalTime()); + String str = handler.write(deviceType.getCommand()); + String power = handler.parseData(str, 2); + log.info("device com {} read str = {} | parse power = {}", deviceType.name(), str, power); + if (StringUtils.isNotBlank(power)) { + String eqtIp = deviceType.getHostNum(); + BigDecimal totalPower = new BigDecimal(power); + TtElectricMeter ttElectricMeter = new TtElectricMeter(); + ttElectricMeter.setTotalPower(totalPower); + ttElectricMeter.setCreateTime(new Date()); + ttElectricMeter.setEqtNo(Optional.ofNullable(eqtNoIpMap.get(eqtIp)).orElse("0")); + ttElectricMeter.setEqtIp(eqtIp); + // 获取昨日用电量 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(TtElectricMeter::getEqtIp, eqtIp).orderByDesc(TtElectricMeter::getCreateTime).last("limit 1"); + TtElectricMeter lastElectricMeter = electricMeterService.getOne(lqw); + BigDecimal lastTotalPower = Optional.ofNullable(lastElectricMeter) + .map(TtElectricMeter::getTotalPower).orElse(new BigDecimal(0)); + BigDecimal lastUse = totalPower.subtract(lastTotalPower); + ttElectricMeter.setLastUse(lastUse); + electricMeterService.save(ttElectricMeter); + } + log.info("device com {} read power data={}", deviceType.name(), str); + }; + this.addTriggerTask(runnable, cron2); + } + } + + + // 获取所有运行状态正常的Ip设备 + private Map getEqtNoIpMapping() { + Map map; + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.isNotNull(TtEqtBase::getEqtIp); + lqw.eq(TtEqtBase::getEqtStatus,1); // 运行正常 + List list = iTtEqtBaseService.list(lqw); + map = list.stream().collect(Collectors.toMap(TtEqtBase::getEqtIp, TtEqtBase::getEqtNo)); + log.info("running eqt ip no mappings = {}", map); + return map; + } + + private void addTriggerTask(Runnable runnable, String cron) { + taskRegistrar.addTriggerTask( + //1.添加任务内容(Runnable) + runnable, + //2.设置执行周期(Trigger) + triggerContext -> { + if (StringUtils.isEmpty(cron)) { + log.error("cron expr invalid!"); + } + //2.3 返回执行周期(Date) + return new CronTrigger(cron).nextExecutionTime(triggerContext); + } + ); + } + + + /** + * 初始化串口 + * @param COMList + * @return Map + */ + private static void initDeviceCOM(List COMList, Integer type) { + for(DEVICE_TYPE COM : COMList) { + // 查找指定的串口 + String COMName = COM.name(); + SerialPort serialPort = SerialPort.getCommPort(COMName); + // 初始化工作 + RS485Handler handler = new RS485Handler(serialPort); + Boolean isOpen = handler.openPort(COM.getParity()); + if (isOpen) { + if (type == 1) { + jzjHandlerMap.put(COM, handler); + } else if (type == 2) { + gzHandlerMap.put(COM, handler); + } else { + meterHandlerMap.put(COM, handler); + } + } + // handler.listen(); + } + } + + +} diff --git a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/RS485Handler.java b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/utils/RS485Handler.java similarity index 88% rename from linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/RS485Handler.java rename to linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/utils/RS485Handler.java index d868710..26e60d6 100644 --- a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/RS485Handler.java +++ b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/custom/utils/RS485Handler.java @@ -1,4 +1,4 @@ -package org.jeecg.rscom; +package org.jeecg.custom.utils; import com.fazecast.jSerialComm.SerialPort; import com.fazecast.jSerialComm.SerialPortDataListener; @@ -6,8 +6,6 @@ import com.fazecast.jSerialComm.SerialPortEvent; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import java.util.Date; - @Slf4j public class RS485Handler { @@ -59,7 +57,6 @@ public class RS485Handler { // 休眠1秒,等待下位机读取数据 Thread.sleep(1000); data = read(); - log.info("portName {} | read data list = {}", portName, data); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -86,26 +83,22 @@ public class RS485Handler { } - // 返回数据处理 -// public XhDeviceRecordDO makeRecord(Integer type, String str){ -// XhDeviceRecordDO entity = new XhDeviceRecordDO(); -// entity.setCom(portName); -// entity.setCreatetime(new Date()); -// entity.setPower(""); // sql字段不为null,设置默认值 -// entity.setTemp(""); -// if (type == 0) { // 解析用电量指标 -// String kwHex = StringUtils.substring(str,6, 14); -// if(!kwHex.equals(str) && StringUtils.isNotBlank(kwHex)) { -// entity.setPower(hex2Float(kwHex)); -// } -// } else if (type == 2){ // 解析温度指标 -// String tempHex = StringUtils.substring(str,6, 10); -// if(!tempHex.equals(str) && StringUtils.isNotBlank(tempHex)) { -// entity.setTemp(hex2Decimal(tempHex)); -// } -// } -// return entity; -// } + // 数据解析处理 + public String parseData(String str, Integer type){ + String content = null; + if (type == 1) { // 解析温度指标 + String tempHex = StringUtils.substring(str,6, 10); + if(!tempHex.equals(str) && StringUtils.isNotBlank(tempHex)) { + content = hex2Decimal(tempHex); + } + } else if (type == 2){ // 解析用电量指标 + String kwHex = StringUtils.substring(str,6, 14); + if(!kwHex.equals(str) && StringUtils.isNotBlank(kwHex)) { + content = hex2Float(kwHex); + } + } + return content; + } diff --git a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/enums/DEVICE_TYPE.java b/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/enums/DEVICE_TYPE.java deleted file mode 100644 index d929134..0000000 --- a/linkage-boot/linkage-module-system/linkage-system-start/src/main/java/org/jeecg/rscom/enums/DEVICE_TYPE.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.jeecg.rscom.enums; - -import com.fazecast.jSerialComm.SerialPort; -import org.apache.commons.lang3.StringUtils; - -// 设备枚举 -public enum DEVICE_TYPE { - - COM1("201", "烘箱1", "", SerialPort.EVEN_PARITY), - COM2("202", "烘箱2", "", 2), - COM3("203", "烘箱3", "", 2), - COM4("204", "烘箱4", "", 2), - COM5("205", "烘箱5", "",2), - COM6("218", "烘箱6", "",2), - COM11("211", "模具1", "",2), - COM12("212", "模具2", "",2), - COM21("215", "罐子1", "",2), - COM22("216", "罐子2", "",2), - COM23("217", "罐子3", "",2), - COM31("225", "数字电表1", "1B 03 00 32 00 02 67 FE", SerialPort.NO_PARITY), - COM32("226", "数字电表2", "07 03 00 32 00 02 65 A2", 0), - COM33("227", "数字电表3", "A0 03 00 32 00 02 7C B5",0), - COM34("228", "数字电表4", "1D 03 00 32 00 02 67 98",0), - COM35("229", "数字电表5", "",0); // todo - - private String hostNum; - private String name; - private String command; - - private Integer parity; - - private static final String tempCmd = "01 03 20 00 00 01 8F CA"; - - private DEVICE_TYPE(String hostNum, String name, String cmd, Integer parity) { - this.hostNum = hostNum; - this.name = name; - this.parity = parity; - this.command = StringUtils.isEmpty(cmd) ? tempCmd : cmd; - } - - public String getHostNum() { - return hostNum; - } - - public String getName() { - return name; - } - - public String getCommand(){ - return command; - } - - public Integer getParity(){ - return parity; - } -}