19 Commits

Author SHA1 Message Date
1111e03bf4 修复bug2 2026-03-20 16:37:32 +08:00
83752b2f11 修复bug 2026-03-19 13:25:11 +08:00
f37cb405cc 提交代码9 2026-03-19 09:49:08 +08:00
cc2713618a 提交代码8 2026-03-18 15:29:42 +08:00
47d40cf9d2 提交代码7 2026-03-06 17:58:39 +08:00
83b97841ef 提交代码6 2026-03-05 17:49:55 +08:00
9d84265f57 Merge remote-tracking branch 'origin/6170' into 6170 2026-03-02 16:38:01 +08:00
fa5dfab939 2.4G设备上报技术方案 2026-03-02 16:37:50 +08:00
5fb71dd092 提交代码5 2026-03-02 15:35:19 +08:00
1ce87aaec5 Merge branch '6170' of http://47.107.152.87:3000/dyf/fys-Multi-tenant into 6170 2026-03-02 14:31:46 +08:00
4f3e7b0ed0 regis 2026-03-02 14:31:40 +08:00
b75b7ef431 提交代码4 2026-03-02 13:55:21 +08:00
c9cad751f0 提交代码3 2026-03-02 13:45:30 +08:00
34841c8704 提交代码2 2026-03-02 11:17:46 +08:00
20ac6b0baa bug修改4 2026-02-27 18:34:21 +08:00
4d5292cebc bug修改3 2026-02-27 18:31:03 +08:00
7a35baa8f0 bug修改2 2026-02-27 17:42:23 +08:00
dbb7076b50 Merge remote-tracking branch 'origin/6170' into 6170 2026-02-27 15:34:22 +08:00
15c85d4c62 bug修改 2026-02-27 15:34:15 +08:00
50 changed files with 1476 additions and 736 deletions

View File

@ -1,17 +1,17 @@
package com.fuyuanshen.app.controller; package com.fuyuanshen.app.controller;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.dto.AppAudioFileDto; import com.fuyuanshen.app.domain.dto.AppAudioFileDto;
import com.fuyuanshen.app.domain.dto.AppFileDto; import com.fuyuanshen.app.domain.dto.AppFileDto;
import com.fuyuanshen.app.domain.dto.AppFileRenameDto; import com.fuyuanshen.app.domain.dto.AppFileRenameDto;
import com.fuyuanshen.app.domain.dto.TextToSpeechRequest; import com.fuyuanshen.app.domain.dto.TextToSpeechRequest;
import com.fuyuanshen.app.domain.vo.AppFileVo;
import com.fuyuanshen.app.service.AudioProcessService; import com.fuyuanshen.app.service.AudioProcessService;
import com.fuyuanshen.app.service.VideoProcessService; import com.fuyuanshen.app.service.VideoProcessService;
import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.vo.AppFileVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -81,6 +81,7 @@ public class AppVideoController extends BaseController {
@PostMapping("/uploadAudioToOss") @PostMapping("/uploadAudioToOss")
public R<String> uploadAudioToOss(@ModelAttribute AppAudioFileDto bo) { public R<String> uploadAudioToOss(@ModelAttribute AppAudioFileDto bo) {
try { try {
bo.setSource("app");
String result = audioProcessService.uploadAudioToOss(bo); String result = audioProcessService.uploadAudioToOss(bo);
return R.ok(result); return R.ok(result);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -101,11 +102,15 @@ public class AppVideoController extends BaseController {
if (request.getDeviceId() == null) { if (request.getDeviceId() == null) {
return R.fail("设备ID不能为空"); return R.fail("设备ID不能为空");
} }
if (StringUtils.isBlank(request.getText())) {
return R.fail("文本不能为空");
}
String result = audioProcessService.textToSpeech( String result = audioProcessService.textToSpeech(
request.getDeviceId(), request.getDeviceId(),
request.getText(), request.getText(),
request.getFileSuffix() request.getFileSuffix(),
"app"
); );
return R.ok(result); return R.ok(result);
} catch (Exception e) { } catch (Exception e) {
@ -119,7 +124,7 @@ public class AppVideoController extends BaseController {
*/ */
@GetMapping("/queryAudioFileList") @GetMapping("/queryAudioFileList")
public R<List<AppFileVo>> queryAudioFileList(Long deviceId) { public R<List<AppFileVo>> queryAudioFileList(Long deviceId) {
return R.ok(audioProcessService.queryAudioFileList(deviceId)); return R.ok(audioProcessService.queryAudioFileList(deviceId,"app"));
} }
/** /**

View File

@ -3,15 +3,13 @@ package com.fuyuanshen.app.controller.device.bjq;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo; import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import com.fuyuanshen.web.service.device.DeviceHBY100JBizService; import com.fuyuanshen.web.service.device.DeviceHBY100JBizService;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
/** /**
* HBY100J设备控制类 * HBY100J设备控制类
*/ */
@ -66,20 +64,6 @@ public class AppDeviceHBY100JController extends BaseController {
} }
@Data
public static class HBY100JVoiceBroadcastDto {
/**
* 设备ID
*/
Long deviceId;
/**
* 0 关闭, 1开启
*/
private Integer voiceBroadcast;
}
/** /**
* 爆闪模式 * 爆闪模式
*/ */
@ -117,100 +101,4 @@ public class AppDeviceHBY100JController extends BaseController {
deviceHBY100JBizService.updateVolume(params); deviceHBY100JBizService.updateVolume(params);
return R.ok(); return R.ok();
} }
@Data
public static class HBY100JUpdateVoiceDto {
private Long id;
}
@Data
public static class HBY100JForceAlarmActivationDto {
/**
* 设备ID
*/
List<Long> deviceIds;
/**
* 0 关闭, 1开启
*/
private Integer voiceStrobeAlarm;
/**
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7语音
*/
private Integer mode;
}
@Data
public static class HBY100JUpdateVolumeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "volume": 1-100(app端可根据需求把40作为低音量, 70作为中音量100作为高音量)
*/
private Integer volume;
}
@Data
public static class HBY100JStrobeFrequencyDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "frequency": 1-12
*/
private Integer frequency;
}
@Data
public static class HBY100JLightAdjustmentDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 亮度值0-100
*/
private Integer brightness;
// /**
// * 红色LED亮度值0-100
// */
// private Integer red;
//
// /**
// * 蓝色LED亮度值0-100
// */
// private Integer blue;
//
// /**
// * 黄色LED亮度值0-100
// */
// private Integer yellow;
}
@Data
public static class HBY100JStrobeModeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 0 关闭 1 开启
*/
private Integer enable;
/**
* 0 红色爆闪1 蓝色爆闪2 黄色爆闪3红色顺时针旋转爆闪4黄色顺时针旋转爆闪5红蓝顺时针旋转爆闪6 红蓝交替爆闪
*/
private Integer mode;
}
} }

View File

@ -14,4 +14,8 @@ public class AppAudioFileDto {
private MultipartFile file; private MultipartFile file;
/**
* 数据来源 1:app 2:web 3:其他
*/
private String source;
} }

View File

