From b98d9f1dc6d2f78dfe695a0fa8e1000a5c0ff620 Mon Sep 17 00:00:00 2001 From: guo Date: Mon, 18 Mar 2024 17:34:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=AE=89=E5=85=A8=E5=B8=BDta?= =?UTF-8?q?sk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zhgd/xmgl/config/SafetyHatWSClient.java | 154 ++++++++++++++++++ .../java/com/zhgd/xmgl/enums/ParamEnum.java | 69 +++++++- .../com/zhgd/xmgl/task/SafetyHatTask.java | 93 +++++++++++ 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java create mode 100644 src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java diff --git a/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java b/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java new file mode 100644 index 000000000..991fdf8fa --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/config/SafetyHatWSClient.java @@ -0,0 +1,154 @@ +package com.zhgd.xmgl.config; + +import cn.hutool.core.text.CharSequenceUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zhgd.jeecg.common.util.SpringContextUtils; +import com.zhgd.xmgl.enums.ParamEnum; +import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatAlarm; +import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatData; +import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatDev; +import com.zhgd.xmgl.modules.safetyhat.mapper.SafetyHatAlarmMapper; +import com.zhgd.xmgl.modules.safetyhat.mapper.SafetyHatDataMapper; +import com.zhgd.xmgl.modules.safetyhat.mapper.SafetyHatDevMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import java.util.Date; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + + +@ClientEndpoint +@Slf4j +@Component +public class SafetyHatWSClient { + public static final ConcurrentHashMap clientMap = new ConcurrentHashMap<>(); + private Session session; + private String id; + + @OnOpen + public void open(Session session) { + log.info("SafetyHatWSClient客户端:" + id + ",连接服务端..."); + this.session = session; + } + + /** + * 插入安全帽实时数据和报警数据 + * + * @param message + */ + @OnMessage + public void onMessage(String message) { + if (CharSequenceUtil.isNotBlank(message)) { + log.info("SafetyHatWSClient报文:" + message); + JSONObject jo = JSON.parseObject(message); + String cmd = jo.getString("cmd"); + if (Objects.equals(cmd, "ma_login")) { + //先登录 + Boolean status = jo.getBoolean("status"); + if (status != null && status) { + //登录成功,发生心跳获取实时数据 + this.send("{\"act\":\"ma_get_active_devices\"}"); + } + } else if (Objects.equals(cmd, "ma_get_active_devices")) { + //插入实时数据 + Boolean status = jo.getBoolean("status"); + if (status != null && status) { + JSONArray jaData = jo.getJSONArray("data"); + if (jaData.size() != 0) { + for (int i = 0; i < jaData.size(); i++) { + JSONObject joData = jaData.getJSONObject(i); + JSONObject joUserInfo = joData.getJSONObject("user_info"); + if (joUserInfo != null) { + String deviceId = joUserInfo.getString("device_id"); + SafetyHatDev dev = SpringContextUtils.getBean(SafetyHatDevMapper.class).selectOne(new LambdaQueryWrapper() + .eq(SafetyHatDev::getDevSn, deviceId)); + if (dev != null) { + JSONObject joLocationInfo = joData.getJSONObject("location_info"); + if (joLocationInfo != null) { + //纬度(坐标系:高德地图 GCJ-02) + Double xPoint = joLocationInfo.getDouble("x_point"); + Double yPoint = joLocationInfo.getDouble("y_point"); + Long ctime = joLocationInfo.getLong("ctime"); + SafetyHatData data = new SafetyHatData(); + data.setWorkerInfoId(dev.getWorkerInfoId()); + data.setDevSn(dev.getDevSn()); + data.setLatitude(xPoint); + data.setLongitude(yPoint); + data.setUploadTime(new Date(ctime * 1000L)); + data.setProjectSn(dev.getProjectSn()); + SpringContextUtils.getBean(SafetyHatDataMapper.class).insert(data); + } + } + } + } + } + } + } else if (Objects.equals(cmd, "server_push_sos")) { + //接受报警数据 + JSONObject joData = jo.getJSONObject("data"); + if (joData != null) { + String deviceId = joData.getString("device_id"); + SafetyHatDev dev = SpringContextUtils.getBean(SafetyHatDevMapper.class).selectOne(new LambdaQueryWrapper() + .eq(SafetyHatDev::getDevSn, deviceId)); + if (dev != null) { + //纬度(坐标系:高德地图 GCJ-02) + Double xPoint = joData.getDouble("x_point"); + Double yPoint = joData.getDouble("y_point"); + Long ctime = joData.getLong("c_time"); + Integer sosType = joData.getInteger("sos_type"); + String str = ParamEnum.getStr(ParamEnum.SafetyHatAlarmAlarmType.values(), sosType); + SafetyHatAlarm alarm = new SafetyHatAlarm(); + alarm.setWorkerInfoId(dev.getWorkerInfoId()); + alarm.setDevSn(dev.getDevSn()); + alarm.setAlarmTime(new Date(ctime * 1000L)); + alarm.setAlarmInfo(str); + alarm.setProjectSn(dev.getProjectSn()); + alarm.setAlarmType(sosType); + alarm.setLatitude(yPoint); + alarm.setLongitude(xPoint); + SpringContextUtils.getBean(SafetyHatAlarmMapper.class).insert(alarm); + } + } + } + } + } + + + @OnClose + public void onClose() { + log.info("SafetyHatWSClient客户端:" + id + ",服务端服务端断开连接"); + } + + /** + * @param session + * @param e + */ + @OnError + public void onError(Session session, Throwable e) { + log.error("SafetyHatWSClient连接服务端错误:" + this.id, e); + } + + /** + * 发送客户端消息到服务端 + * + * @param message 消息内容 + */ + public void send(String message) { + + this.session.getAsyncRemote().sendText(message); + + } + + public SafetyHatWSClient(String id) { + this.id = id; + } + + public SafetyHatWSClient() { + } + +} diff --git a/src/main/java/com/zhgd/xmgl/enums/ParamEnum.java b/src/main/java/com/zhgd/xmgl/enums/ParamEnum.java index ef8edc524..dc1c88e46 100644 --- a/src/main/java/com/zhgd/xmgl/enums/ParamEnum.java +++ b/src/main/java/com/zhgd/xmgl/enums/ParamEnum.java @@ -1,7 +1,6 @@ package com.zhgd.xmgl.enums; import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.models.auth.In; import lombok.experimental.UtilityClass; import java.util.Arrays; @@ -659,5 +658,73 @@ public class ParamEnum { } } + /** + * 安全帽报警, + * 1 脱帽报警 + * 2 围栏报警1 离开工作区域 + * 3 温度报警 + * 4 跌落(撞击)报警 + * 5 围栏报警2 进入禁区 + * 6 静默报警 + * 7 SOS报警 + * 11 近电报警 + * 12 登高报警 + * 17 进入蓝牙信标报警 + * 18 离开蓝牙信标报警 + * 13、15 氧气报警 + * 14、16 甲烷报警 + * 19 一氧化碳浓度 + * 20 体温报警 + * 21 心率报警 + * 22 血压报警 + */ + @JsonFormat(shape = JsonFormat.Shape.OBJECT) + public enum SafetyHatAlarmAlarmType implements BaseEnum { + TMBJ(1, "脱帽报警"), + WLBJ1(2, "围栏报警1 离开工作区域"), + WDBJ(3, "温度报警"), + DLZJBJ(4, "跌落(撞击)报警"), + WLBJ2(5, "围栏报警2 进入禁区"), + JMBJ(6, "静默报警"), + SOSBJ(7, "SOS报警"), + JDBJ(11, "近电报警"), + DGBJ(12, "登高报警"), + JRLYXBBJ(17, "进入蓝牙信标报警"), + LKLYXBBJ(18, "离开蓝牙信标报警"), + YQBJ1(13, "氧气报警"), + YQBJ2(15, "氧气报警"), + JWBJ1(14, "甲烷报警"), + JWBJ2(16, "甲烷报警"), + YYHTND(19, "一氧化碳浓度"), + TWBJ(20, "体温报警"), + XLBJ(21, "心率报警"), + XYBJ(22, "血压报警"), + ; + + SafetyHatAlarmAlarmType(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + private Integer value; + private String desc; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + } + } diff --git a/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java b/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java new file mode 100644 index 000000000..f14542648 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/task/SafetyHatTask.java @@ -0,0 +1,93 @@ +package com.zhgd.xmgl.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.text.CharSequenceUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.zhgd.xmgl.config.SafetyHatWSClient; +import com.zhgd.xmgl.modules.project.entity.Project; +import com.zhgd.xmgl.modules.project.service.IProjectService; +import com.zhgd.xmgl.util.RundeSafeyHatUtils; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.core.SchedulerLock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.websocket.DeploymentException; +import javax.websocket.WebSocketContainer; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +/** + * 智能安全帽task + */ +@Slf4j +@RestController +@RequestMapping("xmgl/task") +public class SafetyHatTask { + @Autowired + IProjectService projectService; + @Autowired + WebSocketContainer webSocketContainer; + @Autowired + SafetyHatWSClient safetyHatWSClient; + + /** + * 获取安全帽最新数据(30秒内的心跳) + */ + @SchedulerLock(name = "getHelmetData", lockAtMostFor = 1000 * 60 * 60, lockAtLeastFor = 1000 * 10) + @Scheduled(cron = "0/10 * * * * ?") + @RequestMapping("getHelmetData") + public void getHelmetData() { + try { + log.info("定时获取安全帽最新数据(30秒内的心跳)"); + List projectList = projectService.list(Wrappers.lambdaQuery().ne(Project::getHelmetUser, "").ne(Project::getHelmetPassword, "")); + if (CollUtil.isNotEmpty(projectList)) { + for (Project project : projectList) { + SafetyHatWSClient client = SafetyHatWSClient.clientMap.get(project.getHelmetUser()); + try { + if (client == null) { + connect(project); + } else { + client.send("{\"act\":\"ma_get_active_devices\"}"); + } + } catch (IllegalStateException e) { + log.info("异常重连:{}", e.getMessage()); + connect(project); + } + } + } + } catch (Exception e) { + log.error("err:", e); + } + } + + /** + * 连接ws和登录 + * + * @param project + * @throws DeploymentException + * @throws IOException + * @throws URISyntaxException + */ + private SafetyHatWSClient connect(Project project) throws DeploymentException, IOException, URISyntaxException { + SafetyHatWSClient client = new SafetyHatWSClient(); + webSocketContainer.connectToServer(client, new URI("wss://caps.runde.pro/wss")); + JSONObject token = RundeSafeyHatUtils.getToken(project.getHelmetUser(), project.getHelmetPassword()); + if (token != null && CharSequenceUtil.isNotBlank(token.getString("session_id"))) { + String sessionId = token.getString("session_id"); + project.setRundeToken(sessionId); + String message = "{\"act\":\"ma_login\",\"user_name\":\"" + project.getHelmetUser() + "\",\"access_token\":\"" + sessionId + "\"}"; + client.send(message); + log.info("安全帽用户:{},ms:{}", project.getHelmetUser(), message); + SafetyHatWSClient.clientMap.put(project.getHelmetUser(), client); + } + return client; + } + + +}