package org.jeecg.modules.iot.service.impl;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.modules.iot.entity.*;
|
import org.jeecg.modules.iot.service.*;
|
import org.jeecg.modules.iot.util.FtpUtil;
|
import org.jeecg.modules.iot.mapper.ServerDeployMapper;
|
import org.jeecg.modules.iot.mqtt.config.MqttCustomerClient;
|
import org.jeecg.modules.iot.util.FileUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.w3c.dom.Document;
|
import org.w3c.dom.Element;
|
|
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.Transformer;
|
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.stream.StreamResult;
|
import java.io.*;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @Description: 项目分类
|
* @Author: cuikaidong
|
* @Date: 2024-12-20
|
* @Version: V1.0
|
*/
|
@Service
|
public class ServerDeployServiceImpl extends ServiceImpl<ServerDeployMapper, ServerDeploy> implements IServerDeployService {
|
@Autowired
|
private IServerDeployService serverDeployService;
|
@Autowired
|
private IInfluxdbDeployService influxdbDeployService;
|
@Autowired
|
private IMqttDeployService mqttDeployService;
|
@Autowired
|
private MqttCustomerClient mqttCustomerClient;
|
@Autowired
|
private IEquipmentService equipmentService;
|
@Autowired
|
private IParameterGroupService parameterGroupService;
|
@Autowired
|
private IRealParameterService realParameterService;
|
@Autowired
|
private IEmptyParameterService emptyParameterService;
|
|
@Override
|
public ServerDeploy findByServerCode(String serverCode) {
|
ServerDeploy serverDeploy = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(ServerDeploy::getServerCode, serverCode)
|
.one();
|
return serverDeploy;
|
}
|
|
@Override
|
public List<ServerDeploy> findByProjectClassifyId(String id) {
|
return new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(ServerDeploy::getProjectClassifyId, id)
|
.list();
|
}
|
|
@Override
|
public void updateServerGuardState(List<MqttClient> mqttClient) {
|
List<ServerDeploy> serverDeploys = serverDeployService.list();
|
serverDeploys.forEach(s -> {
|
s.setGuardState(0);
|
s.setCollectState(0);
|
});
|
serverDeployService.updateBatchById(serverDeploys);
|
// 修改守护程序在线状态
|
if (!mqttClient.isEmpty()) {
|
Set<String> collect = mqttClient.stream().map(MqttClient::getClientid).collect(Collectors.toSet());
|
// 方案一:使用条件判断,避免传入空集合
|
List<ServerDeploy> serverDeployList;
|
if (CollectionUtils.isNotEmpty(collect)) {
|
serverDeployList = new LambdaQueryChainWrapper<>(baseMapper)
|
.in(ServerDeploy::getServerCode, collect)
|
.list();
|
} else {
|
// 集合为空时返回空列表,避免查询
|
serverDeployList = Collections.emptyList();
|
}
|
serverDeployList.forEach(l -> l.setGuardState(1));
|
serverDeployService.updateBatchById(serverDeployList);
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result<?> addDeployDocument(String id) {
|
// 验证FTP连接
|
boolean isConnected = FtpUtil.testFtpConnection();
|
if (!isConnected) {
|
return Result.error("FTP连接失败,请检查配置!");
|
}
|
// 获取当前时间
|
Date now = new Date();
|
// 定义日期格式
|
SimpleDateFormat formatter = new SimpleDateFormat("MMddHHmmss");
|
// 格式化当前时间
|
String formattedDate = formatter.format(now);
|
// 服务器配置
|
ServerDeploy serverDeploy = baseMapper.selectById(id);
|
// Mqtt配置
|
MqttDeploy mqttDeploy = mqttDeployService.findByServerIdMqttDeploy(id);
|
// influxdb配置
|
InfluxdbDeploy influxdbDeploy = influxdbDeployService.findByServerIdInfluxdb(id);
|
if (mqttDeploy == null) {
|
return Result.error("请先配置MQTT服务");
|
}
|
if (influxdbDeploy == null) {
|
return Result.error("请先配置influxdb服务");
|
}
|
|
// 设备信息
|
List<Equipment> equipmentList = equipmentService.findEquipmentByServerId(id);
|
// 参数组信息
|
List<ParameterGroup> parameterGroups = parameterGroupService.findParameterGroupByServerId(id);
|
// 实设备参数
|
List<RealParameter> realParameters = new ArrayList<>();
|
if (!CollectionUtils.isEmpty(parameterGroups)) {
|
Set<String> parameterGroupIds = parameterGroups.stream().map(ParameterGroup::getId).collect(Collectors.toSet());
|
realParameters = realParameterService.findRealParameterByIds(parameterGroupIds);
|
}
|
// 虚设备参数
|
List<EmptyParameter> emptyParameters = new ArrayList<>();
|
if (!CollectionUtils.isEmpty(equipmentList)) {
|
Set<String> equipmentIds = equipmentList.stream().map(Equipment::getId).collect(Collectors.toSet());
|
emptyParameters = emptyParameterService.findParameterByEquipmentIds(equipmentIds);
|
}
|
try {
|
// 创建解析器工厂
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilder db = factory.newDocumentBuilder();
|
Document document = db.newDocument();
|
// 不显示standalone="no"
|
document.setXmlStandalone(true);
|
Element bookstore = document.createElement("ServiceInfo");
|
// 为bookstore节点添加属性
|
bookstore.setAttribute("ID", serverDeploy.getServerCode());
|
bookstore.setAttribute("Name", serverDeploy.getServerName());
|
bookstore.setAttribute("IP", serverDeploy.getServerAddress());
|
bookstore.setAttribute("Port", serverDeploy.getServerPort());
|
bookstore.setAttribute("FileVersion", serverDeploy.getLatestCollectVersion());
|
bookstore.setAttribute("ParameterVersion", formattedDate);
|
// 向bookstore根节点中添加子节点book
|
// 授权信息
|
Element authorize = document.createElement("Authorize");
|
// 为authorize节点添加属性
|
authorize.setAttribute("Licence", serverDeploy.getAuthorize());
|
// 将book节点添加到bookstore根节点中
|
bookstore.appendChild(authorize);
|
// 接口信息
|
Element Interface = document.createElement("Interface");
|
Element mqttService = document.createElement("MqttService");
|
// 为Interface节点添加属性
|
if (mqttDeploy != null) {
|
mqttService.setAttribute("IP", mqttDeploy.getAddress());
|
mqttService.setAttribute("Port", mqttDeploy.getPort().toString());
|
mqttService.setAttribute("ClientID", mqttDeploy.getClintId());
|
mqttService.setAttribute("User", mqttDeploy.getUserName());
|
mqttService.setAttribute("PassWord", mqttDeploy.getUserPassword());
|
} else {
|
mqttService.setAttribute("IP", "");
|
mqttService.setAttribute("Port", "");
|
mqttService.setAttribute("ClientID", "");
|
mqttService.setAttribute("User", "");
|
mqttService.setAttribute("PassWord", "");
|
}
|
Element timingLibrary = document.createElement("TimingLibrary");
|
if (influxdbDeploy != null) {
|
timingLibrary.setAttribute("IP", influxdbDeploy.getAddress());
|
timingLibrary.setAttribute("Port", influxdbDeploy.getPort().toString());
|
timingLibrary.setAttribute("Bucket", influxdbDeploy.getBucket());
|
timingLibrary.setAttribute("Org", influxdbDeploy.getOrganization());
|
timingLibrary.setAttribute("Token", influxdbDeploy.getAuthorizeCode());
|
} else {
|
timingLibrary.setAttribute("IP", "");
|
timingLibrary.setAttribute("Port", "");
|
timingLibrary.setAttribute("Bucket", "");
|
timingLibrary.setAttribute("Org", "");
|
timingLibrary.setAttribute("Token", "");
|
}
|
Interface.appendChild(mqttService);
|
Interface.appendChild(timingLibrary);
|
// 实设备,虚设备信息
|
Element deviceInfos = document.createElement("DeviceInfos");
|
// 添加属性
|
deviceInfos.setAttribute("WriteMessage", "IOT/" + serverDeploy.getServerCode() + "/WriteMessage");
|
// 实设备列表节点
|
Element actualDevices = document.createElement("ActualDevices");
|
// 虚设备列表节点
|
Element virtualDevices = document.createElement("VirtualDevices");
|
// 遍历设备信息
|
List<RealParameter> finalRealParameters = realParameters;
|
List<EmptyParameter> finalEmptyParameters = emptyParameters;
|
equipmentList.forEach(e -> {
|
if (e.getEquipmentType().equals(1)) {
|
Element deviceInfo = document.createElement("DeviceInfo"); // 设备节点
|
deviceInfo.setAttribute("ID", e.getEqptCode());
|
deviceInfo.setAttribute("Name", e.getEqptName());
|
deviceInfo.setAttribute("Model", e.getEqptModel());
|
deviceInfo.setAttribute("Type", e.getEqptType());
|
deviceInfo.setAttribute("Describe", e.getEqptDescribe());
|
deviceInfo.setAttribute("ControlSystem", e.getControlSystem());
|
deviceInfo.setAttribute("Protocol", e.getProtocol());
|
deviceInfo.setAttribute("DriveType", e.getDriveType());
|
deviceInfo.setAttribute("Address", e.getAddress());
|
deviceInfo.setAttribute("LibraryName", e.getLibraryName());
|
deviceInfo.setAttribute("Class", e.getClassName());
|
deviceInfo.setAttribute("LibraryVersion", e.getLibraryVersion());
|
deviceInfo.setAttribute("CollectionCycle", e.getCollectionCycle());
|
deviceInfo.setAttribute("ReconnectCycle", e.getReconnectCycle());
|
deviceInfo.setAttribute("IsCollection", e.getIsCollection());
|
deviceInfo.setAttribute("FloatPosition", e.getFloatPosition());
|
deviceInfo.setAttribute("ReadTopic", e.getReadTopic());
|
deviceInfo.setAttribute("WriteTopic", e.getWriteTopic());
|
actualDevices.appendChild(deviceInfo);
|
// 参数组信息
|
parameterGroups.forEach(p -> {
|
if (p.getEquipmentId().equals(e.getId())) {
|
Element groupInfo = document.createElement("GroupInfo"); // 参数组节点
|
groupInfo.setAttribute("ID", p.getCode());
|
groupInfo.setAttribute("Name", p.getName());
|
groupInfo.setAttribute("Describe", p.getRemark());
|
groupInfo.setAttribute("CollectionCycle", p.getCollectionCycle());
|
deviceInfo.appendChild(groupInfo);
|
if (!CollectionUtils.isEmpty(finalRealParameters)) {
|
finalRealParameters.forEach(r -> {
|
if (p.getId().equals(r.getParameterGroupId())) {
|
Element tagInfo = document.createElement("TagInfo"); // 参数节点
|
tagInfo.setAttribute("ID", r.getParameterCode().toString());
|
tagInfo.setAttribute("Name", r.getParameterName());
|
tagInfo.setAttribute("Address", r.getAddress());
|
tagInfo.setAttribute("DataType", r.getParameterType());
|
if (r.getReadWriteType().equals("只读")){
|
tagInfo.setAttribute("ReadOrWrite", "R");
|
}else{
|
tagInfo.setAttribute("ReadOrWrite", "R/W");
|
}
|
tagInfo.setAttribute("Describe", r.getParameterDescribe());
|
tagInfo.setAttribute("TagType", "OutsideTag");
|
tagInfo.setAttribute("DataLength", r.getDataLength() + "");
|
groupInfo.appendChild(tagInfo);
|
}
|
});
|
}
|
}
|
});
|
} else if (e.getEquipmentType().equals(0)) {
|
Element emptyDeviceInfo = document.createElement("DeviceInfo"); // 设备节点
|
emptyDeviceInfo.setAttribute("ID", e.getEqptCode());
|
emptyDeviceInfo.setAttribute("Name", e.getEqptName());
|
if (e.getIsCollection().equals("1")) {
|
emptyDeviceInfo.setAttribute("IsCollection", "Y");
|
} else {
|
emptyDeviceInfo.setAttribute("IsCollection", "N");
|
}
|
emptyDeviceInfo.setAttribute("Remarks", e.getRemark());
|
emptyDeviceInfo.setAttribute("ReadTopic", e.getReadTopic());
|
emptyDeviceInfo.setAttribute("Measurement", e.getWriteTopic());
|
virtualDevices.appendChild(emptyDeviceInfo);
|
// 参数信息
|
if (!CollectionUtils.isEmpty(equipmentList)) {
|
finalEmptyParameters.forEach(empty -> {
|
if (empty.getEquipmentId().equals(e.getId())) {
|
Element tagInfo = document.createElement("TagInfo"); // 参数节点
|
tagInfo.setAttribute("ID", empty.getParameterCode() + "");
|
tagInfo.setAttribute("Name", empty.getParameterName());
|
tagInfo.setAttribute("SourcePath", empty.getAddress());
|
tagInfo.setAttribute("DataType", empty.getParameterType());
|
if (empty.getReadWriteType().equals("只读")) {
|
tagInfo.setAttribute("ReadOrWrite", "R");
|
} else {
|
tagInfo.setAttribute("ReadOrWrite", "R/W");
|
}
|
tagInfo.setAttribute("Describe", empty.getParameterDescribe());
|
if (empty.getType().equals("1")) {
|
tagInfo.setAttribute("TagType", "InsideTag");
|
} else {
|
tagInfo.setAttribute("TagType", "CustomTag");
|
}
|
tagInfo.setAttribute("ScriptName", ""); // 脚本名称
|
tagInfo.setAttribute("ScriptTagList", empty.getScriptTagList());// 脚本地址
|
tagInfo.setAttribute("DataLength", empty.getDataLength());
|
emptyDeviceInfo.appendChild(tagInfo);
|
}
|
});
|
}
|
}
|
});
|
// 遍历参数组信息
|
// 遍历参数信息
|
deviceInfos.appendChild(actualDevices); // 给实设备,虚设备信息添加子节点
|
deviceInfos.appendChild(virtualDevices); // 给实设备,虚设备信息添加子节点
|
bookstore.appendChild(Interface);
|
bookstore.appendChild(deviceInfos);
|
// 将bookstore节点(已包含book)添加到dom树中
|
document.appendChild(bookstore);
|
// 创建TransformerFactory对象
|
TransformerFactory tff = TransformerFactory.newInstance();
|
// 创建 Transformer对象
|
Transformer tf = tff.newTransformer();
|
// 输出内容是否使用换行
|
tf.setOutputProperty(OutputKeys.ENCODING, "GB2312");
|
tf.setOutputProperty(OutputKeys.INDENT, "yes");
|
// 创建xml文件并写入内容
|
tf.transform(new DOMSource(document), new StreamResult(new File("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx")));
|
// 创建写库表结构查询虚设备列表,增加设备表
|
equipmentService.createEmptyEquipmentTable(serverDeploy.getDeployIssueTime(),serverDeploy.getId());
|
// 查询虚设备参数,增加字段
|
emptyParameterService.createEmptyEmptyField(serverDeploy.getDeployIssueTime(),serverDeploy.getId());
|
} catch (Exception e) {
|
e.printStackTrace();
|
return Result.error("配置文件生成失败");
|
}
|
// 更新版本
|
serverDeploy.setLatestDeployVersion(formattedDate);
|
serverDeploy.setDeployIssueTime(new Date());
|
baseMapper.updateById(serverDeploy);
|
// 生成本地文件夹
|
// FileUtil.createDir("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
|
FileUtil.createDir("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/script");
|
// 上传到ftp
|
String basePath = "/deploy"; // FTP服务器基础目录
|
String filePath = serverDeploy.getServerCode() + "/deploy/" + formattedDate; // FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
|
String filename = "CollectionConfiguration.lmx";// 上传到FTP服务器上的文件名
|
//创建一个输入流
|
try {
|
FileInputStream fileInputStream = new FileInputStream("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx");
|
FtpUtil.uploadFile(basePath, filePath, filename, fileInputStream);
|
} catch (FileNotFoundException e) {
|
e.printStackTrace();
|
}
|
// 存储脚本,复制整个文件夹
|
FtpUtil.uploadFolder(new File("D:/iot/"+serverDeploy.getServerCode()+"/script/"), "/deploy/"+serverDeploy.getServerCode()+"/deploy/"+formattedDate+"/script");
|
// 生成脚本
|
// 发送配置文件版信号
|
MqttParameter mqttParameter = new MqttParameter();
|
mqttParameter.setId(serverDeploy.getServerCode());
|
mqttParameter.setType("version");
|
mqttParameter.setParameter2(formattedDate);
|
mqttParameter.setParameter4(basePath +"/" +filePath);
|
mqttCustomerClient.pushlish(2, false, serverDeploy.getServerCode(), mqttParameter);
|
return Result.ok("配置文件生成成功");
|
}
|
}
|