@ -1,15 +1,19 @@
package com.fuyuanshen.app.service; package com.fuyuanshen.app.service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fuyuanshen.app.domain.AppBusinessFile; import com.fuyuanshen.app.domain.bo.AppDeviceBindRecordBo;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.dto.AppAudioFileDto; import com.fuyuanshen.app.domain.dto.AppAudioFileDto;
import com.fuyuanshen.app.domain.dto.AppFileRenameDto; import com.fuyuanshen.app.domain.dto.AppFileRenameDto;
import com.fuyuanshen.app.domain.vo.AppFileVo; import com.fuyuanshen.app.domain.vo.AppDeviceBindRecordVo;
import com.fuyuanshen.app.http.HttpTtsClient; import com.fuyuanshen.app.http.HttpTtsClient;
import com.fuyuanshen.app.mapper.AppBusinessFileMapper;
import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.AppBusinessFile;
import com.fuyuanshen.equipment.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.equipment.domain.vo.AppFileVo;
import com.fuyuanshen.equipment.mapper.AppBusinessFileMapper;
import com.fuyuanshen.equipment.service.IAppBusinessFileService;
import com.fuyuanshen.equipment.utils.AlibabaTTSUtil; import com.fuyuanshen.equipment.utils.AlibabaTTSUtil;
import com.fuyuanshen.equipment.utils.AudioProcessUtil; import com.fuyuanshen.equipment.utils.AudioProcessUtil;
import com.fuyuanshen.equipment.utils.FileHashUtil; import com.fuyuanshen.equipment.utils.FileHashUtil;
@ -20,6 +24,7 @@ import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.service.ISysOssService; import com.fuyuanshen.system.service.ISysOssService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -62,6 +67,17 @@ public class AudioProcessService {
private final ISysOssService ossService; private final ISysOssService ossService;
private final IAppBusinessFileService appBusinessFileService; private final IAppBusinessFileService appBusinessFileService;
private final AppBusinessFileMapper appBusinessFileMapper; private final AppBusinessFileMapper appBusinessFileMapper;
private final IAppDeviceBindRecordService appDeviceBindRecordService;
// String accessKeyId = "LTAI5t66moCkhNC32TDJ5ReP";
// String accessKeySecret = "2F3sdoBJ08bYvJcuDgSkLnJwGXsvYH";
// String appKey = "lbGuq5K5bEH4uxmT";
@Value("${alibaba.tts.appKey}")
private String appKey;
@Value("${alibaba.tts.akId}")
private String accessKeyId;
@Value("${alibaba.tts.akSecret}")
private String accessKeySecret;
/** /**
* 处理上传的音频文件 * 处理上传的音频文件
@ -372,7 +388,8 @@ public class AudioProcessService {
appBusinessFileBo.setFileId(upload.getOssId()); appBusinessFileBo.setFileId(upload.getOssId());
appBusinessFileBo.setBusinessId(bo.getDeviceId()); appBusinessFileBo.setBusinessId(bo.getDeviceId());
appBusinessFileBo.setFileType(3L); appBusinessFileBo.setFileType(3L);
appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId()); Long userId = getUserId(bo.getSource(), bo.getDeviceId());
appBusinessFileBo.setCreateBy(userId);
savedPath = saveByteArrayToFile(file.getInputStream(), generateRandomFileName(fileSuffix)); savedPath = saveByteArrayToFile(file.getInputStream(), generateRandomFileName(fileSuffix));
if (savedPath != null) { if (savedPath != null) {
log.info("MP3文件已保存: {}", savedPath); log.info("MP3文件已保存: {}", savedPath);
@ -396,6 +413,21 @@ public class AudioProcessService {
return null; return null;
} }
private Long getUserId(String source,Long deviceId){
Long userId = null;
if("app".equals( source)){
userId = AppLoginHelper.getUserId();
} else if ("web".equals( source)){
AppDeviceBindRecordBo appDeviceBindRecordBo = new AppDeviceBindRecordBo();
appDeviceBindRecordBo.setDeviceId(deviceId);
appDeviceBindRecordBo.setCommunicationMode(0);
List<AppDeviceBindRecordVo> appDeviceBindRecordVos = appDeviceBindRecordService.queryList(appDeviceBindRecordBo);
if (appDeviceBindRecordVos != null && !appDeviceBindRecordVos.isEmpty()){
userId = appDeviceBindRecordVos.get(0).getBindingUserId();
}
}
return userId;
}
/** /**
* 校验音频文件格式 * 校验音频文件格式
*/ */
@ -435,7 +467,7 @@ public class AudioProcessService {
return SUPPORTED_FORMATS.contains(ext); return SUPPORTED_FORMATS.contains(ext);
} }
public String textToSpeech(Long deviceId,String text, String fileSuffix) { public String textToSpeech(Long deviceId,String text, String fileSuffix,String source) {
//支持PCM/WAV/MP3格式 //支持PCM/WAV/MP3格式
if (fileSuffix == null || fileSuffix.isEmpty()) { if (fileSuffix == null || fileSuffix.isEmpty()) {
fileSuffix = "mp3"; fileSuffix = "mp3";
@ -448,9 +480,9 @@ public class AudioProcessService {
if (!contains) { if (!contains) {
throw new IllegalArgumentException("不支持的音频格式"); throw new IllegalArgumentException("不支持的音频格式");
} }
String accessKeyId = "LTAI5t66moCkhNC32TDJ5ReP"; // String accessKeyId = "LTAI5t66moCkhNC32TDJ5ReP";
String accessKeySecret = "2F3sdoBJ08bYvJcuDgSkLnJwGXsvYH"; // String accessKeySecret = "2F3sdoBJ08bYvJcuDgSkLnJwGXsvYH";
String appKey = "lbGuq5K5bEH4uxmT"; // String appKey = "lbGuq5K5bEH4uxmT";
String savedPath = null; String savedPath = null;
String savedMp3VolumePath = null; String savedMp3VolumePath = null;
try { try {
@ -458,7 +490,7 @@ public class AudioProcessService {
HttpTtsClient httpClient = new HttpTtsClient(accessKeyId, accessKeySecret, appKey); HttpTtsClient httpClient = new HttpTtsClient(accessKeyId, accessKeySecret, appKey);
// //
byte[] mp3Data = httpClient.synthesizeTextToMp3(text,fileSuffix); byte[] mp3Data = httpClient.synthesizeTextToMp3(text,fileSuffix);
// byte[] mp3Data = alibabaTTSUtil.synthesizeTextToMp3(text); // byte[] mp3Data = alibabaTTSUtil.synthesizeTextToMp3(text,fileSuffix);
AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo(); AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo();
@ -472,7 +504,7 @@ public class AudioProcessService {
String fileName = generateRandomFileName(fileSuffix); String fileName = generateRandomFileName(fileSuffix);
savedMp3VolumePath = directory + "/" + fileName; savedMp3VolumePath = directory + "/" + fileName;
log.info("保存MP3文件: {}", savedMp3VolumePath); log.info("保存MP3文件: {}", savedMp3VolumePath);
FfmpegVolumeUtil.increaseMp3Volume(savedPath, savedMp3VolumePath, 12); FfmpegVolumeUtil.increaseMp3Volume(savedPath, savedMp3VolumePath, 8);
File file = new File(savedMp3VolumePath); File file = new File(savedMp3VolumePath);
String fileHash = fileHashUtil.getFileHash(file,"SHA-256"); String fileHash = fileHashUtil.getFileHash(file,"SHA-256");
@ -486,7 +518,8 @@ public class AudioProcessService {
appBusinessFileBo.setFileId(upload.getOssId()); appBusinessFileBo.setFileId(upload.getOssId());
appBusinessFileBo.setBusinessId(deviceId); appBusinessFileBo.setBusinessId(deviceId);
appBusinessFileBo.setFileType(3L); appBusinessFileBo.setFileType(3L);
appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId()); Long userId = getUserId(source, deviceId);
appBusinessFileBo.setCreateBy(userId);
appBusinessFileService.insertByBo(appBusinessFileBo); appBusinessFileService.insertByBo(appBusinessFileBo);
if (upload != null) { if (upload != null) {
return upload.getUrl(); return upload.getUrl();
@ -531,18 +564,19 @@ public class AudioProcessService {
extension = "." + extension; extension = "." + extension;
} }
return timestamp + "_" + String.format("%04d", randomNum) + "_" + uuidPart + extension; return timestamp+extension;
} }
public List<AppFileVo> queryAudioFileList(Long deviceId) { public List<AppFileVo> queryAudioFileList(Long deviceId,String source) {
if(deviceId == null){ if(deviceId == null){
return null; return null;
} }
Long userId = getUserId(source, deviceId);
AppBusinessFileBo bo = new AppBusinessFileBo(); AppBusinessFileBo bo = new AppBusinessFileBo();
bo.setBusinessId(deviceId); bo.setBusinessId(deviceId);
bo.setCreateBy(userId);
bo.setFileType(3L); bo.setFileType(3L);
List<AppFileVo> appFileVos = appBusinessFileService.queryAppFileList(bo); return appBusinessFileService.queryAppFileList(bo);
return appFileVos;
} }
public R<Void> deleteAudioFile(Long fileId,Long deviceId) { public R<Void> deleteAudioFile(Long fileId,Long deviceId) {

View File

@ -1,68 +1,68 @@
package com.fuyuanshen.global.mqtt.config; //package com.fuyuanshen.global.mqtt.config;
//
//
import cn.hutool.core.lang.UUID; //import cn.hutool.core.lang.UUID;
import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler; //import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator; //import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel; //import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer; //import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory; //import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; //import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; //import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel; //import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler; //import org.springframework.messaging.MessageHandler;
//
//
@Configuration //@Configuration
@Slf4j //@Slf4j
public class NewMqttInboundConfiguration { //public class NewMqttInboundConfiguration {
@Autowired // @Autowired
private MqttPropertiesConfig mqttPropertiesConfig; // private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired // @Autowired
private MqttPahoClientFactory mqttPahoClientFactory; // private MqttPahoClientFactory mqttPahoClientFactory;
@Autowired // @Autowired
private NewReceiverMessageHandler receiverMessageHandler2; // private NewReceiverMessageHandler receiverMessageHandler2;
//消息通道 // //消息通道
@Bean // @Bean
public MessageChannel messageInboundChannel2(){ // public MessageChannel messageInboundChannel2(){
return new DirectChannel(); // return new DirectChannel();
} // }
//
/** // /**
* 配置入站适配器 // * 配置入站适配器
* 作用: 设置订阅主题,以及指定消息的通道 等相关属性 // * 作用: 设置订阅主题,以及指定消息的通道 等相关属性
* */ // * */
@Bean // @Bean
public MessageProducer messageProducer2(){ // public MessageProducer messageProducer2(){
// 生成一个不重复的随机数 // // 生成一个不重复的随机数
String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID(); // String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID();
String subTopic = mqttPropertiesConfig.getSubTopic2(); // String subTopic = mqttPropertiesConfig.getSubTopic2();
log.info("订阅主题:{}", subTopic); // log.info("订阅主题:{}", subTopic);
MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter( // MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
mqttPropertiesConfig.getUrl(), // mqttPropertiesConfig.getUrl(),
clientId, // clientId,
mqttPahoClientFactory, // mqttPahoClientFactory,
subTopic.split(",") // subTopic.split(",")
); // );
mqttPahoMessageDrivenChannelAdapter.setQos(1); // mqttPahoMessageDrivenChannelAdapter.setQos(1);
mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter()); // mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel2()); // mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel2());
return mqttPahoMessageDrivenChannelAdapter; // return mqttPahoMessageDrivenChannelAdapter;
} // }
/** 指定处理消息来自哪个通道 */ // /** 指定处理消息来自哪个通道 */
@Bean // @Bean
@ServiceActivator(inputChannel = "messageInboundChannel2") // @ServiceActivator(inputChannel = "messageInboundChannel2")
public MessageHandler messageHandler2(){ // public MessageHandler messageHandler2(){
return receiverMessageHandler2; // return receiverMessageHandler2;
} // }
//
// @Bean // // @Bean
// @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确 // // @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
// public MessageHandler deviceAlarmMessageHandler() { // // public MessageHandler deviceAlarmMessageHandler() {
// return new DeviceAlrmMessageHandler(); // // return new DeviceAlrmMessageHandler();
// } // // }
} //}

View File

@ -1,46 +1,46 @@
package com.fuyuanshen.global.mqtt.config; //package com.fuyuanshen.global.mqtt.config;
//
import cn.hutool.core.lang.UUID; //import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator; //import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel; //import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory; //import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; //import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel; //import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler; //import org.springframework.messaging.MessageHandler;
//
@Configuration //@Configuration
@Slf4j //@Slf4j
public class NewMqttOutboundConfiguration { //public class NewMqttOutboundConfiguration {
@Autowired // @Autowired
private MqttPropertiesConfig mqttPropertiesConfig; // private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired // @Autowired
private MqttPahoClientFactory mqttPahoClientFactory; // private MqttPahoClientFactory mqttPahoClientFactory;
//
// 消息通道 // // 消息通道
@Bean // @Bean
public MessageChannel mqttOutboundChannel2(){ // public MessageChannel mqttOutboundChannel2(){
return new DirectChannel(); // return new DirectChannel();
} // }
//
//
/** 配置出站消息处理器 */ // /** 配置出站消息处理器 */
@Bean // @Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel2") // 指定处理器针对哪个通道的消息进行处理 // @ServiceActivator(inputChannel = "mqttOutboundChannel2") // 指定处理器针对哪个通道的消息进行处理
public MessageHandler mqttOutboundMessageHandler2(){ // public MessageHandler mqttOutboundMessageHandler2(){
String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID(); // String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID();
MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler( // MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
mqttPropertiesConfig.getUrl(), // mqttPropertiesConfig.getUrl(),
clientId, // clientId,
mqttPahoClientFactory // mqttPahoClientFactory
); // );
mqttPahoMessageHandler.setDefaultQos(1); // mqttPahoMessageHandler.setDefaultQos(1);
mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2()); // mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2());
mqttPahoMessageHandler.setAsync(true); // mqttPahoMessageHandler.setAsync(true);
return mqttPahoMessageHandler; // return mqttPahoMessageHandler;
} // }
//
} //}

View File

@ -0,0 +1,69 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
//import com.fuyuanshen.global.mqtt.receiver.NewReceiverMessageHandler;
import com.fuyuanshen.global.mqtt.receiver.RegisEquipReceiverMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class RegisEquipMqttInboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
@Autowired
private RegisEquipReceiverMessageHandler receiverMessageHandler3;
//消息通道
@Bean
public MessageChannel messageInboundChannel3(){
return new DirectChannel();
}
/**
* 配置入站适配器
* 作用: 设置订阅主题,以及指定消息的通道 等相关属性
* */
@Bean
public MessageProducer messageProducer3(){
// 生成一个不重复的随机数
String clientId = mqttPropertiesConfig.getSubClientId() + "_" + UUID.fastUUID();
String subTopic = mqttPropertiesConfig.getSubTopic2();
log.info("订阅主题:{}", subTopic);
MqttPahoMessageDrivenChannelAdapter mqttPahoMessageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory,
subTopic.split(",")
);
mqttPahoMessageDrivenChannelAdapter.setQos(1);
mqttPahoMessageDrivenChannelAdapter.setConverter(new DefaultPahoMessageConverter());
mqttPahoMessageDrivenChannelAdapter.setOutputChannel(messageInboundChannel3());
return mqttPahoMessageDrivenChannelAdapter;
}
/** 指定处理消息来自哪个通道 */
@Bean
@ServiceActivator(inputChannel = "messageInboundChannel3")
public MessageHandler messageHandler3(){
return receiverMessageHandler3;
}
// @Bean
// @ServiceActivator(inputChannel = "messageInboundChannel") // 确保通道名称正确
// public MessageHandler deviceAlarmMessageHandler() {
// return new DeviceAlrmMessageHandler();
// }
}

View File

@ -0,0 +1,46 @@
package com.fuyuanshen.global.mqtt.config;
import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@Slf4j
public class RegisEquipMqttOutboundConfiguration {
@Autowired
private MqttPropertiesConfig mqttPropertiesConfig;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
// 消息通道
@Bean
public MessageChannel mqttOutboundChannel3(){
return new DirectChannel();
}
/** 配置出站消息处理器 */
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel3") // 指定处理器针对哪个通道的消息进行处理
public MessageHandler mqttOutboundMessageHandler3(){
String clientId = mqttPropertiesConfig.getPubClientId() + "_" + UUID.fastUUID();
MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(
mqttPropertiesConfig.getUrl(),
clientId,
mqttPahoClientFactory
);
mqttPahoMessageHandler.setDefaultQos(1);
mqttPahoMessageHandler.setDefaultTopic(mqttPropertiesConfig.getPubTopic2());
mqttPahoMessageHandler.setAsync(true);
return mqttPahoMessageHandler;
}
}

View File

@ -1,125 +1,125 @@
package com.fuyuanshen.global.mqtt.receiver; //package com.fuyuanshen.global.mqtt.receiver;
//
import cn.hutool.core.lang.Dict; //import cn.hutool.core.lang.Dict;
import com.baomidou.lock.LockTemplate; //import com.baomidou.lock.LockTemplate;
import com.fuyuanshen.common.core.constant.GlobalConstants; //import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils; //import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils; //import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils; //import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext; //import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine; //import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; //import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.queue.MqttMessageQueueConstants; //import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock; //import org.redisson.api.RLock;
import org.redisson.api.RedissonClient; //import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message; //import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler; //import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders; //import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException; //import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service; //import org.springframework.stereotype.Service;
//
import java.time.Duration; //import java.time.Duration;
import java.util.Objects; //import java.util.Objects;
import java.util.concurrent.TimeUnit; //import java.util.concurrent.TimeUnit;
//
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; //import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
//
@Service //@Service
@Slf4j //@Slf4j
public class NewReceiverMessageHandler implements MessageHandler { //public class NewReceiverMessageHandler implements MessageHandler {
//
@Autowired // @Autowired
private NewMqttRuleEngine newRuleEngine; // private NewMqttRuleEngine newRuleEngine;
//
@Override // @Override
public void handleMessage(Message<?> message) throws MessagingException { // public void handleMessage(Message<?> message) throws MessagingException {
//
Object payload = message.getPayload(); // Object payload = message.getPayload();
MessageHeaders headers = message.getHeaders(); // MessageHeaders headers = message.getHeaders();
String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString(); // String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString(); // String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString(); // String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
//
log.info("MQTT2 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}", // log.info("MQTT2 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}",
payload, receivedTopic, receivedQos, timestamp); // payload, receivedTopic, receivedQos, timestamp);
//
Dict payloadDict = JsonUtils.parseMap(payload.toString()); // Dict payloadDict = JsonUtils.parseMap(payload.toString());
if (receivedTopic == null || payloadDict == null) { // if (receivedTopic == null || payloadDict == null) {
return;
}
String imei = payloadDict.getStr("imei");
String funcType = payloadDict.getStr("funcType");
// 执行业务逻辑
if(StringUtils.isNotBlank(imei)){
String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
//在线状态
String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
}
String[] topicArr = receivedTopic.split("/");
NewMqttRuleContext context = new NewMqttRuleContext();
context.setCommandType(topicArr[2]+"_"+funcType);
context.setDeviceImei(imei);
context.setPayloadDict(payloadDict);
boolean ruleExecuted = newRuleEngine.executeRule(context);
if (!ruleExecuted) {
log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
}
// final LockInfo lockInfo = lockTemplate.lock(GlobalConstants.GLOBAL_REDIS_KEY + lockKey + imei, 100L, 3000L, RedissonLockExecutor.class);
// if (null == lockInfo) {
// log.info("MQTT3业务处理中,请稍后再试:funcType=>{},imei=>{}",funcType,imei);
// return; // return;
// } // }
//// 获取锁成功,处理业务 // String imei = payloadDict.getStr("imei");
// try { // String funcType = payloadDict.getStr("funcType");
// if(StringUtils.isNotBlank(imei)){ // // 执行业务逻辑
// String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY; // if(StringUtils.isNotBlank(imei)){
// String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY; // String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
// RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900)); // String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
// //在线状态 // RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; // //在线状态
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360)); // String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
// } // RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
//
// String[] topicArr = receivedTopic.split("/");
//
// NewMqttRuleContext context = new NewMqttRuleContext();
// context.setCommandType(topicArr[2]+"_"+funcType);
// context.setDeviceImei(imei);
// context.setPayloadDict(payloadDict);
//
// boolean ruleExecuted = newRuleEngine.executeRule(context);
//
// if (!ruleExecuted) {
// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
// }
// } finally {
// //释放锁
// lockTemplate.releaseLock(lockInfo);
// } // }
/* ===== 追加:根据报文内容识别格式并统一解析 ===== */
// int intType = MqttXinghanCommandType.computeVirtualCommandType(payloadDict);
// if (intType > 0) {
// MqttRuleContext newCtx = new MqttRuleContext();
// String commandType = "Light_"+intType;
// newCtx.setCommandType(commandType);
// newCtx.setDeviceImei(imei);
// newCtx.setPayloadDict(payloadDict);
// //
// boolean ok = ruleEngine.executeRule(newCtx); // String[] topicArr = receivedTopic.split("/");
// if (!ok) { //
// log.warn("新规则引擎未命中, imei={}", imei); // NewMqttRuleContext context = new NewMqttRuleContext();
// } // context.setCommandType(topicArr[2]+"_"+funcType);
// context.setDeviceImei(imei);
// context.setPayloadDict(payloadDict);
//
// boolean ruleExecuted = newRuleEngine.executeRule(context);
//
// if (!ruleExecuted) {
// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
// } // }
} //// final LockInfo lockInfo = lockTemplate.lock(GlobalConstants.GLOBAL_REDIS_KEY + lockKey + imei, 100L, 3000L, RedissonLockExecutor.class);
} //// if (null == lockInfo) {
//// log.info("MQTT3业务处理中,请稍后再试:funcType=>{},imei=>{}",funcType,imei);
//// return;
//// }
////// 获取锁成功,处理业务
//// try {
//// if(StringUtils.isNotBlank(imei)){
//// String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY;
//// String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY;
//// RedisUtils.offerDeduplicated(queueKey,dedupKey,imei, Duration.ofSeconds(900));
//// //在线状态
//// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ imei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ;
//// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
//// }
////
//// String[] topicArr = receivedTopic.split("/");
////
//// NewMqttRuleContext context = new NewMqttRuleContext();
//// context.setCommandType(topicArr[2]+"_"+funcType);
//// context.setDeviceImei(imei);
//// context.setPayloadDict(payloadDict);
////
//// boolean ruleExecuted = newRuleEngine.executeRule(context);
////
//// if (!ruleExecuted) {
//// log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
//// }
//// } finally {
//// //释放锁
//// lockTemplate.releaseLock(lockInfo);
//// }
//
//
// /* ===== 追加:根据报文内容识别格式并统一解析 ===== */
//// int intType = MqttXinghanCommandType.computeVirtualCommandType(payloadDict);
//// if (intType > 0) {
//// MqttRuleContext newCtx = new MqttRuleContext();
//// String commandType = "Light_"+intType;
//// newCtx.setCommandType(commandType);
//// newCtx.setDeviceImei(imei);
//// newCtx.setPayloadDict(payloadDict);
////
//// boolean ok = ruleEngine.executeRule(newCtx);
//// if (!ok) {
//// log.warn("新规则引擎未命中, imei={}", imei);
//// }
//// }
// }
//}

View File

@ -6,10 +6,7 @@ import com.fuyuanshen.common.core.utils.ImageToCArrayConverter;
import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.MqttRuleContext; import com.fuyuanshen.global.mqtt.base.*;
import com.fuyuanshen.global.mqtt.base.MqttRuleEngine;
import com.fuyuanshen.global.mqtt.base.MqttXinghanCommandType;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.queue.MqttMessageQueueConstants; import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -35,6 +32,9 @@ public class ReceiverMessageHandler implements MessageHandler {
@Autowired @Autowired
private MqttRuleEngine ruleEngine; private MqttRuleEngine ruleEngine;
@Autowired
private NewMqttRuleEngine newRuleEngine;
@Override @Override
public void handleMessage(Message<?> message) throws MessagingException { public void handleMessage(Message<?> message) throws MessagingException {
Object payload = message.getPayload(); Object payload = message.getPayload();
@ -50,9 +50,18 @@ public class ReceiverMessageHandler implements MessageHandler {
if (receivedTopic == null || payloadDict == null) { if (receivedTopic == null || payloadDict == null) {
return; return;
} }
String[] subStr = receivedTopic.split("/");
String deviceImei = subStr[1];
// 模版格式匹配
boolean flag = checkTemplateFormatMatching(payloadDict);
String[] subStr = receivedTopic.split("/");
String deviceImei = null;
if(flag){
deviceImei = payloadDict.getStr("imei");
} else {
deviceImei = subStr[1];
}
RedissonClient client = RedisUtils.getClient(); RedissonClient client = RedisUtils.getClient();
String lockKey = "mqtt:consumer:lock:"; String lockKey = "mqtt:consumer:lock:";
@ -74,7 +83,22 @@ public class ReceiverMessageHandler implements MessageHandler {
RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360)); RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360));
} }
// 新的通信协议
if(flag){
String[] topicArr = receivedTopic.split("/");
String funcType = payloadDict.getStr("funcType");
NewMqttRuleContext context = new NewMqttRuleContext();
context.setCommandType(topicArr[2]+"_"+funcType);
context.setDeviceImei(deviceImei);
context.setPayloadDict(payloadDict);
boolean ruleExecuted = newRuleEngine.executeRule(context);
if (!ruleExecuted) {
log.warn("未找到匹配的规则来处理命令类型: {}", topicArr[2] + " : " +funcType);
}
return;
}
if (convertArr.length > 0) { if (convertArr.length > 0) {
Byte val1 = (Byte) convertArr[0]; Byte val1 = (Byte) convertArr[0];
@ -89,6 +113,7 @@ public class ReceiverMessageHandler implements MessageHandler {
if (!ruleExecuted) { if (!ruleExecuted) {
log.warn("未找到匹配的规则来处理命令类型: {}", val1); log.warn("未找到匹配的规则来处理命令类型: {}", val1);
} }
return;
} }
/* ===== 追加:根据报文内容识别格式并统一解析 ===== */ /* ===== 追加:根据报文内容识别格式并统一解析 ===== */
@ -117,4 +142,18 @@ public class ReceiverMessageHandler implements MessageHandler {
} }
} }
private boolean checkTemplateFormatMatching(Dict payloadDict) {
// 检查是否包含指定的 key
boolean hasImei = payloadDict.containsKey("imei");
boolean hasFuncType = payloadDict.containsKey("funcType");
boolean hasStatus = payloadDict.containsKey("status");
boolean hasTimestamp = payloadDict.containsKey("timestamp");
boolean hasData = payloadDict.containsKey("data");
// 输出检查结果
log.info("包含 imei: {}, funcType: {}, status: {}, timestamp: {}, data: {}",
hasImei, hasFuncType, hasStatus, hasTimestamp, hasData);
return hasImei && hasFuncType && hasStatus && hasTimestamp && hasData;
}
} }

