LED屏管理
parent
35376801aa
commit
d9b6afdc80
File diff suppressed because one or more lines are too long
|
|
@ -45,9 +45,7 @@ public class SysLedscreen extends BaseEntity
|
|||
@Excel(name = "高")
|
||||
private Long height;
|
||||
|
||||
/** 频率(秒) */
|
||||
@Excel(name = "频率(秒)")
|
||||
private Long frequency;
|
||||
|
||||
|
||||
/** LED绘图模式 */
|
||||
@Excel(name = "LED绘图模式")
|
||||
|
|
@ -151,15 +149,8 @@ public class SysLedscreen extends BaseEntity
|
|||
{
|
||||
return height;
|
||||
}
|
||||
public void setFrequency(Long frequency)
|
||||
{
|
||||
this.frequency = frequency;
|
||||
}
|
||||
|
||||
public Long getFrequency()
|
||||
{
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setDrawType(Long drawType)
|
||||
{
|
||||
this.drawType = drawType;
|
||||
|
|
@ -236,7 +227,6 @@ public class SysLedscreen extends BaseEntity
|
|||
.append("deviceSn", getDeviceSn())
|
||||
.append("width", getWidth())
|
||||
.append("height", getHeight())
|
||||
.append("frequency", getFrequency())
|
||||
.append("drawType", getDrawType())
|
||||
.append("title", getTitle())
|
||||
.append("enabled", getEnabled())
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="deviceSn" column="device_sn" />
|
||||
<result property="width" column="width" />
|
||||
<result property="height" column="height" />
|
||||
<result property="frequency" column="frequency" />
|
||||
<result property="drawType" column="draw_type" />
|
||||
<result property="title" column="title" />
|
||||
<result property="enabled" column="enabled" />
|
||||
|
|
@ -29,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</resultMap>
|
||||
|
||||
<sql id="selectSysLedscreenVo">
|
||||
select sl.id, sl.project_id, sl.workarea_id, sl.device_name, sl.device_sn, sl.width, sl.height, sl.frequency, sl.draw_type, sl.title, sl.enabled, sl.is_del, sl.state, sl.is_online, sl.remark, sl.create_by, sl.create_time, sl.update_by, sl.update_time, pi.project_name, wa.title as workarea_name
|
||||
select sl.id, sl.project_id, sl.workarea_id, sl.device_name, sl.device_sn, sl.width, sl.height, sl.draw_type, sl.title, sl.enabled, sl.is_del, sl.state, sl.is_online, sl.remark, sl.create_by, sl.create_time, sl.update_by, sl.update_time, pi.project_name, wa.title as workarea_name
|
||||
from sys_ledscreen sl
|
||||
left join pro_project_info pi on sl.project_id = pi.id
|
||||
left join sys_work_area wa on sl.workarea_id = wa.id
|
||||
|
|
@ -44,7 +43,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="deviceSn != null and deviceSn != ''"> and sl.device_sn = #{deviceSn}</if>
|
||||
<if test="width != null "> and sl.width = #{width}</if>
|
||||
<if test="height != null "> and sl.height = #{height}</if>
|
||||
<if test="frequency != null "> and sl.frequency = #{frequency}</if>
|
||||
<if test="drawType != null "> and sl.draw_type = #{drawType}</if>
|
||||
<if test="title != null and title != ''"> and sl.title = #{title}</if>
|
||||
<if test="enabled != null "> and sl.enabled = #{enabled}</if>
|
||||
|
|
@ -68,7 +66,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="deviceSn != null">device_sn,</if>
|
||||
<if test="width != null">width,</if>
|
||||
<if test="height != null">height,</if>
|
||||
<if test="frequency != null">frequency,</if>
|
||||
<if test="drawType != null">draw_type,</if>
|
||||
<if test="title != null">title,</if>
|
||||
<if test="enabled != null">enabled,</if>
|
||||
|
|
@ -89,7 +86,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="deviceSn != null">#{deviceSn},</if>
|
||||
<if test="width != null">#{width},</if>
|
||||
<if test="height != null">#{height},</if>
|
||||
<if test="frequency != null">#{frequency},</if>
|
||||
<if test="drawType != null">#{drawType},</if>
|
||||
<if test="title != null">#{title},</if>
|
||||
<if test="enabled != null">#{enabled},</if>
|
||||
|
|
@ -113,7 +109,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="deviceSn != null">device_sn = #{deviceSn},</if>
|
||||
<if test="width != null">width = #{width},</if>
|
||||
<if test="height != null">height = #{height},</if>
|
||||
<if test="frequency != null">frequency = #{frequency},</if>
|
||||
<if test="drawType != null">draw_type = #{drawType},</if>
|
||||
<if test="title != null">title = #{title},</if>
|
||||
<if test="enabled != null">enabled = #{enabled},</if>
|
||||
|
|
@ -148,7 +143,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="deviceName != null">device_name = #{deviceName},</if>
|
||||
<if test="width != null">width = #{width},</if>
|
||||
<if test="height != null">height = #{height},</if>
|
||||
<if test="frequency != null">frequency = #{frequency},</if>
|
||||
<if test="drawType != null">draw_type = #{drawType},</if>
|
||||
<if test="title != null">title = #{title},</if>
|
||||
<if test="enabled != null">enabled = #{enabled},</if>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,29 @@
|
|||
package com.yanzhu.led;
|
||||
|
||||
import com.yanzhu.api.domain.SysDictData;
|
||||
import com.yanzhu.led.service.ILedScreenService;
|
||||
import com.yanzhu.led.service.LedDrawService;
|
||||
import com.yanzhu.led.service.LedServerService;
|
||||
import com.yanzhu.system.domain.SysLedscreen;
|
||||
import com.yanzhu.system.domain.SysWorkArea;
|
||||
import com.yanzhu.system.mapper.SysDictDataMapper;
|
||||
import com.yanzhu.system.mapper.SysWorkAreaMapper;
|
||||
import onbon.bx06.Bx6GScreen;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.scheduling.support.CronTrigger;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.yanzhu.led.config.LedProperties;
|
||||
|
||||
|
|
@ -42,45 +47,60 @@ public class LedMainApplication {
|
|||
@Autowired
|
||||
private LedDrawService ledDrawService;
|
||||
|
||||
// 用于管理各个LED屏的刷新任务
|
||||
@Autowired
|
||||
private SysDictDataMapper sysDictDataMapper;
|
||||
|
||||
private final ThreadPoolTaskScheduler cronScheduler = new ThreadPoolTaskScheduler();
|
||||
|
||||
private final ConcurrentHashMap<String, Map<String, ScheduledFuture<?>>> scheduledTasks = new ConcurrentHashMap<>();
|
||||
|
||||
private final ConcurrentHashMap<String, Runnable> refreshTasks = new ConcurrentHashMap<>();
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
|
||||
|
||||
private List<SysDictData> cronExpressions = Collections.emptyList();
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void initialize() throws Exception {
|
||||
// 启动LED服务器守护功能
|
||||
loadLedRefreshTimer();
|
||||
cronScheduler.initialize();
|
||||
|
||||
ledServerService.initializeServer();
|
||||
|
||||
// 加载所有LED屏配置
|
||||
loadAllLedScreens();
|
||||
|
||||
// 启动定时刷新任务
|
||||
startPeriodicRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载所有LED屏配置
|
||||
*/
|
||||
private void loadLedRefreshTimer(){
|
||||
SysDictData dictWhere=new SysDictData();
|
||||
dictWhere.setDictType("led_refresh_timer");
|
||||
dictWhere.setStatus("0");
|
||||
cronExpressions=sysDictDataMapper.selectDictDataList(dictWhere);
|
||||
}
|
||||
|
||||
private void loadAllLedScreens() {
|
||||
List<SysLedscreen> ledScreens = ledScreenService.getAllLedScreens();
|
||||
logger.info("加载了 {} 个LED屏配置", ledScreens.size());
|
||||
|
||||
for (SysLedscreen ledScreen : ledScreens) {
|
||||
// 为每个LED屏创建刷新任务
|
||||
createRefreshTask(ledScreen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为LED屏创建刷新任务
|
||||
*/
|
||||
public List<String> getProjectCronExpressions(long projectId) {
|
||||
String prjId=""+projectId;
|
||||
List<SysDictData> prjList=cronExpressions.stream().filter(d-> StringUtils.equals(prjId,d.getCssClass())).collect(Collectors.toList());
|
||||
if(prjList.isEmpty()){
|
||||
prjList=cronExpressions.stream().filter(d->StringUtils.isBlank(d.getCssClass())).collect(Collectors.toList());
|
||||
}
|
||||
return prjList.stream().map(d->d.getDictValue()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void createRefreshTask(SysLedscreen ledScreen) {
|
||||
Runnable task = () -> {
|
||||
try {
|
||||
// 从服务中获取最新的LED屏信息,确保获取最新的在线状态
|
||||
SysLedscreen currentScreen = ledScreenService.getLedScreenByNetId(ledScreen.getDeviceSn());
|
||||
if (currentScreen != null && currentScreen.isOnline()) {
|
||||
|
||||
boolean success = ledDrawService.drawLedScreenContent(currentScreen);
|
||||
if (success) {
|
||||
logger.info("成功刷新LED屏: {}", currentScreen.getDeviceSn());
|
||||
|
|
@ -95,11 +115,33 @@ public class LedMainApplication {
|
|||
}
|
||||
};
|
||||
|
||||
// 存储任务引用
|
||||
refreshTasks.put(ledScreen.getDeviceSn(), task);
|
||||
scheduleWithCron(ledScreen.getDeviceSn(), task, getProjectCronExpressions(ledScreen.getProjectId()));
|
||||
}
|
||||
|
||||
// 调度任务
|
||||
scheduler.scheduleAtFixedRate(task, 0, ledScreen.getFrequency(), TimeUnit.SECONDS);
|
||||
private void scheduleWithCron(String deviceSn, Runnable task, List<String> cronExpressions) {
|
||||
Map<String, ScheduledFuture<?>> existingTasks = scheduledTasks.get(deviceSn);
|
||||
if (existingTasks != null) {
|
||||
for (ScheduledFuture<?> existingTask : existingTasks.values()) {
|
||||
existingTask.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, ScheduledFuture<?>> newTasks = new HashMap<>();
|
||||
|
||||
for (String cronExpression : cronExpressions) {
|
||||
if (StringUtils.isNotBlank(cronExpression)) {
|
||||
try {
|
||||
ScheduledFuture<?> scheduledTask = cronScheduler.schedule(task, new CronTrigger(cronExpression));
|
||||
newTasks.put(cronExpression, scheduledTask);
|
||||
logger.info("为LED屏 {} 创建调度任务,Cron表达式: {}", deviceSn, cronExpression);
|
||||
} catch (Exception e) {
|
||||
logger.error("为LED屏 {} 创建调度任务失败,Cron表达式: {}, 错误: {}", deviceSn, cronExpression, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scheduledTasks.put(deviceSn, newTasks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -112,64 +154,74 @@ public class LedMainApplication {
|
|||
return new String[]{"image1.jpg", "image2.jpg", "image3.jpg"}; // 实际使用时应从配置或数据库获取
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动检测设备在线状态,通过ping命令验证
|
||||
*/
|
||||
private boolean ledIsOnline(String deviceSn) {
|
||||
try {
|
||||
if(ledServerService.getServer()==null){
|
||||
return false;
|
||||
}
|
||||
return ledServerService.getServer().getOnlineScreenByNetId(deviceSn) != null;
|
||||
return ledDrawService.isConnected(deviceSn);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 定期刷新所有LED屏
|
||||
*/
|
||||
@Scheduled(fixedRate = 60000) // 每分钟执行一次
|
||||
@Scheduled(fixedRate = 60000)
|
||||
public void startPeriodicRefresh() {
|
||||
try {
|
||||
List<SysLedscreen> ledScreens = ledScreenService.getAllLedScreens();
|
||||
|
||||
for (SysLedscreen ledScreen : ledScreens) {
|
||||
// 检查设备的实际连接状态
|
||||
boolean isActuallyOnline = ledIsOnline(ledScreen.getDeviceSn());
|
||||
boolean wasOnline = ledScreen.isOnline();
|
||||
|
||||
// 如果在线状态改变,更新缓存和数据库
|
||||
if (isActuallyOnline != wasOnline) {
|
||||
ledScreen.setOnline(isActuallyOnline);
|
||||
ledScreenService.updateLedScreen(ledScreen);
|
||||
logger.info("LED屏 {} 在线状态已更新: {} -> {}",
|
||||
ledScreen.getDeviceSn(), wasOnline, isActuallyOnline);
|
||||
|
||||
if (!isActuallyOnline) {
|
||||
cancelScheduledTask(ledScreen.getDeviceSn());
|
||||
} else {
|
||||
createRefreshTask(ledScreen);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已有对应的任务
|
||||
if (!refreshTasks.containsKey(ledScreen.getDeviceSn())) {
|
||||
// 如果没有对应的任务,则创建新任务
|
||||
createRefreshTask(ledScreen);
|
||||
} else {
|
||||
// 如果已有任务,检查LED屏配置是否有变化,如果有变化则更新任务
|
||||
// 这样可以确保任务使用最新的配置,包括在线状态
|
||||
SysLedscreen existingScreen = ledScreenService.getLedScreenByNetId(ledScreen.getDeviceSn());
|
||||
if (existingScreen != null) {
|
||||
// 检查频率是否变化,如果变化则重新创建任务
|
||||
if (existingScreen.getFrequency() != ledScreen.getFrequency()) {
|
||||
// 重新创建任务以使用新的频率设置
|
||||
Runnable oldTask = refreshTasks.remove(ledScreen.getDeviceSn());
|
||||
if (oldTask != null) {
|
||||
logger.info("更新LED屏任务: {}", ledScreen.getDeviceSn());
|
||||
}
|
||||
createRefreshTask(ledScreen);
|
||||
}
|
||||
}
|
||||
// 主动检测设备状态,如果设备已连接但ping失败,则认为设备离线
|
||||
if (ledDrawService.isConnected(ledScreen.getDeviceSn()) && !isActuallyOnline) {
|
||||
// 从连接管理器移除屏幕
|
||||
ledDrawService.removeConnectedScreen(ledScreen.getDeviceSn());
|
||||
logger.info("从连接管理器移除离线设备: {}", ledScreen.getDeviceSn());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("执行定期刷新时出错: {}", e.getMessage(), e);
|
||||
logger.error("定期刷新LED屏状态时出错", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 600000)
|
||||
public void refreshLedTimerData() {
|
||||
try {
|
||||
loadLedRefreshTimer();
|
||||
logger.info("已刷新LED定时器数据");
|
||||
} catch (Exception e) {
|
||||
logger.error("刷新LED定时器数据时出错: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelScheduledTask(String deviceSn) {
|
||||
Map<String, ScheduledFuture<?>> cronTasks = scheduledTasks.remove(deviceSn);
|
||||
if (cronTasks != null) {
|
||||
for (ScheduledFuture<?> cronTask : cronTasks.values()) {
|
||||
if (cronTask != null) {
|
||||
cronTask.cancel(false);
|
||||
}
|
||||
}
|
||||
logger.info("已取消LED屏 {} 的所有调度任务", deviceSn);
|
||||
}
|
||||
refreshTasks.remove(deviceSn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据NetID获取LED屏信息
|
||||
*/
|
||||
|
|
@ -177,24 +229,16 @@ public class LedMainApplication {
|
|||
return ledScreenService.getLedScreenByNetId(netId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新LED屏配置
|
||||
*/
|
||||
public void updateLedScreen(SysLedscreen ledScreen) {
|
||||
// 先取消旧的刷新任务
|
||||
Runnable oldTask = refreshTasks.remove(ledScreen.getDeviceSn());
|
||||
if (oldTask != null) {
|
||||
// 注意:这里无法直接取消已提交的任务,但会移除引用
|
||||
logger.info("移除旧的刷新任务: {}", ledScreen.getDeviceSn());
|
||||
}
|
||||
cancelScheduledTask(ledScreen.getDeviceSn());
|
||||
|
||||
// 更新配置
|
||||
ledScreenService.updateLedScreen(ledScreen);
|
||||
|
||||
// 创建新的刷新任务
|
||||
createRefreshTask(ledScreen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取服务器运行状态
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import onbon.bx06.area.page.TextBxPage;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.awt.*;
|
||||
|
|
@ -81,7 +82,6 @@ public class LedDrawService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 为Bx6M控制器创建节目
|
||||
*/
|
||||
|
|
@ -93,7 +93,8 @@ public class LedDrawService {
|
|||
16, profile);
|
||||
|
||||
// 如果没有图片,添加文本页
|
||||
String text ="研筑科技LED屏内容 - " + ledScreen.getTitle()+ DateUtil.now();
|
||||
String text ="X研筑科技LED屏内容 - " + ledScreen.getTitle()+ DateUtil.now();
|
||||
logger.info("LED-->{},sn={}",text,ledScreen.getDeviceSn());
|
||||
TextBxPage textPage = new TextBxPage(text, new Font("宋体", Font.PLAIN, 12));//+当前时间
|
||||
|
||||
textPage.setForeground(Color.WHITE);
|
||||
|
|
@ -127,7 +128,6 @@ public class LedDrawService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 添加已连接的屏幕到管理器
|
||||
*/
|
||||
|
|
@ -159,4 +159,47 @@ public class LedDrawService {
|
|||
public boolean isConnected(String deviceSn) {
|
||||
return connectedScreens.containsKey(deviceSn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定设备的连接屏幕对象
|
||||
* @param deviceSn 设备序列号
|
||||
* @return Bx6GScreen对象,如果未连接则返回null
|
||||
*/
|
||||
public Bx6GScreen getConnectedScreen(String deviceSn) {
|
||||
return connectedScreens.get(deviceSn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定期检测已连接设备的在线状态,如果ping不通则认为设备已离线
|
||||
*/
|
||||
@Scheduled(fixedRate = 30000) // 每30秒检测一次
|
||||
public void checkConnectedDevicesStatus() {
|
||||
for (Map.Entry<String, Bx6GScreen> entry : connectedScreens.entrySet()) {
|
||||
String deviceSn = entry.getKey();
|
||||
Bx6GScreen screen = entry.getValue();
|
||||
|
||||
try {
|
||||
// 尝试ping设备,检测其是否仍然在线
|
||||
Bx6GScreen.Result<?> result = screen.ping();
|
||||
if (result == null || !result.isOK()) {
|
||||
logger.warn("设备 {} ping失败,认为已离线,将从连接管理器中移除", deviceSn);
|
||||
// 设备离线,从连接管理器中移除
|
||||
connectedScreens.remove(deviceSn);
|
||||
logger.info("已从连接管理器移除离线设备: {}", deviceSn);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("检测设备 {} 在线状态时出错: {}, 将从连接管理器中移除", deviceSn, e.getMessage());
|
||||
// 发生异常,从连接管理器中移除设备
|
||||
connectedScreens.remove(deviceSn);
|
||||
logger.info("已从连接管理器移除异常设备: {}", deviceSn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已连接的设备SN列表
|
||||
*/
|
||||
public java.util.Set<String> getAllConnectedDeviceSns() {
|
||||
return new java.util.HashSet<>(connectedScreens.keySet());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.yanzhu.led.service;
|
||||
|
||||
import com.yanzhu.system.domain.SysLedscreen;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* LED屏离线检测服务
|
||||
* 定期检测设备状态,当设备离线时更新数据库状态
|
||||
*/
|
||||
@Service
|
||||
public class LedOfflineDetectionService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LedOfflineDetectionService.class);
|
||||
|
||||
@Autowired
|
||||
private ILedScreenService ledScreenService;
|
||||
|
||||
@Autowired
|
||||
private LedDrawService ledDrawService;
|
||||
|
||||
/**
|
||||
* 定期检查连接状态,检测离线设备
|
||||
* 比较数据库中的在线设备与连接管理器中的设备,更新不一致的状态
|
||||
*/
|
||||
@Scheduled(fixedRate = 45000) // 每45秒检查一次
|
||||
public void detectOfflineDevices() {
|
||||
try {
|
||||
// 获取数据库中所有标记为在线的设备
|
||||
java.util.List<SysLedscreen> onlineScreens = ledScreenService.getAllLedScreens().stream()
|
||||
.filter(SysLedscreen::isOnline)
|
||||
.collect(Collectors.toList()) ;
|
||||
|
||||
// 获取连接管理器中的所有设备
|
||||
Set<String> connectedDeviceSns = ledDrawService.getAllConnectedDeviceSns();
|
||||
|
||||
// 检查数据库中标记为在线但实际未连接的设备
|
||||
for (SysLedscreen screen : onlineScreens) {
|
||||
if (!connectedDeviceSns.contains(screen.getDeviceSn())) {
|
||||
// 设备在数据库中标记为在线,但不在连接管理器中,说明已离线
|
||||
logger.info("检测到设备 {} 已离线,更新数据库状态", screen.getDeviceSn());
|
||||
|
||||
// 更新数据库状态
|
||||
screen.setOnline(false);
|
||||
ledScreenService.updateLedScreen(screen);
|
||||
logger.info("LED屏 {} 状态更新为离线", screen.getDeviceSn());
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("离线设备检测完成,当前在线设备数: {}", connectedDeviceSns.size());
|
||||
} catch (Exception e) {
|
||||
logger.error("检测离线设备时出错", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -142,7 +142,6 @@ public class UniLedDrawer extends BaseDrawer{
|
|||
SysLedscreen led=new SysLedscreen();
|
||||
led.setWidth(230l);
|
||||
led.setHeight(128l);
|
||||
led.setFrequency(180l);
|
||||
led.setDeviceSn("B06M3P2501160132");
|
||||
led.setTitle("abc");
|
||||
LedProperties ledProperties=new LedProperties();
|
||||
|
|
|
|||
|
|
@ -49,14 +49,6 @@
|
|||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="频率(秒)" prop="frequency">
|
||||
<el-input
|
||||
v-model="queryParams.frequency"
|
||||
placeholder="请输入频率(秒)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="queryParams.title"
|
||||
|
|
@ -146,7 +138,6 @@
|
|||
<el-table-column label="设备序列号" align="center" prop="deviceSn" />
|
||||
<el-table-column label="宽" align="center" prop="width" />
|
||||
<el-table-column label="高" align="center" prop="height" />
|
||||
<el-table-column label="频率(秒)" align="center" prop="frequency" />
|
||||
<el-table-column label="LED绘图模式" align="center" prop="drawType" />
|
||||
<el-table-column label="标题" align="center" prop="title" />
|
||||
<el-table-column label="启停1-启用 0-停用" align="center" prop="enabled" />
|
||||
|
|
@ -190,9 +181,6 @@
|
|||
<el-form-item label="高" prop="height">
|
||||
<el-input v-model="form.height" placeholder="请输入高" />
|
||||
</el-form-item>
|
||||
<el-form-item label="频率(秒)" prop="frequency">
|
||||
<el-input v-model="form.frequency" placeholder="请输入频率(秒)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||
</el-form-item>
|
||||
|
|
@ -245,7 +233,6 @@ const data = reactive({
|
|||
deviceSn: null,
|
||||
width: null,
|
||||
height: null,
|
||||
frequency: null,
|
||||
drawType: null,
|
||||
title: null,
|
||||
enabled: null,
|
||||
|
|
@ -284,7 +271,6 @@ function reset() {
|
|||
deviceSn: null,
|
||||
width: null,
|
||||
height: null,
|
||||
frequency: null,
|
||||
drawType: null,
|
||||
title: null,
|
||||
enabled: null,
|
||||
|
|
|
|||
|
|
@ -65,11 +65,6 @@
|
|||
{{ row.width }} × {{ row.height }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新频率" align="center" prop="frequency" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row.frequency }}秒
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.online ? 'success' : 'warning'">
|
||||
|
|
@ -146,12 +141,6 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="更新频率" prop="frequency">
|
||||
<el-input v-model="form.frequency" type="number" placeholder="请输入更新频率(秒)"
|
||||
:disabled="dialogType === 'view'" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="绘制模式" prop="drawType">
|
||||
<el-input v-model="form.drawType" type="number" placeholder="请输入绘制模式"
|
||||
|
|
@ -254,7 +243,6 @@ const form = ref({
|
|||
deviceSn: undefined,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
frequency: undefined,
|
||||
drawType: undefined,
|
||||
title: undefined,
|
||||
enabled: 1,
|
||||
|
|
@ -275,9 +263,6 @@ const rules = ref({
|
|||
],
|
||||
height: [
|
||||
{ required: true, message: "屏幕高度不能为空", trigger: "blur" }
|
||||
],
|
||||
frequency: [
|
||||
{ required: true, message: "更新频率不能为空", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue