package com.ruoyi.schedule; import com.ruoyi.common.domain.CustomThread; import com.ruoyi.common.domain.PlcConnectInfo; import com.ruoyi.device.cdz.domain.DeviceCdz; import com.ruoyi.device.cdz.service.IDeviceCdzService; import com.ruoyi.device.ddj.domain.MsgDdj; import com.ruoyi.device.ddj.service.IMsgDdjService; import com.ruoyi.device.srgv.domain.DeviceSrgv; import com.ruoyi.device.srgv.service.IDeviceSrgvService; import com.ruoyi.device.ssj.domain.DeviceSsj; import com.ruoyi.device.ssj.service.IDeviceSsjService; import com.ruoyi.device.tsj.domain.DeviceTsj; import com.ruoyi.device.tsj.service.IDeviceTsjService; import com.ruoyi.project.ft546.device.Ft546DeviceRuntimeRegistry; import com.ruoyi.project.ft546.device.shuttle.Ft546SrgvRuntimeFactory; import com.ruoyi.project.ft546.config.Ft546WcsProperties; import com.ruoyi.schedule.plcRead.cdz.PlcCdzRead; import com.ruoyi.schedule.plcRead.ddj.PlcDdjRead; import com.ruoyi.schedule.plcRead.srgv.PlcSrgvRead; import com.ruoyi.schedule.plcRead.ssj.PlcSsjRead; import com.ruoyi.schedule.plcRead.tsj.PlcTsjRead; import com.ruoyi.schedule.scheduleTask.cdz.CdzThread; import com.ruoyi.schedule.scheduleTask.ddj.impl.Ddj1Thread; import com.ruoyi.schedule.scheduleTask.monit.MonitoringThread; import com.ruoyi.schedule.scheduleTask.srgv.impl.SRgv1Thread; import com.ruoyi.schedule.scheduleTask.ssj.SsjThread; import com.ruoyi.schedule.scheduleTask.tsj.TsjThread; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component @Slf4j public class ScheduleThread { public CustomThread plcSsjReadCustomThread; public CustomThread plcTsjReadCustomThread; public CustomThread plcCdzReadCustomThread; public final Map> plcSrgvReadCustomThreads = new ConcurrentHashMap>(); public CustomThread monitoringCustomThread; public CustomThread ssjThreadCustomThread; public CustomThread sRgvThreadCustomThread; public CustomThread tsjThreadCustomThread; public CustomThread cdzThreadCustomThread; @Autowired private IDeviceSsjService deviceSsjService; @Autowired private IDeviceSrgvService deviceSrgvService; @Autowired private IDeviceTsjService deviceTsjService; @Autowired private IDeviceCdzService deviceCdzService; @Autowired private Ft546DeviceRuntimeRegistry deviceRuntimeRegistry; @Autowired private Ft546SrgvRuntimeFactory srgvRuntimeFactory; @Autowired private Ft546WcsProperties ft546WcsProperties; private volatile boolean isRun = false; private volatile boolean isRun2 = false; private static final long THREAD_STOP_TIMEOUT_MS = 5000L; /** * 项目初始化启动 */ @PostConstruct public void init() { log.info("初始化调度服务"); //读取信息初始化 plcReadInit(); //调度初始化 scheduleInit(); log.info("调度服务执行成功"); // startAllThread(); // startAllThread2(); } @EventListener(ApplicationReadyEvent.class) public void startStandardFactReadersAfterApplicationReady() { if (isStandardMode()) { startAllThread(); } } /** * 调度初始化 */ private void scheduleInit() { if (isStandardMode()) { return; } MonitoringThread monitoringThread = new MonitoringThread(); monitoringCustomThread = new CustomThread(new Thread(monitoringThread), monitoringThread); SsjThread ssjThread=new SsjThread(); ssjThreadCustomThread=new CustomThread(new Thread(ssjThread),ssjThread); SRgv1Thread srgvThread=new SRgv1Thread(); sRgvThreadCustomThread=new CustomThread<>(new Thread(srgvThread),srgvThread); TsjThread tsjThread=new TsjThread(); tsjThreadCustomThread=new CustomThread<>(new Thread(tsjThread),tsjThread); CdzThread cdzThread = new CdzThread(); cdzThreadCustomThread=new CustomThread<>(new Thread(cdzThread),cdzThread); // Ddj1Thread ddj1Thread = new Ddj1Thread(); // ddj1CustomThread = new CustomThread<>(new Thread(ddj1Thread), ddj1Thread); /*Ddj2Thread ddj2Thread = new Ddj2Thread(); ddj2CustomThread = new CustomThread<>(new Thread(ddj2Thread), ddj2Thread); Ddj3Thread ddj3Thread = new Ddj3Thread(); ddj3CustomThread = new CustomThread<>(new Thread(ddj3Thread), ddj3Thread); Ddj4Thread ddj4Thread = new Ddj4Thread(); ddj4CustomThread = new CustomThread<>(new Thread(ddj4Thread), ddj4Thread); Ddj5Thread ddj5Thread = new Ddj5Thread(); ddj5CustomThread = new CustomThread<>(new Thread(ddj5Thread), ddj5Thread); Ddj6Thread ddj6Thread = new Ddj6Thread(); ddj6CustomThread = new CustomThread<>(new Thread(ddj6Thread), ddj6Thread);*/ } /** * plc读取初始化 */ private void plcReadInit() { ConcurrentHashMap ssjList = new ConcurrentHashMap<>(); //获取要去取的输送机 List deviceSsjs = deviceSsjService.selectDeviceSsjList(new DeviceSsj()); for (DeviceSsj deviceSsj : deviceSsjs) { ssjList.put(deviceSsj.getDeviceCode(), deviceSsj); } // plc输送机读取线程 PlcSsjRead plcSsjRead = new PlcSsjRead(ssjList, new PlcConnectInfo("192.168.200.41", 102)); Thread plcSsjReadThread = new Thread(plcSsjRead); plcSsjReadCustomThread = new CustomThread(plcSsjReadThread, plcSsjRead); //四向车读取线程 ConcurrentHashMap srgvList = new ConcurrentHashMap<>(); List srgvs=deviceSrgvService.selectDeviceSrgvList(new DeviceSrgv()); for(DeviceSrgv srgv:srgvs){ String deviceId = srgv.getDeviceId().toString(); srgvList.put(deviceId,srgv); PlcSrgvRead plcSrgvRead = srgvRuntimeFactory.create(srgv); deviceRuntimeRegistry.register(deviceId, plcSrgvRead); Thread plcSrgvReadThread = new Thread(plcSrgvRead); plcSrgvReadCustomThreads.put(deviceId, new CustomThread(plcSrgvReadThread, plcSrgvRead)); } PlcSrgvRead.deviceSrgvMap=srgvList; //提升机读取线程 ConcurrentHashMap tsjList = new ConcurrentHashMap<>(); List deviceTsjs = deviceTsjService.selectDeviceTsjList(new DeviceTsj()); for (DeviceTsj deviceTsj : deviceTsjs) { tsjList.put(deviceTsj.getId().toString(), deviceTsj); } PlcTsjRead plcTsjRead = new PlcTsjRead(tsjList,new PlcConnectInfo("192.168.200.41", 102)); Thread plcTsjReadThread = new Thread(plcTsjRead); plcTsjReadCustomThread = new CustomThread<>(plcTsjReadThread, plcTsjRead); //充电桩读取线程 ConcurrentHashMap cdzList = new ConcurrentHashMap<>(); List deviceCdzs = deviceCdzService.selectDeviceCdzList(new DeviceCdz()); for (DeviceCdz deviceCdz : deviceCdzs) { cdzList.put(deviceCdz.getId().toString(), deviceCdz); } PlcCdzRead plcCdzRead = new PlcCdzRead(cdzList,new PlcConnectInfo("192.168.200.41", 102)); Thread plcCdzReadThread = new Thread(plcCdzRead); plcCdzReadCustomThread = new CustomThread<>(plcCdzReadThread, plcCdzRead); } /** * 开始线程 */ public synchronized void startAllThread() { if (isRun) { return; } List readerThreads = requireFactReaderThreads(); for (Thread readerThread : readerThreads) { if (readerThread.getState() != Thread.State.NEW) { throw new IllegalStateException( "PLC fact reader cannot be restarted: " + readerThread.getName()); } } for (Thread readerThread : readerThreads) { readerThread.start(); } isRun = true; } /** * 开启线程2 */ public void startAllThread2() { if (isStandardMode()) { throw new IllegalStateException( "legacy business scheduler is disabled in STANDARD mode"); } monitoringCustomThread.thread.start(); ssjThreadCustomThread.thread.start(); tsjThreadCustomThread.thread.start(); sRgvThreadCustomThread.thread.start(); cdzThreadCustomThread.thread.start(); isRun2 = true; } /** * 停止线程 */ public synchronized void stopAllThread() { if (!isRun) { return; } List readerThreads = currentFactReaderThreads(); signalFactReadersToStop(); isRun = false; awaitFactReadersStopped(readerThreads); plcSrgvReadCustomThreads.clear(); if (deviceRuntimeRegistry != null) { deviceRuntimeRegistry.clear(); } // plcDdj1ReadCustomThread.runnable.isRun = false; /* plcDdj2ReadCustomThread.runnable.isRun = false; plcDdj3ReadCustomThread.runnable.isRun = false; plcDdj4ReadCustomThread.runnable.isRun = false; plcDdj5ReadCustomThread.runnable.isRun = false; plcDdj6ReadCustomThread.runnable.isRun = false;*/ plcReadInit(); } private List requireFactReaderThreads() { List threads = new ArrayList(); threads.add(requireThread(plcSsjReadCustomThread, "conveyor fact reader")); for (Map.Entry> entry : plcSrgvReadCustomThreads.entrySet()) { threads.add(requireThread(entry.getValue(), "shuttle fact reader " + entry.getKey())); } threads.add(requireThread(plcTsjReadCustomThread, "lift fact reader")); threads.add(requireThread(plcCdzReadCustomThread, "charger fact reader")); return threads; } private List currentFactReaderThreads() { List threads = new ArrayList(); addThreadIfPresent(threads, plcSsjReadCustomThread); for (CustomThread reader : plcSrgvReadCustomThreads.values()) { addThreadIfPresent(threads, reader); } addThreadIfPresent(threads, plcTsjReadCustomThread); addThreadIfPresent(threads, plcCdzReadCustomThread); return threads; } private void signalFactReadersToStop() { if (plcSsjReadCustomThread != null && plcSsjReadCustomThread.runnable != null) { plcSsjReadCustomThread.runnable.isRun = false; } for (CustomThread reader : plcSrgvReadCustomThreads.values()) { if (reader != null && reader.runnable != null) { reader.runnable.isRun = false; } } if (plcTsjReadCustomThread != null && plcTsjReadCustomThread.runnable != null) { plcTsjReadCustomThread.runnable.isRun = false; } if (plcCdzReadCustomThread != null && plcCdzReadCustomThread.runnable != null) { plcCdzReadCustomThread.runnable.isRun = false; } } private void awaitFactReadersStopped(List readerThreads) { long deadline = System.currentTimeMillis() + THREAD_STOP_TIMEOUT_MS; for (Thread readerThread : readerThreads) { long remaining = deadline - System.currentTimeMillis(); if (remaining <= 0L) { break; } try { readerThread.join(remaining); } catch (InterruptedException interrupted) { Thread.currentThread().interrupt(); throw new IllegalStateException( "interrupted while stopping PLC fact readers", interrupted); } } for (Thread readerThread : readerThreads) { if (readerThread.isAlive()) { throw new IllegalStateException( "PLC fact reader did not stop: " + readerThread.getName()); } } } private static Thread requireThread(CustomThread customThread, String name) { if (customThread == null || customThread.getThread() == null) { throw new IllegalStateException(name + " is not initialized"); } return customThread.getThread(); } private static void addThreadIfPresent(List threads, CustomThread customThread) { if (customThread != null && customThread.getThread() != null) { threads.add(customThread.getThread()); } } /** * 停止线程2 */ public void stopAllThread2() { if (isStandardMode()) { isRun2 = false; return; } monitoringCustomThread.runnable.isRun = false; // ddj1CustomThread.runnable.isRun = false; /*ddj2CustomThread.runnable.isRun = false; ddj3CustomThread.runnable.isRun = false; ddj4CustomThread.runnable.isRun = false; ddj5CustomThread.runnable.isRun = false; ddj6CustomThread.runnable.isRun = false;*/ scheduleInit(); isRun2 = false; } /** * 获取调度状态 */ public HashMap getScheduleStatus() { HashMap map = new HashMap<>(); map.put("isRun",isRun); map.put("isRun2",isRun2); return map; } private boolean isStandardMode() { return ft546WcsProperties != null && ft546WcsProperties.getRuntimeMode() == Ft546WcsProperties.RuntimeMode.STANDARD; } }