View File

@ -0,0 +1,156 @@
package com.fuyuanshen.global.mqtt.receiver;
import cn.hutool.core.lang.Dict;
import cn.hutool.json.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.domain.form.DeviceForm;
import com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.equipment.service.DeviceService;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleEngine;
import com.fuyuanshen.global.mqtt.config.MqttGateway;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.queue.MqttMessageQueueConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Objects;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
/**
* 注册设备消息接收处理
*/
@Service
@Slf4j
public class RegisEquipReceiverMessageHandler implements MessageHandler {
@Autowired
private NewMqttRuleEngine newRuleEngine;
@Autowired
private MqttGateway mqttGateway;
@Autowired
private DeviceMapper deviceMapper;
@Autowired
private DeviceService deviceService;
@Autowired
private DeviceTypeMapper deviceTypeMapper;
@Override
public void handleMessage(Message<?> message) throws MessagingException {
Object payload = message.getPayload();
MessageHeaders headers = message.getHeaders();
String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString();
// 只处理 regis/equip/# 主题的消息
if (!receivedTopic.startsWith("regis/equip/")) {
return;
}
// 从主题中提取设备ID
String[] topicParts = receivedTopic.split("/");
if (topicParts.length < 3) {
log.warn("Invalid topic format: {}", receivedTopic);
return;
}
String deviceTypeName = topicParts[2]; // HBY100-J
String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString();
String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString();
log.info("MQTT3 payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}",
payload, receivedTopic, receivedQos, timestamp);
// 解析JSON payload获取imei和mac
Dict payloadDict = JsonUtils.parseMap(payload.toString());
if (payloadDict == null) {
log.warn("Failed to parse payload JSON");
return;
}
String imei = payloadDict.getStr("imei");
String mac = payloadDict.getStr("mac");
log.info("Extracted IMEI: {}, MAC: {}", imei, mac);
// 验证必要字段
if (StringUtils.isEmpty(imei) || StringUtils.isEmpty(mac)) {
log.warn("Missing required fields - IMEI: {}, MAC: {}", imei, mac);
return;
}
DeviceTypeQueryCriteria criteria = new DeviceTypeQueryCriteria();
criteria.setTypeName(deviceTypeName);
DeviceType deviceType = deviceTypeMapper.queryByName(criteria);
if (deviceType == null) {
log.warn("Device type not found for name: {}", deviceTypeName);
return;
}
Device device = deviceMapper.selectDeviceByImei(imei);
if (device != null) {
log.warn("Device already exists for IMEI: {}", imei);
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
imei + ":regis";
Object value = RedisUtils.getCacheObject(redisKey);
if (value != null) {
log.warn("regis/imei发送次数频率过快: {}", imei);
return;
}
// sendSuccessMessage(imei);
RedisUtils.setCacheObject(redisKey, payload.toString(), Duration.ofSeconds(10));
return;
}
// 提取MAC地址后6位
String macSuffix = mac.replaceAll(":", "").substring(6); // 43:73:43:33:53:33 -> 335333
// 构建设备名称和蓝牙名称:设备类型+MAC后6位
String deviceName = deviceTypeName + "-" + macSuffix; // HBY100-335333
DeviceForm deviceForm = new DeviceForm();
deviceForm.setDeviceImei(imei);
deviceForm.setDeviceMac(mac);
deviceForm.setDeviceName(deviceName);
deviceForm.setBluetoothName(deviceName);
deviceForm.setDeviceType(deviceType.getId());
try {
deviceService.addDevice(deviceForm);
} catch (Exception e) {
throw new RuntimeException(e);
}
sendSuccessMessage(imei);
}
private void sendSuccessMessage(String imei) {
// 解析原始JSON数据
JSONObject originalData = new JSONObject();
originalData.put("code", 200);
// 发送到MQTT
String topic = "regis/" + imei;
mqttGateway.sendMsgToMqtt(topic, originalData.toString());
}
}

View File

@ -38,18 +38,18 @@ public class BjqActiveReportingDeviceDataRule implements MqttMessageRule {
@Override @Override
public void execute(MqttRuleContext context) { public void execute(MqttRuleContext context) {
try { try {
// Object[] convertArr = context.getConvertArr(); Object[] convertArr = context.getConvertArr();
// // Latitude, longitude // Latitude, longitude
// //主灯档位,激光灯档位,电量百分比,充电状态,电池剩余续航时间 //主灯档位,激光灯档位,电量百分比,充电状态,电池剩余续航时间
// String mainLightMode = convertArr[1].toString(); String mainLightMode = convertArr[1].toString();
// String laserLightMode = convertArr[2].toString(); String laserLightMode = convertArr[2].toString();
// String batteryPercentage = convertArr[3].toString(); String batteryPercentage = convertArr[3].toString();
// String chargeState = convertArr[4].toString(); String chargeState = convertArr[4].toString();
// String batteryRemainingTime = convertArr[5].toString(); String batteryRemainingTime = convertArr[5].toString();
//
// // 发送设备状态和位置信息到Redis // 发送设备状态和位置信息到Redis
// asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(), mainLightMode, laserLightMode, asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(), mainLightMode, laserLightMode,
// batteryPercentage, chargeState, batteryRemainingTime); batteryPercentage, chargeState, batteryRemainingTime);
} catch (Exception e) { } catch (Exception e) {
log.error("处理上报数据命令时出错", e); log.error("处理上报数据命令时出错", e);
} }

View File

@ -44,37 +44,37 @@ public class BjqBootLogoRule implements MqttMessageRule {
public void execute(MqttRuleContext context) { public void execute(MqttRuleContext context) {
String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei();
try { try {
// Byte val2 = (Byte) context.getConvertArr()[1]; Byte val2 = (Byte) context.getConvertArr()[1];
// if (val2 == 100) { if (val2 == 100) {
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
// return; return;
// } }
//
// String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX);
// if (StringUtils.isEmpty(data)) { if (StringUtils.isEmpty(data)) {
// return; return;
// } }
//
// byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
// byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512);
// log.info("第{}块数据大小: {} 字节", val2, specificChunk.length); log.info("第{}块数据大小: {} 字节", val2, specificChunk.length);
//
// ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
// intData.add(3); intData.add(3);
// intData.add((int) val2); intData.add((int) val2);
// ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData); ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
//
// Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
// map.put("instruct", intData); map.put("instruct", intData);
//
// mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map)); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map));
// log.info("发送开机LOGO点阵数据到设备消息=>topic:{},payload:{}", log.info("发送开机LOGO点阵数据到设备消息=>topic:{},payload:{}",
// MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(),
// JsonUtils.toJsonString(map)); JsonUtils.toJsonString(map));
} catch (Exception e) { } catch (Exception e) {
log.error("处理开机LOGO时出错", e); log.error("处理开机LOGO时出错", e);

View File

@ -34,15 +34,15 @@ public class BjqLaserModeSettingsRule implements MqttMessageRule {
public void execute(MqttRuleContext context) { public void execute(MqttRuleContext context) {
String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei();
try { try {
// Object[] convertArr = context.getConvertArr(); Object[] convertArr = context.getConvertArr();
//
// String mode = convertArr[1].toString(); String mode = convertArr[1].toString();
// if(StringUtils.isNotBlank(mode)){ if(StringUtils.isNotBlank(mode)){
// // 发送设备状态和位置信息到Redis // 发送设备状态和位置信息到Redis
// syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mode); syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mode);
// } }
//
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(30)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(30));
} catch (Exception e) { } catch (Exception e) {
log.error("处理激光模式命令时出错", e); log.error("处理激光模式命令时出错", e);
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(30)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(30));

View File

@ -34,15 +34,15 @@ public class BjqLightBrightnessRule implements MqttMessageRule {
public void execute(MqttRuleContext context) { public void execute(MqttRuleContext context) {
String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei();
try { try {
// Object[] convertArr = context.getConvertArr(); Object[] convertArr = context.getConvertArr();
//
// String convertValue = convertArr[1].toString(); String convertValue = convertArr[1].toString();
// // 将设备状态信息存储到Redis中 // 将设备状态信息存储到Redis中
// String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX; String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX;
//
// // 存储到Redis // 存储到Redis
// RedisUtils.setCacheObject(deviceRedisKey, convertValue); RedisUtils.setCacheObject(deviceRedisKey, convertValue);
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
} catch (Exception e) { } catch (Exception e) {
log.error("处理灯光亮度命令时出错", e); log.error("处理灯光亮度命令时出错", e);
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20));

View File

@ -52,26 +52,26 @@ public class BjqLocationDataRule implements MqttMessageRule {
public void execute(MqttRuleContext context) { public void execute(MqttRuleContext context) {
String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei();
try { try {
// Object[] convertArr = context.getConvertArr(); Object[] convertArr = context.getConvertArr();
// // Latitude, longitude // Latitude, longitude
// String latitude = convertArr[1].toString(); String latitude = convertArr[1].toString();
// String longitude = convertArr[2].toString(); String longitude = convertArr[2].toString();
// // 判断 latitude 和 longitude 是否都为 0 // 判断 latitude 和 longitude 是否都为 0
// if ("0".equals(latitude) && "0".equals(longitude)) { if ("0".equals(latitude) && "0".equals(longitude)) {
// log.info("位置信息为0不存储到Redis: device={}, lat={}, lon={}", context.getDeviceImei(), latitude, longitude); log.info("位置信息为0不存储到Redis: device={}, lat={}, lon={}", context.getDeviceImei(), latitude, longitude);
// return; return;
// } }
// // 异步发送经纬度到Redis // 异步发送经纬度到Redis
// asyncSendLocationToRedisWithFuture(context.getDeviceImei(), latitude, longitude); asyncSendLocationToRedisWithFuture(context.getDeviceImei(), latitude, longitude);
// // 异步保存数据 // 异步保存数据
// asyncSaveLocationToMySQLWithFuture(context.getDeviceImei(), latitude, longitude); asyncSaveLocationToMySQLWithFuture(context.getDeviceImei(), latitude, longitude);
//
// Map<String, Object> map = buildLocationDataMap(latitude, longitude); Map<String, Object> map = buildLocationDataMap(latitude, longitude);
// mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map)); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map));
// log.info("发送定位数据到设备=>topic:{},payload:{}", log.info("发送定位数据到设备=>topic:{},payload:{}",
// MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(),
// JsonUtils.toJsonString(map)); JsonUtils.toJsonString(map));
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
} catch (Exception e) { } catch (Exception e) {
log.error("处理定位数据命令时出错", e); log.error("处理定位数据命令时出错", e);
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20));

View File

@ -52,45 +52,45 @@ public class BjqModeRule implements MqttMessageRule {
try { try {
log.info("处理灯光模式命令"); log.info("处理灯光模式命令");
log.info("MQTT消息负载字典{}", context.getPayloadDict()); log.info("MQTT消息负载字典{}", context.getPayloadDict());
// Object[] convertArr = context.getConvertArr(); Object[] convertArr = context.getConvertArr();
//
// String mainLightMode = convertArr[1].toString(); String mainLightMode = convertArr[1].toString();
// String batteryRemainingTime = convertArr[2].toString(); String batteryRemainingTime = convertArr[2].toString();
// if (StringUtils.isNotBlank(mainLightMode)) { if (StringUtils.isNotBlank(mainLightMode)) {
// log.info("设备离线mainLightMode{}", mainLightMode); log.info("设备离线mainLightMode{}", mainLightMode);
// if ("0".equals(mainLightMode)) { if ("0".equals(mainLightMode)) {
//
// // 设备离线 // 设备离线
// String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + context.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX; String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + context.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX;
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "0"); RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "0");
//
// String sendMessageIng = GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + context.getDeviceImei() + ":messageSending"; String sendMessageIng = GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + context.getDeviceImei() + ":messageSending";
// String messageSendingValue = RedisUtils.getCacheObject(sendMessageIng); String messageSendingValue = RedisUtils.getCacheObject(sendMessageIng);
// if ("1".equals(messageSendingValue)) { if ("1".equals(messageSendingValue)) {
// // 设置为故障状态 // 设置为故障状态
// RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "2"); RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "2");
// UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>(); UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
// updateWrapper.eq("device_imei", context.getDeviceImei()); updateWrapper.eq("device_imei", context.getDeviceImei());
// updateWrapper.set("online_status", 2); updateWrapper.set("online_status", 2);
// deviceService.update(updateWrapper); deviceService.update(updateWrapper);
// RedisUtils.deleteObject(sendMessageIng); RedisUtils.deleteObject(sendMessageIng);
//
// // 解除告警 // 解除告警
// String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX; String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX;
// if (RedisUtils.getCacheObject(deviceRedisKey) != null) { if (RedisUtils.getCacheObject(deviceRedisKey) != null) {
// RedisUtils.deleteObject(deviceRedisKey); RedisUtils.deleteObject(deviceRedisKey);
// } }
// cancelAlarm(context.getDeviceImei()); cancelAlarm(context.getDeviceImei());
// } }
// } }
// // 发送设备状态和位置信息到Redis // 发送设备状态和位置信息到Redis
// syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(), mainLightMode); syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(), mainLightMode);
// String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX; String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX;
//
// // 存储到Redis // 存储到Redis
// RedisUtils.setCacheObject(deviceRedisKey, batteryRemainingTime); RedisUtils.setCacheObject(deviceRedisKey, batteryRemainingTime);
// } }
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
} catch (Exception e) { } catch (Exception e) {
log.error("处理灯光模式命令时出错", e); log.error("处理灯光模式命令时出错", e);
RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20));

View File

@ -45,47 +45,47 @@ public class BjqSendMessageRule implements MqttMessageRule {
try { try {
// Byte val2 = (Byte) context.getConvertArr()[1]; // Byte val2 = (Byte) context.getConvertArr()[1];
// String val2Str = context.getConvertArr()[1].toString(); String val2Str = context.getConvertArr()[1].toString();
// int val2 = Integer.parseInt(val2Str); int val2 = Integer.parseInt(val2Str);
// System.out.println("收到设备信息命令:"+val2); System.out.println("收到设备信息命令:"+val2);
// if (val2 == 100) { if (val2 == 100) {
// RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20));
// return; return;
// } }
//
// if(val2==200){ if(val2==200){
// String sendMessageIng = GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":messageSending"; String sendMessageIng = GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":messageSending";
// RedisUtils.deleteObject(sendMessageIng); RedisUtils.deleteObject(sendMessageIng);
// return; return;
// } }
//
//
// String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":app_send_message_data"); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":app_send_message_data");
// if (StringUtils.isEmpty(data)) { if (StringUtils.isEmpty(data)) {
// return; return;
// } }
//
// byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data);
// byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512);
// log.info("第{}块数据大小: {} 字节", val2, specificChunk.length); log.info("第{}块数据大小: {} 字节", val2, specificChunk.length);
//// System.out.println("第" + val2 + "块数据: " + Arrays.toString(specificChunk)); // System.out.println("第" + val2 + "块数据: " + Arrays.toString(specificChunk));
//
// ArrayList<Integer> intData = new ArrayList<>(); ArrayList<Integer> intData = new ArrayList<>();
// intData.add(6); intData.add(6);
// intData.add(val2); intData.add(val2);
// ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData); ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk), intData);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
// intData.add(0); intData.add(0);
//
// Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
// map.put("instruct", intData); map.put("instruct", intData);
//
// mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map)); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map));
// log.info("发送设备信息数据到设备消息=>topic:{},payload:{}", log.info("发送设备信息数据到设备消息=>topic:{},payload:{}",
// MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(),
// JsonUtils.toJsonString(map)); JsonUtils.toJsonString(map));
} catch (Exception e) { } catch (Exception e) {
log.error("处理发送设备信息时出错", e); log.error("处理发送设备信息时出错", e);

View File

@ -29,13 +29,13 @@ public class FuncType10StrobeMode implements NewMqttMessageRule {
log.info("HBY100J爆闪模式开启/关闭,消息负载:{}", context.getPayloadDict()); log.info("HBY100J爆闪模式开启/关闭,消息负载:{}", context.getPayloadDict());
try { try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":strobeMode"; context.getDeviceImei() + ":strobeMode";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J爆闪模式开启/关闭失败", e); log.error("HBY100J爆闪模式开启/关闭失败", e);
} }

View File

@ -29,13 +29,13 @@ public class FuncType11Frequency implements NewMqttMessageRule {
log.info("HBY100J修改警示灯爆闪频率消息负载{}", context.getPayloadDict()); log.info("HBY100J修改警示灯爆闪频率消息负载{}", context.getPayloadDict());
try { try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":frequency"; context.getDeviceImei() + ":frequency";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J修改警示灯爆闪频率失败", e); log.error("HBY100J修改警示灯爆闪频率失败", e);
} }

View File

@ -30,14 +30,14 @@ public class FuncType12ForceAudio implements NewMqttMessageRule {
try { try {
// 构建强制声光报警开关的Redis键 // 构建强制声光报警开关的Redis键
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":forceAudio"; context.getDeviceImei() + ":forceAudio";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// // 存储强制声光报警开关状态到Redis // 存储强制声光报警开关状态到Redis
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J强制声光报警开启/关闭失败", e); log.error("HBY100J强制声光报警开启/关闭失败", e);
} }

View File

@ -1,46 +1,46 @@
//package com.fuyuanshen.global.mqtt.rule.hby100j; package com.fuyuanshen.global.mqtt.rule.hby100j;
//
//import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
//import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.constant.GlobalConstants;
//import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.redis.utils.RedisUtils;
//import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule; import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
//import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext; import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//
//import java.util.Map; import java.util.Map;
//
//import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
//
///** /**
// * 设备复位 * 设备复位
// */ */
//@Slf4j @Slf4j
//@Component @Component
//public class FuncType1Rest implements NewMqttMessageRule { public class FuncType1Rest implements NewMqttMessageRule {
//
// @Override @Override
// public String getCommandType() { public String getCommandType() {
// return "HBY100_1"; return "HBY100_1";
// } }
//
// @Override @Override
// public void execute(NewMqttRuleContext context) { public void execute(NewMqttRuleContext context) {
// log.info("开始处理设备复位,消息负载:{}", context.getPayloadDict()); log.info("开始处理设备复位,消息负载:{}", context.getPayloadDict());
//
// try { try {
// // 构建强制声光报警开关的Redis键 // 构建强制声光报警开关的Redis键
//// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
//// context.getDeviceImei() + ":force_audio_visual_alarm_switch"; context.getDeviceImei() + ":rest";
////
//// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
//// if (payloadDict != null) { if (payloadDict != null) {
//// // 存储强制声光报警开关状态到Redis // 存储强制声光报警开关状态到Redis
//// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
//// } }
// log.info("设备复位设备ID{}", context.getDeviceImei()); log.info("设备复位设备ID{}", context.getDeviceImei());
// } catch (Exception e) { } catch (Exception e) {
// log.error("处理设备复位失败", e); log.error("处理设备复位失败", e);
// } }
// } }
//} }

View File

@ -1,46 +1,46 @@
//package com.fuyuanshen.global.mqtt.rule.hby100j; package com.fuyuanshen.global.mqtt.rule.hby100j;
//
//import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
//import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.constant.GlobalConstants;
//import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.redis.utils.RedisUtils;
//import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule; import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
//import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext; import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//
//import java.util.Map; import java.util.Map;
//
//import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
//
///** /**
// * 获取设备基础信息 * 获取设备基础信息
// */ */
//@Slf4j @Slf4j
//@Component @Component
//public class FuncType2BaseInfo implements NewMqttMessageRule { public class FuncType2BaseInfo implements NewMqttMessageRule {
//
// @Override @Override
// public String getCommandType() { public String getCommandType() {
// return "HBY100_2"; return "HBY100_2";
// } }
//
// @Override @Override
// public void execute(NewMqttRuleContext context) { public void execute(NewMqttRuleContext context) {
// log.info("开始处理强制声光报警开关,消息负载:{}", context.getPayloadDict()); log.info("开始处理强制声光报警开关,消息负载:{}", context.getPayloadDict());
//
// try { try {
// // 构建强制声光报警开关的Redis键 // 构建强制声光报警开关的Redis键
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":force_audio_visual_alarm_switch"; context.getDeviceImei() + ":force_audio_visual_alarm_switch";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// // 存储强制声光报警开关状态到Redis // 存储强制声光报警开关状态到Redis
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
// log.info("强制声光报警开关处理完成设备ID{}", context.getDeviceImei()); log.info("强制声光报警开关处理完成设备ID{}", context.getDeviceImei());
// } catch (Exception e) { } catch (Exception e) {
// log.error("处理强制声光报警开关失败", e); log.error("处理强制声光报警开关失败", e);
// } }
// } }
//} }

View File

@ -29,13 +29,13 @@ public class FuncType5UpdateVoice implements NewMqttMessageRule {
log.info("HBY100J更新语音消息负载{}", context.getPayloadDict()); log.info("HBY100J更新语音消息负载{}", context.getPayloadDict());
try { try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":updateVoice"; context.getDeviceImei() + ":updateVoice";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J更新语音失败", e); log.error("HBY100J更新语音失败", e);
} }

View File

@ -29,13 +29,13 @@ public class FuncType6VoicePlay implements NewMqttMessageRule {
log.info("HBY100J语音播报开启/关闭,消息负载:{}", context.getPayloadDict()); log.info("HBY100J语音播报开启/关闭,消息负载:{}", context.getPayloadDict());
try { try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":VoicePlay"; context.getDeviceImei() + ":voicePlay";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J语音播报开启/关闭失败", e); log.error("HBY100J语音播报开启/关闭失败", e);
} }

View File

@ -29,13 +29,13 @@ public class FuncType9UpdateVolume implements NewMqttMessageRule {
log.info("HBY100J修改音量消息负载{}", context.getPayloadDict()); log.info("HBY100J修改音量消息负载{}", context.getPayloadDict());
try { try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":updateVolume"; context.getDeviceImei() + ":updateVolume";
//
// Map<String, Object> payloadDict = context.getPayloadDict(); Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) { if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict)); RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// } }
} catch (Exception e) { } catch (Exception e) {
log.error("HBY100J修改音量失败", e); log.error("HBY100J修改音量失败", e);
} }

View File

@ -0,0 +1,137 @@
package com.fuyuanshen.web.controller.device;
import com.fuyuanshen.app.domain.dto.AppAudioFileDto;
import com.fuyuanshen.app.domain.dto.AppFileRenameDto;
import com.fuyuanshen.app.domain.dto.TextToSpeechRequest;
import com.fuyuanshen.app.service.AudioProcessService;
import com.fuyuanshen.app.service.VideoProcessService;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.equipment.domain.vo.AppFileVo;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* APP 视频处理控制器
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/video")
public class WebVideoController extends BaseController {
private final VideoProcessService videoProcessService;
private final AudioProcessService audioProcessService;
/**
* 上传视频转码code默认1RGB565 2BGR565
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,message = "请勿重复提交!")
public R<List<String>> uploadVideo(@RequestParam("file") MultipartFile file, @RequestParam(defaultValue = "1") int code) {
return R.ok(videoProcessService.processVideo(file, code));
}
/**
* 上传音频文件并转码
*/
@PostMapping(value = "/audio", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,message = "请勿重复提交!")
public R<List<String>> uploadAudio(@RequestParam("file") MultipartFile file) {
return R.ok(audioProcessService.processAudio(file));
}
/**
* 文字转音频TTS服务
*/
@GetMapping("/audioTTS")
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,message = "请勿重复提交!")
public R<List<String>> uploadAudioTTS(@RequestParam String text) throws IOException {
return R.ok(audioProcessService.generateStandardPcmData(text));
}
/**
* 提取文本内容只支持txt/docx
*/
@PostMapping(value = "/extract", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS,message = "请勿重复提交!")
public R<String> extract(@RequestParam("file") MultipartFile file) throws Exception {
return R.ok("Success",audioProcessService.extract(file));
}
/**
* 上传音频文件进行处理
* 支持MP3、WAV、PCM格式
*/
@PostMapping("/uploadAudioToOss")
public R<String> uploadAudioToOss(@ModelAttribute AppAudioFileDto bo) {
try {
bo.setSource("web");
String result = audioProcessService.uploadAudioToOss(bo);
return R.ok(result);
} catch (IllegalArgumentException e) {
return R.fail("文件格式错误: " + e.getMessage());
} catch (Exception e) {
return R.fail("上传处理失败: " + e.getMessage());
}
}
/**
* 文本转语音
* 支持MP3、WAV、PCM格式
*/
@PostMapping("/ttsToOss")
public R<String> textToSpeech(@RequestBody TextToSpeechRequest request) {
try {
if (request.getDeviceId() == null) {
return R.fail("设备ID不能为空");
}
String result = audioProcessService.textToSpeech(
request.getDeviceId(),
request.getText(),
request.getFileSuffix(),
"web"
);
return R.ok(result);
} catch (Exception e) {
return R.fail("文本转语音失败: " + e.getMessage());
}
}
/**
* 查询语音文件列表
*/
@GetMapping("/queryAudioFileList")
public R<List<AppFileVo>> queryAudioFileList(Long deviceId) {
return R.ok(audioProcessService.queryAudioFileList(deviceId,"web"));
}
/**
* 删除语音文件
*/
@GetMapping("/deleteAudioFile")
public R<Void> deleteAudioFile(Long fileId,Long deviceId) {
return audioProcessService.deleteAudioFile(fileId,deviceId);
}
/**
* 文件重命名
*/
@PostMapping("/renameAudioFile")
public R<Void> renameAudioFile(@RequestBody AppFileRenameDto bo) {
return audioProcessService.renameAudioFile(bo);
}
}

View File

@ -0,0 +1,106 @@
package com.fuyuanshen.web.controller.device.bjq;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.web.core.BaseController;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import com.fuyuanshen.web.service.device.DeviceHBY100JBizService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* HBY100J设备控制类
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/hby100j/device")
public class WebDeviceHBY100JController extends BaseController {
private final DeviceHBY100JBizService deviceHBY100JBizService;
/**
* 获取设备详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<AppDeviceHBY100JDetailVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(deviceHBY100JBizService.getInfo(id));
}
/**
* 更新语音
*/
@PostMapping("/updateVoice")
public R<Void> updateVoice(@RequestBody HBY100JUpdateVoiceDto dto) {
deviceHBY100JBizService.updateVoice(dto);
return R.ok();
}
/**
* 强制报警
*
*/
@PostMapping("/forceAlarmActivation")
public R<Void> forceAlarmActivation(@RequestBody HBY100JForceAlarmActivationDto bo) {
deviceHBY100JBizService.forceAlarmActivation(bo);
return R.ok();
}
/**
* 语音播报
*
*/
@PostMapping("/voiceBroadcast")
public R<Void> voiceBroadcast(@RequestBody HBY100JVoiceBroadcastDto params) {
deviceHBY100JBizService.voiceBroadcast(params);
return R.ok();
}
/**
* 爆闪模式
*/
@PostMapping("/strobeMode")
public R<Void> strobeMode(@RequestBody HBY100JStrobeModeDto params) {
deviceHBY100JBizService.strobeMode(params);
return R.ok();
}
/**
* 灯光调节
*/
@PostMapping("/lightAdjustment")
public R<Void> lightAdjustment(@RequestBody HBY100JLightAdjustmentDto params) {
deviceHBY100JBizService.lightAdjustment(params);
return R.ok();
}
/**
* 爆闪频率
*/
@PostMapping("/strobeFrequency")
public R<Void> strobeFrequency(@RequestBody HBY100JStrobeFrequencyDto params) {
deviceHBY100JBizService.strobeFrequency(params);
return R.ok();
}
/**
* 修改音量
*/
@PostMapping("/updateVolume")
public R<Void> updateVolume(@RequestBody HBY100JUpdateVolumeDto params) {
deviceHBY100JBizService.updateVolume(params);
return R.ok();
}
}

View File

@ -0,0 +1,23 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
import java.util.List;
@Data
public class HBY100JForceAlarmActivationDto {
/**
* 设备ID
*/
List<Long> deviceIds;
/**
* 0 关闭, 1开启
*/
private Integer voiceStrobeAlarm;
/**
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7语音
*/
private Integer mode;
}

View File

@ -0,0 +1,31 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JLightAdjustmentDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 亮度值0-100
*/
private Integer brightness;
// /**
// * 红色LED亮度值0-100
// */
// private Integer red;
//
// /**
// * 蓝色LED亮度值0-100
// */
// private Integer blue;
//
// /**
// * 黄色LED亮度值0-100
// */
// private Integer yellow;
}

View File

@ -0,0 +1,16 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JStrobeFrequencyDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "frequency": 1-12
*/
private Integer frequency;
}

View File

@ -0,0 +1,21 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JStrobeModeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* 0 关闭 1 开启
*/
private Integer enable;
/**
* 0 红色爆闪1 蓝色爆闪2 黄色爆闪3红色顺时针旋转爆闪4黄色顺时针旋转爆闪5红蓝顺时针旋转爆闪6 红蓝交替爆闪
*/
private Integer mode;
}

View File

@ -0,0 +1,10 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JUpdateVoiceDto {
private Long id;
}

View File

@ -0,0 +1,16 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JUpdateVolumeDto{
/**
* 设备ID
*/
private Long deviceId;
/**
* "volume": 1-100(app端可根据需求把40作为低音量, 70作为中音量100作为高音量)
*/
private Integer volume;
}

View File

@ -0,0 +1,17 @@
package com.fuyuanshen.web.controller.device.domain.dto;
import lombok.Data;
@Data
public class HBY100JVoiceBroadcastDto {
/**
* 设备ID
*/
Long deviceId;
/**
* 0 关闭, 1开启
*/
private Integer voiceBroadcast;
}

View File

@ -86,7 +86,7 @@ public class DeviceBizService {
List<AppDeviceVo> records = result.getRecords(); List<AppDeviceVo> records = result.getRecords();
if (records != null && !records.isEmpty()) { if (records != null && !records.isEmpty()) {
records.forEach(item -> { records.forEach(item -> {
if (item.getCommunicationMode() != null && item.getCommunicationMode() == 0) { if (item.getCommunicationMode() != null && (item.getCommunicationMode() == 0 || item.getCommunicationMode() == 2)) {
// 设备在线状态 // 设备在线状态
String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX);

View File

@ -1,63 +1,46 @@
package com.fuyuanshen.web.service.device; package com.fuyuanshen.web.service.device;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fuyuanshen.app.controller.device.bjq.AppDeviceHBY100JController;
import com.fuyuanshen.app.domain.AppBusinessFile;
import com.fuyuanshen.app.domain.AppPersonnelInfo;
import com.fuyuanshen.app.domain.AppPersonnelInfoRecords;
import com.fuyuanshen.app.domain.bo.AppBusinessFileBo;
import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo;
import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto;
import com.fuyuanshen.app.domain.dto.DeviceInstructDto;
import com.fuyuanshen.app.domain.vo.AppBusinessFileVo;
import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo;
import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo; import com.fuyuanshen.app.domain.vo.AppDeviceHBY100JDetailVo;
import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceShareMapper;
import com.fuyuanshen.app.mapper.AppBusinessFileMapper;
import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper;
import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper;
import com.fuyuanshen.app.service.IAppBusinessFileService;
import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.domain.model.AppLoginUser;
import com.fuyuanshen.common.core.domain.model.LoginUser; import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.exception.ServiceException;
import com.fuyuanshen.common.core.utils.*; import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper; import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.AppBusinessFile;
import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; import com.fuyuanshen.equipment.domain.vo.AppBusinessFileVo;
import com.fuyuanshen.equipment.enums.LightModeEnum; import com.fuyuanshen.equipment.mapper.AppBusinessFileMapper;
import com.fuyuanshen.equipment.mapper.DeviceLogMapper; import com.fuyuanshen.equipment.mapper.DeviceLogMapper;
import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
import com.fuyuanshen.equipment.service.IAppBusinessFileService;
import com.fuyuanshen.global.mqtt.config.MqttGateway; import com.fuyuanshen.global.mqtt.config.MqttGateway;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.constants.MqttConstants; import com.fuyuanshen.global.mqtt.constants.MqttConstants;
import com.fuyuanshen.global.mqtt.rule.hby100j.domin.*; import com.fuyuanshen.global.mqtt.rule.hby100j.domin.*;
import com.fuyuanshen.global.mqtt.utils.GenerateIdUtil; import com.fuyuanshen.global.mqtt.utils.GenerateIdUtil;
import com.fuyuanshen.system.domain.SysOss;
import com.fuyuanshen.system.domain.vo.SysOssVo; import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.mapper.SysOssMapper; import com.fuyuanshen.system.mapper.SysOssMapper;
import com.fuyuanshen.web.controller.device.domain.dto.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream; import java.util.Date;
import java.time.Duration; import java.util.List;
import java.util.*;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX;
import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*;
@Slf4j @Slf4j
@ -72,9 +55,12 @@ public class DeviceHBY100JBizService {
private final IAppBusinessFileService appBusinessFileService; private final IAppBusinessFileService appBusinessFileService;
private final AppBusinessFileMapper appBusinessFileMapper; private final AppBusinessFileMapper appBusinessFileMapper;
private final SysOssMapper sysOssMapper; private final SysOssMapper sysOssMapper;
private final AppDeviceShareMapper appDeviceShareMapper;
private static final String DEVICE_TYPE = "HBY100/"; private static final String DEVICE_TYPE = "HBY100/";
private static final Long pcUserId = 0L;
/** /**
* 记录设备操作日志 * 记录设备操作日志
* *
@ -174,6 +160,60 @@ public class DeviceHBY100JBizService {
} }
} }
String voicePlayRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
device.getDeviceImei() + ":voicePlay";
String voicePlayStatus = RedisUtils.getCacheObject(voicePlayRedisKey);
if(StringUtils.isNotBlank(voicePlayStatus)){
FuncType6VoicePlayRequest funcType6VoicePlayRequest = JSONObject.parseObject(voicePlayStatus, FuncType6VoicePlayRequest.class);
if(funcType6VoicePlayRequest.getData() != null){
vo.setVolume(funcType6VoicePlayRequest.getData().getVoiceBroadcast());
}
}
String strobeModeRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
device.getDeviceImei() + ":strobeMode";
String strobeModeStatus = RedisUtils.getCacheObject(strobeModeRedisKey);
if(StringUtils.isNotBlank(strobeModeStatus)){
FuncType10StrobeModeRequest strobeModeRequest = JSONObject.parseObject(strobeModeStatus, FuncType10StrobeModeRequest.class);
FuncType10StrobeModeRequest.Data data = strobeModeRequest.getData();
if(data != null){
vo.setStrobeMode(strobeModeRequest.getData().getMode());
vo.setStrobeEnable(strobeModeRequest.getData().getEnable());
}
}
String updateVolumeRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
device.getDeviceImei() + ":updateVolume";
String updateVolumeStatus = RedisUtils.getCacheObject(updateVolumeRedisKey);
if(StringUtils.isNotBlank(updateVolumeStatus)){
FuncType9UpdateVolumeRequest updateVolumeRequest = JSONObject.parseObject(updateVolumeStatus, FuncType9UpdateVolumeRequest.class);
if(updateVolumeRequest.getData() != null){
vo.setVolume(updateVolumeRequest.getData().getVolume());
}
}
String frequencyRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
device.getDeviceImei() + ":frequency";
String frequencyStatus = RedisUtils.getCacheObject(frequencyRedisKey);
if(StringUtils.isNotBlank(frequencyStatus)){
FuncType11FrequencyRequest frequencyRequest = JSONObject.parseObject(frequencyStatus, FuncType11FrequencyRequest.class);
if(frequencyRequest.getData() != null){
vo.setStrobeFrequency(frequencyRequest.getData().getFrequency());
}
}
String forceAudioRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
device.getDeviceImei() + ":forceAudio";
String forceAudioStatus = RedisUtils.getCacheObject(forceAudioRedisKey);
if(StringUtils.isNotBlank(forceAudioStatus)){
FuncType12ForceAudioRequest forceAudioRequest = JSONObject.parseObject(forceAudioStatus, FuncType12ForceAudioRequest.class);
if(forceAudioRequest.getData() != null){
vo.setVoiceStrobeAlarm(forceAudioRequest.getData().getVoiceStrobeAlarm());
vo.setAlarmMode(forceAudioRequest.getData().getMode());
}
}
// 获取经度纬度 // 获取经度纬度
String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX); String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX);
@ -206,12 +246,12 @@ public class DeviceHBY100JBizService {
} }
public void forceAlarmActivation(AppDeviceHBY100JController.HBY100JForceAlarmActivationDto bo) { public void forceAlarmActivation(HBY100JForceAlarmActivationDto bo) {
List<Long> deviceIds = bo.getDeviceIds(); List<Long> deviceIds = bo.getDeviceIds();
if (deviceIds == null || deviceIds.isEmpty()) { if (deviceIds == null || deviceIds.isEmpty()) {
throw new ServiceException("请选择设备"); throw new ServiceException("请选择设备");
} }
LoginUser loginUser = LoginHelper.getLoginUser(); AppLoginUser loginUser = AppLoginHelper.getLoginUser();
bo.getDeviceIds().forEach(deviceId -> { bo.getDeviceIds().forEach(deviceId -> {
Device deviceObj = deviceMapper.selectById(deviceId); Device deviceObj = deviceMapper.selectById(deviceId);
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
@ -229,14 +269,14 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J强制报警下发设备参数{}", request); log.info("HBY100J强制报警下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceId, deviceObj.getDeviceName(), "强制报警激活", "强制报警激活", userId);
// recordDeviceLog(deviceId, deviceObj.getDeviceName(), "强制报警激活", "强制报警激活", loginUser.getUserId());
}); });
} }
public void updateVoice(AppDeviceHBY100JController.HBY100JUpdateVoiceDto dto) { public void updateVoice(HBY100JUpdateVoiceDto dto) {
AppBusinessFileVo appBusinessFileVo = appBusinessFileMapper.selectVoById(dto.getId()); AppBusinessFileVo appBusinessFileVo = appBusinessFileMapper.selectVoById(dto.getId());
if(appBusinessFileVo == null){ if(appBusinessFileVo == null){
throw new ServiceException("文件不存在"); throw new ServiceException("文件不存在");
@ -246,7 +286,7 @@ public class DeviceHBY100JBizService {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
LoginUser loginUser = LoginHelper.getLoginUser(); AppLoginUser loginUser = AppLoginHelper.getLoginUser();
SysOssVo sysOssVo = sysOssMapper.selectVoById(appBusinessFileVo.getFileId()); SysOssVo sysOssVo = sysOssMapper.selectVoById(appBusinessFileVo.getFileId());
FuncType5UpdateVoiceRequest request = new FuncType5UpdateVoiceRequest(); FuncType5UpdateVoiceRequest request = new FuncType5UpdateVoiceRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
@ -270,6 +310,8 @@ public class DeviceHBY100JBizService {
updateWrapper2.eq("id", appBusinessFileVo.getId()); updateWrapper2.eq("id", appBusinessFileVo.getId());
updateWrapper2.set("use_status", 1); updateWrapper2.set("use_status", 1);
appBusinessFileMapper.update(updateWrapper2); appBusinessFileMapper.update(updateWrapper2);
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), "更新语音", "更新语音", userId);
} }
private String buildMqttTopic(String deviceImei) { private String buildMqttTopic(String deviceImei) {
@ -277,11 +319,12 @@ public class DeviceHBY100JBizService {
return MqttConstants.GLOBAL_PUB_KEY2 +tenantId + "/" + DEVICE_TYPE + deviceImei; return MqttConstants.GLOBAL_PUB_KEY2 +tenantId + "/" + DEVICE_TYPE + deviceImei;
} }
public void strobeMode(AppDeviceHBY100JController.HBY100JStrobeModeDto params) { public void strobeMode(HBY100JStrobeModeDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId()); Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
FuncType10StrobeModeRequest request = new FuncType10StrobeModeRequest(); FuncType10StrobeModeRequest request = new FuncType10StrobeModeRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei()); request.setImei(deviceObj.getDeviceImei());
@ -293,9 +336,12 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J爆闪模式开启/关闭,下发设备参数:{}", request); log.info("HBY100J爆闪模式开启/关闭,下发设备参数:{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
String content = params.getEnable() != null && params.getEnable() == 1 ? "爆闪模式开启" : "爆闪模式关闭";
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), content, content, userId);
} }
public void lightAdjustment(AppDeviceHBY100JController.HBY100JLightAdjustmentDto params) { public void lightAdjustment(HBY100JLightAdjustmentDto params) {
log.info("HBY100J灯光调节请求参数{}", params); log.info("HBY100J灯光调节请求参数{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId()); Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) { if (deviceObj == null) {
@ -304,6 +350,7 @@ public class DeviceHBY100JBizService {
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
FuncType13BrightnessRequest request = new FuncType13BrightnessRequest(); FuncType13BrightnessRequest request = new FuncType13BrightnessRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei()); request.setImei(deviceObj.getDeviceImei());
@ -316,9 +363,11 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J灯光调节下发设备参数{}", request); log.info("HBY100J灯光调节下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), "灯光调节", "灯光调节", userId);
} }
public void strobeFrequency(AppDeviceHBY100JController.HBY100JStrobeFrequencyDto params) { public void strobeFrequency(HBY100JStrobeFrequencyDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId()); Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) { if (deviceObj == null) {
throw new ServiceException("设备不存在"); throw new ServiceException("设备不存在");
@ -326,6 +375,7 @@ public class DeviceHBY100JBizService {
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
FuncType11FrequencyRequest request = new FuncType11FrequencyRequest(); FuncType11FrequencyRequest request = new FuncType11FrequencyRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei()); request.setImei(deviceObj.getDeviceImei());
@ -336,9 +386,11 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J爆闪频率下发设备参数{}", request); log.info("HBY100J爆闪频率下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), "爆闪频率", "爆闪频率", userId);
} }
public void updateVolume(AppDeviceHBY100JController.HBY100JUpdateVolumeDto params) { public void updateVolume(HBY100JUpdateVolumeDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId()); Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) { if (deviceObj == null) {
throw new ServiceException("设备不存在"); throw new ServiceException("设备不存在");
@ -346,6 +398,7 @@ public class DeviceHBY100JBizService {
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
FuncType9UpdateVolumeRequest request = new FuncType9UpdateVolumeRequest(); FuncType9UpdateVolumeRequest request = new FuncType9UpdateVolumeRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei()); request.setImei(deviceObj.getDeviceImei());
@ -356,9 +409,11 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J更新音量下发设备参数{}", JSON.toJSONString(request)); log.info("HBY100J更新音量下发设备参数{}", JSON.toJSONString(request));
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), "更新音量", "更新音量", userId);
} }
public void voiceBroadcast(AppDeviceHBY100JController.HBY100JVoiceBroadcastDto params) { public void voiceBroadcast(HBY100JVoiceBroadcastDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId()); Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) { if (deviceObj == null) {
throw new ServiceException("设备不存在"); throw new ServiceException("设备不存在");
@ -366,6 +421,7 @@ public class DeviceHBY100JBizService {
if (getDeviceStatus(deviceObj.getDeviceImei())) { if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接"); throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
} }
AppLoginUser loginUser = AppLoginHelper.getLoginUser();
FuncType6VoicePlayRequest request = new FuncType6VoicePlayRequest(); FuncType6VoicePlayRequest request = new FuncType6VoicePlayRequest();
request.setRequestId(GenerateIdUtil.generateNumericId()); request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei()); request.setImei(deviceObj.getDeviceImei());
@ -376,5 +432,9 @@ public class DeviceHBY100JBizService {
request.setData(data); request.setData(data);
log.info("HBY100J语音播报下发设备参数{}", request); log.info("HBY100J语音播报下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request)); mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
Long userId = loginUser == null ? pcUserId : loginUser.getUserId();
recordDeviceLog(deviceObj.getId(), deviceObj.getDeviceName(), "语音播报", "语音播报", userId);
} }
} }

View File

@ -282,10 +282,10 @@ mqtt:
password: #YtvpSfCNG password: #YtvpSfCNG
url: tcp://47.120.79.150:2883 url: tcp://47.120.79.150:2883
subClientId: fys_subClient subClientId: fys_subClient
subTopic: A/# subTopic: A/#,status/#
pubTopic: B/# pubTopic: B/#,command/#
subTopic2: command/894078/# subTopic2: regis/equip/#
pubTopic2: status/894078/# pubTopic2: regis/#
pubClientId: fys_pubClient pubClientId: fys_pubClient

View File

@ -283,10 +283,10 @@ mqtt:
password: #YtvpSfCNG password: #YtvpSfCNG
url: tcp://47.120.79.150:3883 url: tcp://47.120.79.150:3883
subClientId: fys_subClient subClientId: fys_subClient
subTopic: A/# subTopic: A/#,status/#
pubTopic: B/# pubTopic: B/#,command/#
subTopic2: status/894078/# subTopic2: regis/equip/#
pubTopic2: command/894078/# pubTopic2: regis/#
pubClientId: fys_pubClient pubClientId: fys_pubClient
# TTS语音交互配置 # TTS语音交互配置

View File

@ -46,6 +46,9 @@ public class AppDeviceBindRecordBo extends BaseEntity {
* 绑定时间 * 绑定时间
*/ */
private Date bindingTime; private Date bindingTime;
/**
* 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙
*/
private Integer communicationMode;
} }

View File

@ -76,6 +76,7 @@ public class AppDeviceBindRecordServiceImpl implements IAppDeviceBindRecordServi
lqw.eq(bo.getDeviceId() != null, AppDeviceBindRecord::getDeviceId, bo.getDeviceId()); lqw.eq(bo.getDeviceId() != null, AppDeviceBindRecord::getDeviceId, bo.getDeviceId());
lqw.eq(bo.getBindingUserId() != null, AppDeviceBindRecord::getBindingUserId, bo.getBindingUserId()); lqw.eq(bo.getBindingUserId() != null, AppDeviceBindRecord::getBindingUserId, bo.getBindingUserId());
lqw.eq(bo.getBindingTime() != null, AppDeviceBindRecord::getBindingTime, bo.getBindingTime()); lqw.eq(bo.getBindingTime() != null, AppDeviceBindRecord::getBindingTime, bo.getBindingTime());
lqw.eq(bo.getCommunicationMode() != null, AppDeviceBindRecord::getCommunicationMode, bo.getCommunicationMode());
return lqw; return lqw;
} }

View File

@ -56,4 +56,6 @@ public class AppBusinessFileBo extends BaseEntity {
* 是否使用语音播报0-否1-是) * 是否使用语音播报0-否1-是)
*/ */
private Integer useStatus; private Integer useStatus;
private Long createBy;
} }

View File

@ -209,6 +209,20 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
DeviceTypeGrants typeGrants = new DeviceTypeGrants(); DeviceTypeGrants typeGrants = new DeviceTypeGrants();
// 修改为:
Long userId;
LoginUser loginUser;
try {
loginUser = LoginHelper.getLoginUser();
userId = loginUser != null ? loginUser.getUserId() : 1938143703108689922L; // 如果没有登录用户使用默认系统用户ID
} catch (Exception e) {
userId = 1938143703108689922L; // 出现异常时使用默认系统用户ID
loginUser = new LoginUser();
loginUser.setUserId(userId);
loginUser.setNickname("admin");
loginUser.setTenantId("894078"); // 设置租户ID
}
if (deviceForm.getDeviceType() != null) { if (deviceForm.getDeviceType() != null) {
DeviceTypeQueryCriteria queryCriteria = new DeviceTypeQueryCriteria(); DeviceTypeQueryCriteria queryCriteria = new DeviceTypeQueryCriteria();
queryCriteria.setDeviceTypeId(deviceForm.getDeviceType()); queryCriteria.setDeviceTypeId(deviceForm.getDeviceType());
@ -281,8 +295,8 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
throw new RuntimeException("设备类型名称已存在,无法新增!!!"); throw new RuntimeException("设备类型名称已存在,无法新增!!!");
} }
LoginUser loginUser = LoginHelper.getLoginUser();
newDeviceType.setCreateByName(loginUser.getNickname()); newDeviceType.setCreateByName(loginUser.getNickname());
newDeviceType.setTenantId(loginUser.getTenantId());
deviceTypeMapper.insert(newDeviceType); deviceTypeMapper.insert(newDeviceType);
// 重新查询确保获取到正确的ID // 重新查询确保获取到正确的ID
@ -294,6 +308,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
deviceTypeGrants.setCustomerId(loginUser.getUserId()); deviceTypeGrants.setCustomerId(loginUser.getUserId());
deviceTypeGrants.setGrantorCustomerId(loginUser.getUserId()); deviceTypeGrants.setGrantorCustomerId(loginUser.getUserId());
deviceTypeGrants.setGrantedAt(new Date()); deviceTypeGrants.setGrantedAt(new Date());
deviceTypeGrants.setTenantId(loginUser.getTenantId());
deviceTypeGrantsMapper.insert(deviceTypeGrants); deviceTypeGrantsMapper.insert(deviceTypeGrants);
} }
@ -318,13 +333,13 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
BeanUtil.copyProperties(deviceForm, device, true); BeanUtil.copyProperties(deviceForm, device, true);
device.setDeviceNo(createDeviceNo()); device.setDeviceNo(createDeviceNo());
LoginUser loginUser = LoginHelper.getLoginUser();
device.setCurrentOwnerId(loginUser.getUserId()); device.setCurrentOwnerId(loginUser.getUserId());
device.setOriginalOwnerId(loginUser.getUserId()); device.setOriginalOwnerId(loginUser.getUserId());
device.setCreateByName(loginUser.getNickname()); device.setCreateByName(loginUser.getNickname());
device.setTypeName(deviceType.getTypeName()); device.setTypeName(deviceType.getTypeName());
device.setDeviceType(deviceType.getId()); device.setDeviceType(deviceType.getId());
device.setDevicePic(deviceType.getDevicePic()); device.setDevicePic(deviceType.getDevicePic());
device.setTenantId(loginUser.getTenantId());
if (device.getDeviceImei() != null) { if (device.getDeviceImei() != null) {
device.setPubTopic("A/" + device.getDeviceImei()); device.setPubTopic("A/" + device.getDeviceImei());
device.setSubTopic("B/" + device.getDeviceImei()); device.setSubTopic("B/" + device.getDeviceImei());
@ -336,7 +351,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
// 查询设备类型的文件列表 // 查询设备类型的文件列表
// 4. 核心优化:同步设备类型的文件列表 (一行代码) // 4. 核心优化:同步设备类型的文件列表 (一行代码)
appBusinessFileService.cloneFiles(deviceType.getId(), device.getId()); appBusinessFileService.cloneFiles(deviceType.getId(), device.getId());
//同步设备类型的视频列表 // 同步设备类型的视频列表
appOperationVideoService.cloneFiles(deviceType.getId(), device.getId()); appOperationVideoService.cloneFiles(deviceType.getId(), device.getId());
// 新增设备类型记录 // 新增设备类型记录
@ -351,10 +366,12 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode()); assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
String lever = USER_ID_SEPARATOR + loginUser.getUserId(); String lever = USER_ID_SEPARATOR + loginUser.getUserId();
assignments.setLever(lever); assignments.setLever(lever);
assignments.setTenantId(loginUser.getTenantId());
deviceAssignmentsService.save(assignments); deviceAssignmentsService.save(assignments);
} }
private String createDeviceNo() { private String createDeviceNo() {
String uuidStr = UUID.fastUUID().toString(); // 获取带 - 的标准格式字符串 String uuidStr = UUID.fastUUID().toString(); // 获取带 - 的标准格式字符串
return uuidStr.replaceAll("-", ""); return uuidStr.replaceAll("-", "");

View File

@ -113,14 +113,14 @@ public class AlibabaTTSUtil {
DEFAULT_VOLUME, DEFAULT_SPEECH_RATE, DEFAULT_PITCH_RATE); DEFAULT_VOLUME, DEFAULT_SPEECH_RATE, DEFAULT_PITCH_RATE);
} }
public byte[] synthesizeTextToMp3(String text){ public byte[] synthesizeTextToMp3(String text,String fileSuffix){
try { try {
// 获取访问令牌 // 获取访问令牌
String token = getValidAccessToken(); String token = getValidAccessToken();
// 使用HTTP方式调用 // 使用HTTP方式调用
HttpTtsClient httpClient = new HttpTtsClient(appkey,token); HttpTtsClient httpClient = new HttpTtsClient(appkey,token);
return httpClient.synthesizeTextToMp3(text); return httpClient.synthesizeTextToMp3(text,fileSuffix);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -9,7 +9,9 @@ import java.net.URL;
import static cn.dev33.satoken.SaManager.log; import static cn.dev33.satoken.SaManager.log;
public class HttpTtsClient { public class HttpTtsClient {
private String accessKeyId;
private String accessKeySecret;
private String appKey; private String appKey;
private String token; private String token;
/** /**
@ -17,36 +19,57 @@ public class HttpTtsClient {
*/ */
private static final String BASE_URL = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts"; private static final String BASE_URL = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
public HttpTtsClient(String appKey, String token) { public HttpTtsClient(String accessKeyId, String token) {
this.appKey = appKey; this.accessKeyId = accessKeyId;
this.token = token; this.token = token;
// this.accessKeySecret = accessKeySecret;
// this.appKey = appKey;
} }
// private String refreshAccessToken() {
// try {
// // 调用阿里云API获取访问令牌
// AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
// accessToken.apply();
// String token = accessToken.getToken();
// log.info("访问令牌刷新成功");
//
// return token;
// } catch (Exception e) {
// log.error("刷新访问令牌失败: {}", e.getMessage(), e);
// return null;
// }
// }
/** /**
* 使用HTTP POST方式调用阿里云TTS服务生成MP3格式语音 * 使用HTTP POST方式调用阿里云TTS服务生成MP3格式语音
*/ */
public byte[] synthesizeTextToMp3(String text) throws IOException { public byte[] synthesizeTextToMp3(String text,String fileSuffix) throws IOException {
String endpoint = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts"; // String endpoint = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
// 构建请求体 // 构建请求体
// String requestBody = String.format( // String requestBody = String.format(
// "{\"appkey\":\"%s\",\"text\":\"%s\",\"voice\":\"zhifeng\",\"format\":\"MP3\",\"sample_rate\":24000,\"volume\":50,\"speech_rate\":0,\"pitch_rate\":0}", // "{\"appkey\":\"%s\",\"text\":\"%s\",\"voice\":\"zhifeng\",\"format\":\"MP3\",\"sample_rate\":24000,\"volume\":50,\"speech_rate\":0,\"pitch_rate\":0}",
// appKey, // appKey,
// text.replace("\"", "\\\"") // text.replace("\"", "\\\"")zhide
// ); // );
// String token = refreshAccessToken();
String requestBody = " {\n" + String requestBody = " {\n" +
" \"appkey\":\""+appKey+"\",\n" + " \"appkey\":\""+appKey+"\",\n" +
" \"voice\":\"zhifeng\",\n" +
" \"text\":\""+text+"\",\n" + " \"text\":\""+text+"\",\n" +
" \"token\":\""+token+"\",\n" + " \"token\":\""+token+"\",\n" +
" \"format\":\"mp3\"\n" + " \"volume\": 100,\n" +
" \"pitch_rate\": 0,\n" +
" \"format\":\""+fileSuffix+"\"\n" +
" }"; " }";
URL url = new URL(endpoint); URL url = new URL(BASE_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方法和头部 // 设置请求方法和头部
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Content-Type", "application/json");
// conn.setRequestProperty("Authorization", buildAuthorization()); conn.setRequestProperty("Authorization", buildAuthorization());
conn.setRequestProperty("Content-Length", String.valueOf(requestBody.getBytes().length)); conn.setRequestProperty("Content-Length", String.valueOf(requestBody.getBytes().length));
conn.setDoOutput(true); conn.setDoOutput(true);
@ -72,13 +95,29 @@ public class HttpTtsClient {
throw new IOException("HTTP请求失败状态码: " + responseCode); throw new IOException("HTTP请求失败状态码: " + responseCode);
} }
} }
/**
* 构建授权头部
*/
private String buildAuthorization() {
// 实际实现需要根据阿里云API规范构建签名
// 这里是简化示例
return "Bearer " + generateAccessToken();
}
/**
* 生成访问令牌
*/
private String generateAccessToken() {
// 实际实现需要调用阿里云获取token的API
return "your-access-token";
}
/** /**
* 保存MP3到文件 * 保存MP3到文件
*/ */
public String saveMp3ToFile(String text, String outputPath) throws IOException { public String saveMp3ToFile(String text, String outputPath) throws IOException {
byte[] mp3Data = synthesizeTextToMp3(text); byte[] mp3Data = synthesizeTextToMp3(text,"mp3");
try (FileOutputStream fos = new FileOutputStream(outputPath)) { try (FileOutputStream fos = new FileOutputStream(outputPath)) {
fos.write(mp3Data); fos.write(mp3Data);

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fuyuanshen.app.mapper.AppBusinessFileMapper"> <mapper namespace="com.fuyuanshen.equipment.mapper.AppBusinessFileMapper">
<select id="queryAppFileList" resultType="com.fuyuanshen.equipment.domain.vo.AppFileVo"> <select id="queryAppFileList" resultType="com.fuyuanshen.equipment.domain.vo.AppFileVo">
select a.id,a.business_id,a.file_id,a.file_type,b.file_name,b.url fileUrl,a.duration, select a.id,a.business_id,a.file_id,a.file_type,b.file_name,b.url fileUrl,a.duration,

BIN
generated_speech.wav Normal file

Binary file not shown.

0
log/de_english-words.txt Normal file
View File

0
log/de_unknown.txt Normal file
View File

BIN
公安报警中.wav Normal file

Binary file not shown.