Compare commits
6 Commits
dev_new_co
...
dev_system
| Author | SHA1 | Date | |
|---|---|---|---|
| 372b1a2d11 | |||
| e57699dbdf | |||
| 9e3ec6a1dd | |||
| 11984316d4 | |||
| 11e209bcb3 | |||
| bde6b89965 |
@@ -0,0 +1,53 @@
|
||||
package com.maibu.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.domain.entity.SysParam;
|
||||
import com.maibu.service.SysParamService;
|
||||
|
||||
/**
|
||||
* 系统参数管理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/param")
|
||||
public class SysParamController extends BaseController {
|
||||
@Autowired
|
||||
private SysParamService sysParamService;
|
||||
|
||||
/**
|
||||
* 查询系统参数列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list() {
|
||||
try {
|
||||
return AjaxResult.success(sysParamService.list());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或者修改系统参数
|
||||
*/
|
||||
|
||||
@PostMapping("/save")
|
||||
public AjaxResult save(@RequestBody List<SysParam> sysParams) {
|
||||
try {
|
||||
return AjaxResult.success(sysParamService.save(sysParams));
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("新增修改系统参数出错", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,28 @@
|
||||
system.param.systemName.name = 系统名称
|
||||
system.param.systemName.desc = 系统名称
|
||||
|
||||
system.param.defaultStationName.name = 默认场站
|
||||
system.param.defaultStationName.desc = "默认场站
|
||||
|
||||
system.param.defaultLanguage.name = 默认语言
|
||||
system.param.defaultLanguage.desc = 默认语言
|
||||
|
||||
system.param.defaultZoneId.name = 默认时区
|
||||
system.param.defaultZoneId.desc = 默认时区
|
||||
|
||||
system.param.daylightSavingTime.name = 夏令时
|
||||
system.param.daylightSavingTime.desc = 夏令时
|
||||
|
||||
system.param.defaultUnit.name = 默认单位
|
||||
system.param.defaultUnit.desc = 默认单位
|
||||
|
||||
system.param.defaultDateFormat.name = 默认日期格式
|
||||
system.param.defaultDateFormat.desc = 默认日期格式
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#\u9519\u8BEF\u6D88\u606F
|
||||
not.null=* \u5FC5\u987B\u586B\u5199
|
||||
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
system.param.systemName.name = System Name
|
||||
system.param.systemName.desc = System Name
|
||||
|
||||
system.param.defaultStationName.name = Default Station
|
||||
system.param.defaultStationName.desc = Default Station
|
||||
|
||||
system.param.defaultLanguage.name = Default Language
|
||||
system.param.defaultLanguage.desc = Default Language
|
||||
|
||||
system.param.defaultZoneId.name = Default Zone
|
||||
system.param.defaultZoneId.desc = Default Zone
|
||||
|
||||
system.param.daylightSavingTime.name = Daylight Saving Time
|
||||
system.param.daylightSavingTime.desc = Daylight Saving Time
|
||||
|
||||
system.param.defaultUnit.name = Default Unit
|
||||
system.param.defaultUnit.desc = Default Unit
|
||||
|
||||
system.param.defaultDateFormat.name = Default Date Format
|
||||
system.param.defaultDateFormat.desc = Default Date Format
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#\u9519\u8BEF\u6D88\u606F
|
||||
not.null=* \u5FC5\u987B\u586B\u5199
|
||||
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
system.param.systemName.name = 系统名称
|
||||
system.param.systemName.desc = 系统名称
|
||||
|
||||
system.param.defaultStationName.name = 默认场站
|
||||
system.param.defaultStationName.desc = "默认场站
|
||||
|
||||
system.param.defaultLanguage.name = 默认语言
|
||||
system.param.defaultLanguage.desc = 默认语言
|
||||
|
||||
system.param.defaultZoneId.name = 默认时区
|
||||
system.param.defaultZoneId.desc = 默认时区
|
||||
|
||||
system.param.daylightSavingTime.name = 夏令时
|
||||
system.param.daylightSavingTime.desc = 夏令时
|
||||
|
||||
system.param.defaultUnit.name = 默认单位
|
||||
system.param.defaultUnit.desc = 默认单位
|
||||
|
||||
system.param.defaultDateFormat.name = 默认日期格式
|
||||
system.param.defaultDateFormat.desc = 默认日期格式
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#\u9519\u8BEF\u6D88\u606F
|
||||
not.null=* \u5FC5\u987B\u586B\u5199
|
||||
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package com.maibu.constant;
|
||||
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.enums.ConnectionCloseReason;
|
||||
import io.netty.util.AttributeKey;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Data
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.enums.ConnectionCloseReason;
|
||||
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
|
||||
public class Constant {
|
||||
|
||||
public static final AttributeKey<String> ATT_DEVICE_ID = AttributeKey.valueOf("deviceId");
|
||||
|
||||
public static final AttributeKey<CompletableFuture<DeviceRunParam>> READ_CONFIG_KEY =
|
||||
AttributeKey.valueOf("READ_CONFIG");
|
||||
public static final AttributeKey<CompletableFuture<DeviceRunParam>> READ_CONFIG_KEY = AttributeKey
|
||||
.valueOf("READ_CONFIG");
|
||||
|
||||
public static final AttributeKey<ConnectionCloseReason> ATT_CLOSE_REASON = AttributeKey.valueOf("closeReason");
|
||||
|
||||
@@ -27,5 +27,10 @@ public class Constant {
|
||||
|
||||
public static final String mqttHandleKey = "hostHandle";
|
||||
|
||||
public static final Long hostOfflineInterval = 10000L; //单位毫秒
|
||||
public static final Long hostOfflineInterval = 10000L; // 单位毫秒
|
||||
|
||||
// ==================== 远程控制 ====================
|
||||
public static final String protocol_version = "1.4.3";
|
||||
public static final String remote_control_msg_prefix = "remote-msg";
|
||||
public static final String remote_control_cmd_prefix = "remote-cmd";
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.maibu.annotation.Excel;
|
||||
import com.maibu.constant.CommandConstant;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "iot_device_run_param", autoResultMap = true)
|
||||
@@ -25,366 +22,440 @@ public class DeviceRunParam extends BaseDO {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
// private String deviceId;
|
||||
// private String deviceId;
|
||||
|
||||
private Long siteId;
|
||||
|
||||
private Long orgId;
|
||||
|
||||
private Integer runSpeed; //不下发到设备自己用
|
||||
private Integer runSpeed; // 不下发到设备自己用
|
||||
|
||||
@Excel(name = "设备序列号", cellType = Excel.ColumnType.STRING, prompt = "设备序列号")
|
||||
private String deviceId;//设备序列号
|
||||
private String deviceId;// 设备序列号
|
||||
|
||||
@Excel(name = "产品型号", cellType = Excel.ColumnType.STRING, prompt = "产品型号")
|
||||
private String productModel;//产品型号
|
||||
private String productModel;// 产品型号
|
||||
|
||||
@Excel(name = "设备类型", cellType = Excel.ColumnType.STRING, prompt = "设备类型")
|
||||
private String deviceType;//设备类型:mower-割草机器人
|
||||
private String deviceType;// 设备类型:mower-割草机器人
|
||||
|
||||
@Excel(name = "RTK模式", cellType = Excel.ColumnType.STRING, prompt = "RTK模式")
|
||||
private String rtkMode;//RTK模式:network-4G网络差分
|
||||
private String rtkMode;// RTK模式:network-4G网络差分
|
||||
|
||||
@Excel(name = "摄像头数量", cellType = Excel.ColumnType.STRING, prompt = "摄像头数量")
|
||||
private Integer cameraNum;//摄像头数量
|
||||
private Integer cameraNum;// 摄像头数量
|
||||
|
||||
@Excel(name = "动力类型", cellType = Excel.ColumnType.STRING, prompt = "动力类型")
|
||||
private String powerType;//动力类型:hybrid-混动
|
||||
private String powerType;// 动力类型:hybrid-混动
|
||||
|
||||
@Excel(name = "车轮类型", cellType = Excel.ColumnType.STRING, prompt = "车轮类型")
|
||||
private String wheelType;//车轮类型:track-履带式
|
||||
private String wheelType;// 车轮类型:track-履带式
|
||||
|
||||
@Excel(name = "发动机类型", cellType = Excel.ColumnType.STRING, prompt = "发动机类型")
|
||||
private String engineType;//发动机类型:honda-本田发动机
|
||||
private String engineType;// 发动机类型:honda-本田发动机
|
||||
|
||||
@Excel(name = "是否搭载上位机",cellType = Excel.ColumnType.NUMERIC)
|
||||
private Integer hasHost = 1;//是否搭载上位机
|
||||
@Excel(name = "是否搭载上位机", cellType = Excel.ColumnType.NUMERIC)
|
||||
private Integer hasHost = 1;// 是否搭载上位机
|
||||
|
||||
@Excel(name = "设备能力列表")
|
||||
@TableField(exist = false)
|
||||
private String capabilities;
|
||||
|
||||
private String factoryCode; // 工厂码
|
||||
|
||||
private String lineNum;// 产线号
|
||||
|
||||
private LocalDate productionDate;// 生产日期
|
||||
|
||||
private String serialNumber;// 流水号
|
||||
|
||||
@Excel(name = "电池类型", cellType = Excel.ColumnType.STRING, prompt = "电池类型")
|
||||
private String batteryType;// 电池类型
|
||||
|
||||
@Excel(name = "行走驱动类型", cellType = Excel.ColumnType.STRING, prompt = "行走驱动类型")
|
||||
private String walkingDriveType;// 行走驱动类型
|
||||
|
||||
@Excel(name = "割刀驱动类型", cellType = Excel.ColumnType.STRING, prompt = "割刀驱动类型")
|
||||
private String cutterDriveType;// 割刀驱动类型
|
||||
|
||||
@Excel(name = "RTK天线数", cellType = Excel.ColumnType.STRING, prompt = "RTK天线数")
|
||||
private String rtkAntennasNum;// RTK天线数
|
||||
|
||||
@Excel(name = "手柄类型", cellType = Excel.ColumnType.STRING, prompt = "手柄类型")
|
||||
private String handleType;// 手柄类型
|
||||
|
||||
@Excel(name = "PCB硬件版本", cellType = Excel.ColumnType.STRING, prompt = "PCB硬件版本")
|
||||
private String pcbVersion;// PCB硬件版本
|
||||
|
||||
@Excel(name = "长宽高", cellType = Excel.ColumnType.STRING, prompt = "长宽高")
|
||||
private String dimensions;// 长宽高
|
||||
|
||||
@Excel(name = "割刀宽度", cellType = Excel.ColumnType.STRING, prompt = "割刀宽度")
|
||||
private String bladeWidth;// 割刀宽度
|
||||
|
||||
@Excel(name = "轮胎尺寸", cellType = Excel.ColumnType.STRING, prompt = "轮胎尺寸")
|
||||
private String tyreSize;// 轮胎尺寸
|
||||
|
||||
@Excel(name = "转速比", cellType = Excel.ColumnType.STRING, prompt = "转速比")
|
||||
private String speedRatio;// 转速比
|
||||
|
||||
@Excel(name = "蜂窝网络通信信息", cellType = Excel.ColumnType.STRING, prompt = "蜂窝网络通信信息")
|
||||
private String cellularInfo;// 蜂窝网络通信信息
|
||||
|
||||
@Excel(name = "wifi名称", cellType = Excel.ColumnType.STRING, prompt = "wifi名称")
|
||||
private String wifiName;// wifi名称
|
||||
|
||||
@Excel(name = "蓝牙广播名", cellType = Excel.ColumnType.STRING, prompt = "蓝牙广播名")
|
||||
private String bluetoothName;// 蓝牙广播名
|
||||
|
||||
@Excel(name = "硬件标识信息", cellType = Excel.ColumnType.STRING, prompt = "硬件标识信息")
|
||||
private String hardwareIdentifiers;// 硬件标识信息
|
||||
|
||||
@Excel(name = "IMU型号", cellType = Excel.ColumnType.STRING, prompt = "IMU型号")
|
||||
private String imuModel;// IMU型号
|
||||
|
||||
@Excel(name = "温湿度传感器", cellType = Excel.ColumnType.STRING, prompt = "温湿度传感器")
|
||||
private String tempHumiditySensor;// 温湿度传感器
|
||||
|
||||
@Excel(name = "气压计在位", cellType = Excel.ColumnType.STRING, prompt = "气压计在位")
|
||||
private String barometerPresent;// 气压计在位
|
||||
|
||||
@Excel(name = "超声波在位", cellType = Excel.ColumnType.STRING, prompt = "超声波在位")
|
||||
private String ultrasonicPresent;// 超声波在位
|
||||
|
||||
@Excel(name = "DAC在位", cellType = Excel.ColumnType.STRING, prompt = "DAC在位")
|
||||
private String dacPresent;// DAC在位
|
||||
|
||||
@Excel(name = "质检员", cellType = Excel.ColumnType.STRING, prompt = "质检员")
|
||||
private String operator;// 质检员
|
||||
|
||||
@Excel(name = "检测报告号", cellType = Excel.ColumnType.STRING, prompt = "检测报告号")
|
||||
private String inspectionNo;// 检测报告号
|
||||
|
||||
@Excel(name = "固件版本", cellType = Excel.ColumnType.STRING, prompt = "固件版本")
|
||||
private String firmwareVersion;// 固件版本
|
||||
|
||||
@Excel(name = "经销商", cellType = Excel.ColumnType.STRING, prompt = "经销商")
|
||||
private String dealer;// DAC在位
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<String> capabilityList;//设备能力列表:heartbeat-上报心跳/location-上报位置/vehicle_status-上报整机状态/task_control-任务控制/single_point-单点作业/coverage-全覆盖割草作业/path_upload-作业路径上传
|
||||
private List<String> capabilityList;// 设备能力列表:heartbeat-上报心跳/location-上报位置/vehicle_status-上报整机状态/task_control-任务控制/single_point-单点作业/coverage-全覆盖割草作业/path_upload-作业路径上传
|
||||
|
||||
// @TableField(exist = false)
|
||||
// public byte header1;
|
||||
// @TableField(exist = false)
|
||||
// public byte header2;
|
||||
// @TableField(exist = false)
|
||||
// public byte cmd;
|
||||
|
||||
// public byte chipUidSign;// 芯片UID固化标志位
|
||||
// public String chipUid;// 芯片UID
|
||||
|
||||
// public byte[] remoteConfig;// 遥控器通道配置
|
||||
// public int knifeMotorMode;// 割刀电机模式
|
||||
// public int walkMotorMode;// 行走电机模式
|
||||
// public int leftMotorReverse;// 左轮电机方向极性
|
||||
// public int rightMotorReverse;// 右轮电机方向极性
|
||||
// public int swapChannel;// 左右轮通道互换标志位
|
||||
// public int use4G;// 联网标志位
|
||||
|
||||
// public short forwardSpeedLimit;// 前进速度限制
|
||||
// public short turnSpeedLimit;// 转向速度限制
|
||||
|
||||
// public int knifePolarity;// 割刀通道极性
|
||||
// public int fanPolarity;// 风门通道极性
|
||||
// public int throttlePolarity;// 油门通道极性
|
||||
// public int liftProtectTime;// 底盘升降电机保护时间
|
||||
// public int dualRtk;// RTK配置
|
||||
|
||||
// public int knifeChannel;// 割刀通道配置
|
||||
// public int fanChannel;// 风门通道配置
|
||||
|
||||
// public int throttleChannel;// 油门通道配置
|
||||
// public int remoteType;// 遥控器类型
|
||||
// public boolean relayBoard;// 是否搭载继电器板
|
||||
|
||||
// public int liftChannel;// 底盘升通道配置
|
||||
// public int chassisChannel;// 底盘降通道配置
|
||||
|
||||
// public int armChannel;// 抱闸通道配置
|
||||
// public int fuelPumpChannel;// 燃油励磁通道配置
|
||||
|
||||
// public String wifiName;// wifi名称
|
||||
// public String wifiPassword;// wifi密码
|
||||
|
||||
// public int batteryType;// 电池类型
|
||||
// public int driveType;// 行走驱动配置
|
||||
|
||||
// public float gearRatio;// 转速比
|
||||
// public float robotLength;// 机器人长度
|
||||
// public float robotWidth;// 机器人宽度
|
||||
// public float robotHeight;// 机器人高度
|
||||
// public float knifeWidth;// 割刀宽度
|
||||
// public float tyreSize;// 轮胎尺寸
|
||||
// public float leftForwardGain;// 左轮前进增益
|
||||
// public float leftBackwardGain;// 左轮后退增益
|
||||
// public float rightForwardGain;// 右轮前进增益
|
||||
// public float rightBackwardGain;// 右轮后退增益
|
||||
|
||||
// public String firmwareVersion;// 固件版本
|
||||
// @TableField(exist = false)
|
||||
// public int crc16;
|
||||
// @TableField(exist = false)
|
||||
// public byte tail1;
|
||||
// @TableField(exist = false)
|
||||
// public byte tail2;
|
||||
// @TableField(exist = false)
|
||||
// private byte[] originalData;
|
||||
|
||||
// public static byte[] toReadBytes() {
|
||||
// ByteBuffer buffer = ByteBuffer.allocate(7); // 修改为27字节
|
||||
// buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// buffer.put((byte) 0xAB);
|
||||
// buffer.put((byte) 0xAA);
|
||||
|
||||
// buffer.put(CommandConstant.readConfig);
|
||||
|
||||
// buffer.putShort((short) 0);
|
||||
|
||||
// buffer.put((byte) 0xAA);
|
||||
// buffer.put((byte) 0xAB);
|
||||
|
||||
// return buffer.array();
|
||||
// }
|
||||
|
||||
// public byte[] toWriteBytes() {
|
||||
// // 如果没有原始数据,使用静态方法重新构建
|
||||
// if (originalData == null || originalData.length < 178) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// // 克隆原始数据,避免修改原始数据
|
||||
// byte[] result = originalData.clone();
|
||||
// ByteBuffer buffer = ByteBuffer.wrap(result);
|
||||
// buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// // 修改指令为写配置(字节2)
|
||||
// buffer.put(2, CommandConstant.writeConfig);
|
||||
|
||||
// // 修改字节68:遥控器配置
|
||||
// byte remote = 0;
|
||||
// remote |= (getKnifeMotorMode() & 0x03);
|
||||
// remote |= (getWalkMotorMode() & 0x03) << 2;
|
||||
// remote |= (getLeftMotorReverse() & 0x01) << 4;
|
||||
// remote |= (getRightMotorReverse() & 0x01) << 5;
|
||||
// remote |= (getSwapChannel() & 0x01) << 6;
|
||||
// remote |= (getUse4G() & 0x01) << 7;
|
||||
// buffer.put(68, remote);
|
||||
|
||||
// // 修改字节69-72:速度限制
|
||||
// buffer.putShort(69, getForwardSpeedLimit());
|
||||
// buffer.putShort(71, getTurnSpeedLimit());
|
||||
|
||||
// // 修改字节73:通道极性
|
||||
// byte b73 = 0;
|
||||
// b73 |= (getKnifePolarity() & 1);
|
||||
// b73 |= (getFanPolarity() & 1) << 1;
|
||||
// b73 |= (getThrottlePolarity() & 1) << 2;
|
||||
// b73 |= (getLiftProtectTime() & 0x0F) << 3;
|
||||
// b73 |= (getDualRtk() & 1) << 7;
|
||||
// buffer.put(73, b73);
|
||||
|
||||
// // 修改字节74-77:通道配置
|
||||
// byte b74 = 0;
|
||||
// b74 |= (getKnifeChannel() & 0x0F);
|
||||
// b74 |= (getFanChannel() & 0x0F) << 4;
|
||||
// buffer.put(74, b74);
|
||||
|
||||
// byte b75 = 0;
|
||||
// b75 |= (getThrottleChannel() & 0x0F);
|
||||
// b75 |= (getRemoteType() & 0x07) << 4;
|
||||
// if (isRelayBoard())
|
||||
// b75 |= 1 << 7;
|
||||
// buffer.put(75, b75);
|
||||
|
||||
// byte b76 = 0;
|
||||
// b76 |= (getLiftChannel() & 0x0F);
|
||||
// b76 |= (getChassisChannel() & 0x0F) << 4;
|
||||
// buffer.put(76, b76);
|
||||
|
||||
// byte b77 = 0;
|
||||
// b77 |= (getArmChannel() & 0x0F);
|
||||
// b77 |= (getFuelPumpChannel() & 0x0F) << 4;
|
||||
// buffer.put(77, b77);
|
||||
|
||||
// // // 修改字节78-117:WiFi信息
|
||||
// // byte[] wifiNameBytes = new byte[20];
|
||||
// // if (getWifiName() != null) {
|
||||
// // byte[] src = getWifiName().getBytes(StandardCharsets.UTF_8);
|
||||
// // System.arraycopy(src, 0, wifiNameBytes, 0, Math.min(src.length, 20));
|
||||
// // }
|
||||
// // System.arraycopy(wifiNameBytes, 0, result, 78, 20);
|
||||
// //
|
||||
// // byte[] wifiPwdBytes = new byte[20];
|
||||
// // if (getWifiPassword() != null) {
|
||||
// // byte[] src = getWifiPassword().getBytes(StandardCharsets.UTF_8);
|
||||
// // System.arraycopy(src, 0, wifiPwdBytes, 0, Math.min(src.length, 20));
|
||||
// // }
|
||||
// // System.arraycopy(wifiPwdBytes, 0, result, 98, 20);
|
||||
|
||||
// // // 修改字节118:电池和驱动配置
|
||||
// // byte b118 = 0;
|
||||
// // b118 |= (getBatteryType() & 0x03);
|
||||
// // b118 |= (getDriveType() & 0x03) << 2;
|
||||
// // buffer.put(118, b118);
|
||||
|
||||
// // 修改字节119-158:float参数
|
||||
// buffer.putFloat(119, getGearRatio());
|
||||
// buffer.putFloat(123, getRobotLength());
|
||||
// buffer.putFloat(127, getRobotWidth());
|
||||
// buffer.putFloat(131, getRobotHeight());
|
||||
// buffer.putFloat(135, getKnifeWidth());
|
||||
// buffer.putFloat(139, getTyreSize());
|
||||
// buffer.putFloat(143, getLeftForwardGain());
|
||||
// buffer.putFloat(147, getLeftBackwardGain());
|
||||
// buffer.putFloat(151, getRightForwardGain());
|
||||
// buffer.putFloat(155, getRightBackwardGain());
|
||||
|
||||
// // 修改字节159-173:固件版本
|
||||
// // byte[] fwBytes = new byte[15];
|
||||
// // if (getFirmwareVersion() != null) {
|
||||
// // byte[] src = getFirmwareVersion().getBytes(StandardCharsets.UTF_8);
|
||||
// // System.arraycopy(src, 0, fwBytes, 0, Math.min(src.length, 15));
|
||||
// // }
|
||||
// // System.arraycopy(fwBytes, 0, result, 159, 15);
|
||||
|
||||
// // 保留原始的 CRC 和尾部,不强制修改
|
||||
// // 移除以下强制修改:
|
||||
// // buffer.putShort(174, (short) 0);
|
||||
// // buffer.put(176, (byte) 0xAA);
|
||||
// // buffer.put(177, (byte) 0xAB);
|
||||
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// public static void putFixedString(ByteBuffer buffer, String value, int len) {
|
||||
|
||||
// byte[] bytes = new byte[len];
|
||||
|
||||
// if (value != null) {
|
||||
// byte[] src = value.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
// System.arraycopy(src, 0, bytes, 0, Math.min(src.length, len));
|
||||
// }
|
||||
|
||||
// buffer.put(bytes);
|
||||
// }
|
||||
|
||||
// public static DeviceRunParam fromBytes(byte[] data) {
|
||||
// // 183
|
||||
// if (data == null || data.length < 178) {
|
||||
// throw new IllegalArgumentException("数据长度不足");
|
||||
// }
|
||||
|
||||
// ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
// buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// DeviceRunParam p = new DeviceRunParam();
|
||||
|
||||
// p.setOriginalData(data);
|
||||
|
||||
@TableField(exist = false)
|
||||
public byte header1;
|
||||
@TableField(exist = false)
|
||||
public byte header2;
|
||||
@TableField(exist = false)
|
||||
public byte cmd;
|
||||
|
||||
|
||||
public byte chipUidSign;//芯片UID固化标志位
|
||||
public String chipUid;//芯片UID
|
||||
|
||||
public byte[] remoteConfig;//遥控器通道配置
|
||||
public int knifeMotorMode;//割刀电机模式
|
||||
public int walkMotorMode;//行走电机模式
|
||||
public int leftMotorReverse;//左轮电机方向极性
|
||||
public int rightMotorReverse;//右轮电机方向极性
|
||||
public int swapChannel;//左右轮通道互换标志位
|
||||
public int use4G;//联网标志位
|
||||
|
||||
public short forwardSpeedLimit;//前进速度限制
|
||||
public short turnSpeedLimit;//转向速度限制
|
||||
|
||||
public int knifePolarity;//割刀通道极性
|
||||
public int fanPolarity;//风门通道极性
|
||||
public int throttlePolarity;//油门通道极性
|
||||
public int liftProtectTime;//底盘升降电机保护时间
|
||||
public int dualRtk;//RTK配置
|
||||
|
||||
|
||||
public int knifeChannel;//割刀通道配置
|
||||
public int fanChannel;//风门通道配置
|
||||
|
||||
public int throttleChannel;//油门通道配置
|
||||
public int remoteType;//遥控器类型
|
||||
public boolean relayBoard;//是否搭载继电器板
|
||||
|
||||
public int liftChannel;//底盘升通道配置
|
||||
public int chassisChannel;//底盘降通道配置
|
||||
|
||||
public int armChannel;//抱闸通道配置
|
||||
public int fuelPumpChannel;//燃油励磁通道配置
|
||||
|
||||
public String wifiName;//wifi名称
|
||||
public String wifiPassword;//wifi密码
|
||||
|
||||
public int batteryType;//电池类型
|
||||
public int driveType;//行走驱动配置
|
||||
|
||||
public float gearRatio;//转速比
|
||||
public float robotLength;//机器人长度
|
||||
public float robotWidth;//机器人宽度
|
||||
public float robotHeight;//机器人高度
|
||||
public float knifeWidth;//割刀宽度
|
||||
public float tyreSize;//轮胎尺寸
|
||||
public float leftForwardGain;//左轮前进增益
|
||||
public float leftBackwardGain;//左轮后退增益
|
||||
public float rightForwardGain;//右轮前进增益
|
||||
public float rightBackwardGain;//右轮后退增益
|
||||
|
||||
public String firmwareVersion;//固件版本
|
||||
@TableField(exist = false)
|
||||
public int crc16;
|
||||
@TableField(exist = false)
|
||||
public byte tail1;
|
||||
@TableField(exist = false)
|
||||
public byte tail2;
|
||||
@TableField(exist = false)
|
||||
private byte[] originalData;
|
||||
|
||||
public static byte[] toReadBytes() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(7); // 修改为27字节
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
buffer.put((byte) 0xAB);
|
||||
buffer.put((byte) 0xAA);
|
||||
|
||||
buffer.put(CommandConstant.readConfig);
|
||||
|
||||
buffer.putShort((short) 0);
|
||||
|
||||
buffer.put((byte) 0xAA);
|
||||
buffer.put((byte) 0xAB);
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
public byte[] toWriteBytes() {
|
||||
// 如果没有原始数据,使用静态方法重新构建
|
||||
if (originalData == null || originalData.length < 178) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 克隆原始数据,避免修改原始数据
|
||||
byte[] result = originalData.clone();
|
||||
ByteBuffer buffer = ByteBuffer.wrap(result);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// 修改指令为写配置(字节2)
|
||||
buffer.put(2, CommandConstant.writeConfig);
|
||||
|
||||
// 修改字节68:遥控器配置
|
||||
byte remote = 0;
|
||||
remote |= (getKnifeMotorMode() & 0x03);
|
||||
remote |= (getWalkMotorMode() & 0x03) << 2;
|
||||
remote |= (getLeftMotorReverse() & 0x01) << 4;
|
||||
remote |= (getRightMotorReverse() & 0x01) << 5;
|
||||
remote |= (getSwapChannel() & 0x01) << 6;
|
||||
remote |= (getUse4G() & 0x01) << 7;
|
||||
buffer.put(68, remote);
|
||||
|
||||
// 修改字节69-72:速度限制
|
||||
buffer.putShort(69, getForwardSpeedLimit());
|
||||
buffer.putShort(71, getTurnSpeedLimit());
|
||||
|
||||
// 修改字节73:通道极性
|
||||
byte b73 = 0;
|
||||
b73 |= (getKnifePolarity() & 1);
|
||||
b73 |= (getFanPolarity() & 1) << 1;
|
||||
b73 |= (getThrottlePolarity() & 1) << 2;
|
||||
b73 |= (getLiftProtectTime() & 0x0F) << 3;
|
||||
b73 |= (getDualRtk() & 1) << 7;
|
||||
buffer.put(73, b73);
|
||||
|
||||
// 修改字节74-77:通道配置
|
||||
byte b74 = 0;
|
||||
b74 |= (getKnifeChannel() & 0x0F);
|
||||
b74 |= (getFanChannel() & 0x0F) << 4;
|
||||
buffer.put(74, b74);
|
||||
|
||||
byte b75 = 0;
|
||||
b75 |= (getThrottleChannel() & 0x0F);
|
||||
b75 |= (getRemoteType() & 0x07) << 4;
|
||||
if (isRelayBoard()) b75 |= 1 << 7;
|
||||
buffer.put(75, b75);
|
||||
|
||||
byte b76 = 0;
|
||||
b76 |= (getLiftChannel() & 0x0F);
|
||||
b76 |= (getChassisChannel() & 0x0F) << 4;
|
||||
buffer.put(76, b76);
|
||||
|
||||
byte b77 = 0;
|
||||
b77 |= (getArmChannel() & 0x0F);
|
||||
b77 |= (getFuelPumpChannel() & 0x0F) << 4;
|
||||
buffer.put(77, b77);
|
||||
|
||||
// // 修改字节78-117:WiFi信息
|
||||
// byte[] wifiNameBytes = new byte[20];
|
||||
// if (getWifiName() != null) {
|
||||
// byte[] src = getWifiName().getBytes(StandardCharsets.UTF_8);
|
||||
// System.arraycopy(src, 0, wifiNameBytes, 0, Math.min(src.length, 20));
|
||||
// }
|
||||
// System.arraycopy(wifiNameBytes, 0, result, 78, 20);
|
||||
//
|
||||
// byte[] wifiPwdBytes = new byte[20];
|
||||
// if (getWifiPassword() != null) {
|
||||
// byte[] src = getWifiPassword().getBytes(StandardCharsets.UTF_8);
|
||||
// System.arraycopy(src, 0, wifiPwdBytes, 0, Math.min(src.length, 20));
|
||||
// }
|
||||
// System.arraycopy(wifiPwdBytes, 0, result, 98, 20);
|
||||
|
||||
// // 修改字节118:电池和驱动配置
|
||||
// byte b118 = 0;
|
||||
// b118 |= (getBatteryType() & 0x03);
|
||||
// b118 |= (getDriveType() & 0x03) << 2;
|
||||
// buffer.put(118, b118);
|
||||
|
||||
// 修改字节119-158:float参数
|
||||
buffer.putFloat(119, getGearRatio());
|
||||
buffer.putFloat(123, getRobotLength());
|
||||
buffer.putFloat(127, getRobotWidth());
|
||||
buffer.putFloat(131, getRobotHeight());
|
||||
buffer.putFloat(135, getKnifeWidth());
|
||||
buffer.putFloat(139, getTyreSize());
|
||||
buffer.putFloat(143, getLeftForwardGain());
|
||||
buffer.putFloat(147, getLeftBackwardGain());
|
||||
buffer.putFloat(151, getRightForwardGain());
|
||||
buffer.putFloat(155, getRightBackwardGain());
|
||||
|
||||
// 修改字节159-173:固件版本
|
||||
// byte[] fwBytes = new byte[15];
|
||||
// if (getFirmwareVersion() != null) {
|
||||
// byte[] src = getFirmwareVersion().getBytes(StandardCharsets.UTF_8);
|
||||
// System.arraycopy(src, 0, fwBytes, 0, Math.min(src.length, 15));
|
||||
// }
|
||||
// System.arraycopy(fwBytes, 0, result, 159, 15);
|
||||
|
||||
// 保留原始的 CRC 和尾部,不强制修改
|
||||
// 移除以下强制修改:
|
||||
// buffer.putShort(174, (short) 0);
|
||||
// buffer.put(176, (byte) 0xAA);
|
||||
// buffer.put(177, (byte) 0xAB);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void putFixedString(ByteBuffer buffer, String value, int len) {
|
||||
|
||||
byte[] bytes = new byte[len];
|
||||
|
||||
if (value != null) {
|
||||
byte[] src = value.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
System.arraycopy(src, 0, bytes, 0, Math.min(src.length, len));
|
||||
}
|
||||
|
||||
buffer.put(bytes);
|
||||
}
|
||||
|
||||
|
||||
public static DeviceRunParam fromBytes(byte[] data) {
|
||||
// 183
|
||||
if (data == null || data.length < 178) {
|
||||
throw new IllegalArgumentException("数据长度不足");
|
||||
}
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
DeviceRunParam p = new DeviceRunParam();
|
||||
// p.setHeader1(buffer.get());
|
||||
// p.setHeader2(buffer.get());
|
||||
|
||||
p.setOriginalData(data);
|
||||
// p.setCmd(buffer.get());
|
||||
|
||||
p.setHeader1(buffer.get());
|
||||
p.setHeader2(buffer.get());
|
||||
// p.setChipUidSign(buffer.get());
|
||||
|
||||
p.setCmd(buffer.get());
|
||||
// p.setChipUid(readString(buffer, 45));
|
||||
|
||||
p.setChipUidSign(buffer.get());
|
||||
// // 跳过字节49-67(共19字节,预留不用)
|
||||
// buffer.position(buffer.position() + 19);
|
||||
|
||||
p.setChipUid(readString(buffer, 45));
|
||||
// byte remote = buffer.get();
|
||||
|
||||
// 跳过字节49-67(共19字节,预留不用)
|
||||
buffer.position(buffer.position() + 19);
|
||||
// // p.setRemoteConfig(remote);
|
||||
|
||||
byte remote = buffer.get();
|
||||
// p.setKnifeMotorMode(remote & 0x03);
|
||||
// p.setWalkMotorMode((remote >> 2) & 0x03);
|
||||
// p.setLeftMotorReverse((remote >> 4) & 0x01);
|
||||
// p.setRightMotorReverse((remote >> 5) & 0x01);
|
||||
// p.setSwapChannel((remote >> 6) & 0x01);
|
||||
// p.setUse4G((remote >> 7) & 0x01);
|
||||
|
||||
// p.setRemoteConfig(remote);
|
||||
// p.setForwardSpeedLimit(buffer.getShort());
|
||||
// p.setTurnSpeedLimit(buffer.getShort());
|
||||
|
||||
p.setKnifeMotorMode(remote & 0x03);
|
||||
p.setWalkMotorMode((remote >> 2) & 0x03);
|
||||
p.setLeftMotorReverse((remote >> 4) & 0x01);
|
||||
p.setRightMotorReverse((remote >> 5) & 0x01);
|
||||
p.setSwapChannel((remote >> 6) & 0x01);
|
||||
p.setUse4G((remote >> 7) & 0x01);
|
||||
// byte b73 = buffer.get();
|
||||
|
||||
p.setForwardSpeedLimit(buffer.getShort());
|
||||
p.setTurnSpeedLimit(buffer.getShort());
|
||||
// p.setKnifePolarity(b73 & 1);
|
||||
// p.setFanPolarity((b73 >> 1) & 1);
|
||||
// p.setThrottlePolarity((b73 >> 2) & 1);
|
||||
// p.setLiftProtectTime((b73 >> 3) & 0x0F);
|
||||
// p.setDualRtk((b73 >> 7) & 1);
|
||||
|
||||
byte b73 = buffer.get();
|
||||
// byte b74 = buffer.get();
|
||||
|
||||
p.setKnifePolarity(b73 & 1);
|
||||
p.setFanPolarity((b73 >> 1) & 1);
|
||||
p.setThrottlePolarity((b73 >> 2) & 1);
|
||||
p.setLiftProtectTime((b73 >> 3) & 0x0F);
|
||||
p.setDualRtk((b73 >> 7) & 1);
|
||||
// p.setKnifeChannel(b74 & 0x0F);
|
||||
// p.setFanChannel((b74 >> 4) & 0x0F);
|
||||
|
||||
byte b74 = buffer.get();
|
||||
// byte b75 = buffer.get();
|
||||
|
||||
p.setKnifeChannel(b74 & 0x0F);
|
||||
p.setFanChannel((b74 >> 4) & 0x0F);
|
||||
// p.setThrottleChannel(b75 & 0x0F);
|
||||
// p.setRemoteType((b75 >> 4) & 0x07);
|
||||
// p.setRelayBoard(((b75 >> 7) & 1) == 1);
|
||||
|
||||
byte b75 = buffer.get();
|
||||
// byte b76 = buffer.get();
|
||||
|
||||
p.setThrottleChannel(b75 & 0x0F);
|
||||
p.setRemoteType((b75 >> 4) & 0x07);
|
||||
p.setRelayBoard(((b75 >> 7) & 1) == 1);
|
||||
// p.setLiftChannel(b76 & 0x0F);
|
||||
// p.setChassisChannel((b76 >> 4) & 0x0F);
|
||||
|
||||
byte b76 = buffer.get();
|
||||
// byte b77 = buffer.get();
|
||||
|
||||
p.setLiftChannel(b76 & 0x0F);
|
||||
p.setChassisChannel((b76 >> 4) & 0x0F);
|
||||
// p.setArmChannel(b77 & 0x0F);
|
||||
// p.setFuelPumpChannel((b77 >> 4) & 0x0F);
|
||||
|
||||
byte b77 = buffer.get();
|
||||
// p.setWifiName(readString(buffer, 20));
|
||||
// p.setWifiPassword(readString(buffer, 20));
|
||||
|
||||
p.setArmChannel(b77 & 0x0F);
|
||||
p.setFuelPumpChannel((b77 >> 4) & 0x0F);
|
||||
// byte b118 = buffer.get();
|
||||
|
||||
p.setWifiName(readString(buffer, 20));
|
||||
p.setWifiPassword(readString(buffer, 20));
|
||||
// p.setBatteryType(b118 & 0x03);
|
||||
// p.setDriveType((b118 >> 2) & 0x03);
|
||||
|
||||
byte b118 = buffer.get();
|
||||
// // float
|
||||
// p.setGearRatio(buffer.getFloat());
|
||||
// p.setRobotLength(buffer.getFloat());
|
||||
// p.setRobotWidth(buffer.getFloat());
|
||||
// p.setRobotHeight(buffer.getFloat());
|
||||
// p.setKnifeWidth(buffer.getFloat());
|
||||
// p.setTyreSize(buffer.getFloat());
|
||||
// p.setLeftForwardGain(buffer.getFloat());
|
||||
// p.setLeftBackwardGain(buffer.getFloat());
|
||||
// p.setRightForwardGain(buffer.getFloat());
|
||||
// p.setRightBackwardGain(buffer.getFloat());
|
||||
|
||||
p.setBatteryType(b118 & 0x03);
|
||||
p.setDriveType((b118 >> 2) & 0x03);
|
||||
// p.setFirmwareVersion(readString(buffer, 15));
|
||||
|
||||
// float
|
||||
p.setGearRatio(buffer.getFloat());
|
||||
p.setRobotLength(buffer.getFloat());
|
||||
p.setRobotWidth(buffer.getFloat());
|
||||
p.setRobotHeight(buffer.getFloat());
|
||||
p.setKnifeWidth(buffer.getFloat());
|
||||
p.setTyreSize(buffer.getFloat());
|
||||
p.setLeftForwardGain(buffer.getFloat());
|
||||
p.setLeftBackwardGain(buffer.getFloat());
|
||||
p.setRightForwardGain(buffer.getFloat());
|
||||
p.setRightBackwardGain(buffer.getFloat());
|
||||
// p.setCrc16(Short.toUnsignedInt(buffer.getShort()));
|
||||
|
||||
p.setFirmwareVersion(readString(buffer, 15));
|
||||
// p.setTail1(buffer.get());
|
||||
// p.setTail2(buffer.get());
|
||||
|
||||
p.setCrc16(Short.toUnsignedInt(buffer.getShort()));
|
||||
// return p;
|
||||
// }
|
||||
|
||||
p.setTail1(buffer.get());
|
||||
p.setTail2(buffer.get());
|
||||
// public static String readString(ByteBuffer buffer, int len) {
|
||||
// byte[] bytes = new byte[len];
|
||||
// buffer.get(bytes);
|
||||
|
||||
return p;
|
||||
}
|
||||
// int end = 0;
|
||||
// while (end < bytes.length && bytes[end] != 0) {
|
||||
// end++;
|
||||
// }
|
||||
|
||||
public static String readString(ByteBuffer buffer, int len) {
|
||||
byte[] bytes = new byte[len];
|
||||
buffer.get(bytes);
|
||||
|
||||
int end = 0;
|
||||
while (end < bytes.length && bytes[end] != 0) {
|
||||
end++;
|
||||
}
|
||||
|
||||
return new String(bytes, 0, end, StandardCharsets.UTF_8);
|
||||
}
|
||||
// return new String(bytes, 0, end, StandardCharsets.UTF_8);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.maibu.dto;
|
||||
package com.maibu.core.business;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -42,13 +42,13 @@ public class LawnMoverProtocolEntity {
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(15);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(27);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN); // 根据协议决定字节序
|
||||
buffer.put(Header1);
|
||||
buffer.put(Header2);
|
||||
buffer.put(CommandType);
|
||||
buffer.putShort(LeftWheelSpeed);
|
||||
buffer.putShort(RightWheelSpeed);
|
||||
buffer.putDouble(linearSpeed);
|
||||
buffer.putDouble(angularSpeed);
|
||||
buffer.put(ChassisLiftFlag);
|
||||
buffer.put(MowerSpeedFlag);
|
||||
buffer.put(IgnitionFlag);
|
||||
@@ -67,7 +67,46 @@ public class LawnMoverProtocolEntity {
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将控制指令字节数组解析为实体对象
|
||||
*/
|
||||
public static LawnMoverProtocolEntity parseControlCommand(byte[] data) {
|
||||
if (data == null || data.length != 27) {
|
||||
throw new IllegalArgumentException("控制指令长度必须为15字节");
|
||||
}
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
LawnMoverProtocolEntity entity = new LawnMoverProtocolEntity();
|
||||
|
||||
// 帧头
|
||||
entity.setHeader1(buffer.get());
|
||||
entity.setHeader2(buffer.get());
|
||||
|
||||
// 命令类型
|
||||
entity.setCommandType(buffer.get());
|
||||
|
||||
// 左右轮速度:int16
|
||||
entity.setLinearSpeed(buffer.getDouble());
|
||||
entity.setAngularSpeed(buffer.getDouble());
|
||||
|
||||
// 控制标志:uint8
|
||||
entity.setChassisLiftFlag(buffer.get());
|
||||
entity.setMowerSpeedFlag(buffer.get());
|
||||
entity.setIgnitionFlag(buffer.get());
|
||||
entity.setEmergencyStopFlag(buffer.get());
|
||||
|
||||
// 预留字段
|
||||
buffer.get();
|
||||
buffer.get();
|
||||
|
||||
// 帧尾
|
||||
entity.setEndFlag1(buffer.get());
|
||||
entity.setEndFlag2(buffer.get());
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
// 包头起始字节1
|
||||
private byte Header1;
|
||||
@@ -79,6 +118,10 @@ public class LawnMoverProtocolEntity {
|
||||
private short LeftWheelSpeed;
|
||||
// 右轮速度:16位有符号
|
||||
private short RightWheelSpeed;
|
||||
|
||||
private double linearSpeed;
|
||||
|
||||
private double angularSpeed;
|
||||
// 底盘升降标志位
|
||||
private byte ChassisLiftFlag;
|
||||
// 割刀速度标志位
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.maibu.constant.Constant;
|
||||
import com.maibu.core.business.*;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.business.path.RoutePlanSendEntity;
|
||||
@@ -136,7 +137,6 @@ public class NettyDevice extends Connector {
|
||||
return finishId;
|
||||
}
|
||||
|
||||
|
||||
public synchronized boolean cancelingTask() throws MqttException {
|
||||
if (task != null) {
|
||||
WorkRecord workRecord = workRecordMapper.selectById(task.getRouteId());
|
||||
@@ -149,7 +149,7 @@ public class NettyDevice extends Connector {
|
||||
dto.setMode(workRecord.getMode());
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version("1.4");
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
@@ -214,7 +214,7 @@ public class NettyDevice extends Connector {
|
||||
|
||||
// 配置左右轮增益系数
|
||||
public void sendWheelGainCoefficientsCommand(double leftForwardGain, double leftBackwardGain,
|
||||
double rightForwardGain, double rightBackwardGain) {
|
||||
double rightForwardGain, double rightBackwardGain) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(39);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
@@ -246,24 +246,24 @@ public class NettyDevice extends Connector {
|
||||
}
|
||||
}
|
||||
|
||||
public void readConfigCommand() {
|
||||
byte[] bytes = DeviceRunParam.toReadBytes();
|
||||
log.debug("下发读取配置的报文:{}", toHexString(bytes));
|
||||
if (this.getChannel() != null && this.getChannel().isActive()) {
|
||||
this.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
|
||||
}
|
||||
log.debug("下发读取配置的报文完成:{}", toHexString(bytes));
|
||||
}
|
||||
// public void readConfigCommand() {
|
||||
// byte[] bytes = DeviceRunParam.toReadBytes();
|
||||
// log.debug("下发读取配置的报文:{}", toHexString(bytes));
|
||||
// if (this.getChannel() != null && this.getChannel().isActive()) {
|
||||
// this.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
|
||||
// }
|
||||
// log.debug("下发读取配置的报文完成:{}", toHexString(bytes));
|
||||
// }
|
||||
|
||||
public void writeConfigCommand(DeviceRunParam deviceRunParam) {
|
||||
log.debug("下发修改配置的属性:{}", JsonUtils.toJsonString(deviceRunParam));
|
||||
byte[] bytes = deviceRunParam.toWriteBytes();
|
||||
log.debug("下发修改配置的报文:{}", toHexString(bytes));
|
||||
if (this.getChannel() != null && this.getChannel().isActive()) {
|
||||
this.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
|
||||
}
|
||||
log.debug("下发修改配置的报文完成:{}", toHexString(bytes));
|
||||
}
|
||||
// public void writeConfigCommand(DeviceRunParam deviceRunParam) {
|
||||
// log.debug("下发修改配置的属性:{}", JsonUtils.toJsonString(deviceRunParam));
|
||||
// byte[] bytes = deviceRunParam.toWriteBytes();
|
||||
// log.debug("下发修改配置的报文:{}", toHexString(bytes));
|
||||
// if (this.getChannel() != null && this.getChannel().isActive()) {
|
||||
// this.getChannel().writeAndFlush(Unpooled.wrappedBuffer(bytes));
|
||||
// }
|
||||
// log.debug("下发修改配置的报文完成:{}", toHexString(bytes));
|
||||
// }
|
||||
|
||||
// todo 优化
|
||||
public synchronized boolean pauseTask() {
|
||||
@@ -294,7 +294,6 @@ public class NettyDevice extends Connector {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void startTask() {
|
||||
try {
|
||||
if (executingTask)
|
||||
@@ -363,7 +362,7 @@ public class NettyDevice extends Connector {
|
||||
dto.setMode(workRecord.getMode());
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version("1.4");
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
PointEntity point = new PointEntity();
|
||||
if (!StringUtils.isEmpty(workRecord.getMode())) {
|
||||
@@ -414,8 +413,19 @@ public class NettyDevice extends Connector {
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(
|
||||
mqttClientId,
|
||||
String.format(MqttTopic.MOWER_OTA_UPGRADE_SET, deviceId),
|
||||
JsonUtils.toJsonString(payload)
|
||||
);
|
||||
JsonUtils.toJsonString(payload));
|
||||
}
|
||||
|
||||
public void searchDevice(String deviceId) throws MqttException {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("action", "search_device");
|
||||
payload.put("timestamp", System.currentTimeMillis());
|
||||
payload.put("message_id", "search_device_" + System.currentTimeMillis());
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(
|
||||
mqttClientId,
|
||||
String.format(MqttTopic.MOWER_SEARCH_DEVICE_SET, deviceId),
|
||||
JsonUtils.toJsonString(payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@ public class DeviceMapPushDTO {
|
||||
private String id;
|
||||
private double lat;
|
||||
private double lng;
|
||||
private double y; //yaw
|
||||
private String f; //fix_status
|
||||
private double a; //altitude
|
||||
private String s;//status 运行状态
|
||||
private Long t; //taskId 任务id
|
||||
private double b; //电量
|
||||
private boolean ha = false;//hasAlarm 有无告警
|
||||
private double y; // yaw
|
||||
private String f; // fix_status
|
||||
private double a; // altitude
|
||||
private String s;// status 运行状态
|
||||
private Long t; // taskId 任务id
|
||||
private double b; // 电量
|
||||
private boolean ha = false;// hasAlarm 有无告警
|
||||
|
||||
private String cm;// 控制模式 manual_remote|auto
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.maibu.dto;
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import com.maibu.core.enums.MesType;
|
||||
|
||||
@@ -12,4 +12,6 @@ public class WebOlineStatusMessageDTO {
|
||||
private String errorCode;
|
||||
private String description;
|
||||
private MesType type;
|
||||
|
||||
private Long time;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.maibu.core.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.core.domain.OrgNoUserDO;
|
||||
import com.maibu.core.enums.SysParamType;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "sys_param")
|
||||
public class SysParam extends OrgNoUserDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private SysParamType paramType;
|
||||
|
||||
private String paramKey;
|
||||
|
||||
private String nameTranslateKey;
|
||||
|
||||
private String paramValue;
|
||||
|
||||
private String descTranslateKey;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String nameTranslate;
|
||||
@TableField(exist = false)
|
||||
private String descTranslate;
|
||||
|
||||
private String valueRange;
|
||||
|
||||
private String dataType;
|
||||
|
||||
}
|
||||
@@ -1,27 +1,26 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import com.maibu.annotation.Excel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AlarmType {
|
||||
|
||||
UAV_FAULT("UAV_FAULT", "无人机故障"),
|
||||
|
||||
MOWER_FAULT("MOWER_FAULT", "割草机故障"),
|
||||
|
||||
OTHER_DEVICE_FAULT("OTHER_DEVICE_FAULT", "其他设备故障"),
|
||||
|
||||
SERVER_FAILURE("SERVER_FAILURE", "服务器故障"),
|
||||
|
||||
SYSTEM_ERROR("SYSTEM_ERROR", "系统错误");
|
||||
|
||||
/** 错误来源值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 错误来源名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
}
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum AlarmType {
|
||||
|
||||
UAV_FAULT("UAV_FAULT", "无人机故障"),
|
||||
|
||||
MOWER_FAULT("MOWER_FAULT", "割草机故障"),
|
||||
|
||||
OTHER_DEVICE_FAULT("OTHER_DEVICE_FAULT", "其他设备故障"),
|
||||
|
||||
SERVER_FAILURE("SERVER_FAILURE", "服务器故障"),
|
||||
|
||||
SYSTEM_ERROR("SYSTEM_ERROR", "系统错误");
|
||||
|
||||
/** 错误来源值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 错误来源名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SysParamType {
|
||||
|
||||
site("site", "场站维度"),
|
||||
|
||||
org("org", "组织维度"),
|
||||
|
||||
global("global", "全局维度"),
|
||||
|
||||
personal("personal", "个人维度");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 上位机远程控制参数
|
||||
* DeviceRemoteControlDTO
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class DeviceRemoteControlDTO extends HostBase {
|
||||
private String command_id;
|
||||
private ParamDetail data;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ParamDetail {
|
||||
// private short left_wheel_rpm; // 左轮转速
|
||||
// private short right_wheel_rpm; // 右轮转速
|
||||
|
||||
private double linear_x; // 线速度
|
||||
private double angular_z; // 角速度
|
||||
|
||||
private int chassis_lift; // 底盘升降 0:停止 1:升 2:降
|
||||
private int cutter; // 割刀加减速 0:停止 1:加速 2:减速
|
||||
private int ignition; // 点火熄火 0:停止 1:点火 2:熄火
|
||||
private int emergency_stop; // 急停 0:正常 1:急停
|
||||
private int valid_for_ms; // 指令有效时间,单位毫秒
|
||||
}
|
||||
@@ -5,12 +5,33 @@ import lombok.Data;
|
||||
@Data
|
||||
public class VehicleMessage {
|
||||
|
||||
private double speed;
|
||||
private double battery_percentage;// 电量
|
||||
private double battery_voltage;// 电压
|
||||
private String motion;// moving|stopped|blocked
|
||||
private boolean emergency_stop; // 急停状态
|
||||
private double battery_percentage;// 实时电量百分比
|
||||
private double battery_voltage;// 实时电压
|
||||
|
||||
private double distance; // 里程数
|
||||
private double left_motor_current;// 实时左电机电流
|
||||
private double right_motor_current;// 实时右电机电流
|
||||
private double left_motor_temperature;// 实时左电机温度
|
||||
private double right_motor_temperature;// 实时右电机温度
|
||||
private double main_temperature;// 实时主温度
|
||||
private double yaw;// 实时航向角度
|
||||
private double pitch;// 实时俯仰角度
|
||||
private String heading_status;// 实时航向状态
|
||||
private double total_work_area;// 累计作业面积
|
||||
private double total_work_duration;// 累计作业时长
|
||||
private double total_work_distance;// 累计作业里程
|
||||
private String motion;// moving|stopped|blocked 运动状态
|
||||
private Boolean emergency_stop; // 急停状态
|
||||
|
||||
private double left_target_rpm; // 实时左电机目标转速
|
||||
private double right_target_rpm;// 实时右电机目标转速
|
||||
private double left_measured_rpm;// 实时左电机测量转速
|
||||
private double right_measured_rpm;// 实时右电机测量转速
|
||||
private double left_motor_rpm;// 实时左电机转速
|
||||
private double right_motor_rpm;// 实时右电机转速
|
||||
private double roll;// 实时翻滚角度
|
||||
private String control_mode;// 遥控器拨杆对应的当前控制模式
|
||||
|
||||
private double linear_speed; // 实时线速度
|
||||
private double angular_speed; // 实时角速度
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.maibu.core.domain.entity.SysSite;
|
||||
import com.maibu.core.enums.ErrorSource;
|
||||
import com.maibu.core.host.VehicleMessage;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -59,6 +60,20 @@ public class SiteMemory {
|
||||
|
||||
public static ConcurrentHashMap<String, DeviceMapPushDTO> deviceMapPushMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static ConcurrentHashMap<String, VehicleMessage> vehicleMessageMap = new ConcurrentHashMap<>();
|
||||
|
||||
public VehicleMessage getVehicleMessage(String deviceId) {
|
||||
return vehicleMessageMap.get(deviceId);
|
||||
}
|
||||
|
||||
public void saveVehicleMessage(String deviceId, VehicleMessage vehicleMessage) {
|
||||
vehicleMessageMap.put(deviceId, vehicleMessage);
|
||||
}
|
||||
|
||||
public void removeVehicleMessage(String deviceId) {
|
||||
vehicleMessageMap.remove(deviceId);
|
||||
}
|
||||
|
||||
public Map<String, DeviceMapPushDTO> getAllDeviceMapPush() {
|
||||
return deviceMapPushMap;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
|
||||
|
||||
private final DeviceSessionManager deviceSessionManager = SpringUtils.getBean(DeviceSessionManager.class);
|
||||
|
||||
private final WebsocketMesDispather websocketMesDispather = SpringUtils.getBean(WebsocketMesDispather.class);
|
||||
@@ -148,6 +148,15 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
locationMessage.setDeviceId(deviceId);
|
||||
redisCache.setCacheObject(key, locationMessage);
|
||||
|
||||
// todo 推送实时位置和状态消息到外部
|
||||
try {
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.DEVICE_LOCATION_MESSAGE_TOPIC, deviceId),
|
||||
JsonUtils.toJsonString(locationRelTimeDTO));
|
||||
} catch (MqttException e) {
|
||||
log.error("位置实时数据推送失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("位置消息解析失败: deviceId={}, payload={}, error={}", deviceId, payload, e);
|
||||
@@ -155,7 +164,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
}
|
||||
|
||||
public WebStatusMessageDTO createWebDeviceLocationMessage(HostLocationRelTimeDTO locationRelTimeDTO,
|
||||
String deviceId) {
|
||||
String deviceId) {
|
||||
WebStatusMessageDTO webStatusMessageDTO = new WebStatusMessageDTO();
|
||||
List<DeviceStatusDetail> transferData = new ArrayList<>();
|
||||
|
||||
@@ -227,7 +236,6 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
DeviceMapPushDTO dto = new DeviceMapPushDTO();
|
||||
dto.setA(Double.parseDouble(altitude.getValue()));
|
||||
dto.setId(deviceId);
|
||||
// dto.setB();
|
||||
// dto.setHa();
|
||||
dto.setF(fix_status.getValue());
|
||||
dto.setS(status.getValue());
|
||||
@@ -235,6 +243,12 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
dto.setLng(Double.parseDouble(lng.getValue()));
|
||||
dto.setT(nettyDevice.getCurrentTaskId());
|
||||
dto.setY(Double.parseDouble(yaw.getValue()));
|
||||
siteMemory.getVehicleMessage(deviceId);
|
||||
VehicleMessage vehicleMessage = siteMemory.getVehicleMessage(deviceId);
|
||||
if (vehicleMessage != null) {
|
||||
dto.setCm(vehicleMessage.getControl_mode());
|
||||
dto.setB(vehicleMessage.getBattery_percentage());
|
||||
}
|
||||
siteMemory.saveMapPushDTO(deviceId, dto);
|
||||
}
|
||||
}
|
||||
@@ -248,17 +262,82 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
WebStatusMessageDTO webStatusMessageDTO = new WebStatusMessageDTO();
|
||||
List<DeviceStatusDetail> transferData = new ArrayList<>();
|
||||
DeviceStatusDetail voltage = new DeviceStatusDetail();
|
||||
voltage.setName("voltage");
|
||||
voltage.setValue(String.valueOf(vehicleRelTimeDTO.getData().getBattery_voltage()));
|
||||
voltage.setName("battery_percentage");
|
||||
voltage.setValue(String.valueOf(vehicleRelTimeDTO.getData().getBattery_percentage()));
|
||||
voltage.setUnit("");
|
||||
|
||||
transferData.add(voltage);
|
||||
|
||||
DeviceStatusDetail speed = new DeviceStatusDetail();
|
||||
speed.setName("speed");
|
||||
speed.setValue(String.valueOf(vehicleRelTimeDTO.getData().getSpeed()));
|
||||
speed.setUnit("");
|
||||
transferData.add(speed);
|
||||
DeviceStatusDetail battery_voltage = new DeviceStatusDetail();
|
||||
battery_voltage.setName("battery_voltage");
|
||||
battery_voltage.setValue(String.valueOf(vehicleRelTimeDTO.getData().getBattery_voltage()));
|
||||
battery_voltage.setUnit("");
|
||||
transferData.add(battery_voltage);
|
||||
|
||||
DeviceStatusDetail left_motor_current = new DeviceStatusDetail();
|
||||
left_motor_current.setName("left_motor_current");
|
||||
left_motor_current.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLeft_motor_current()));
|
||||
left_motor_current.setUnit("");
|
||||
transferData.add(left_motor_current);
|
||||
|
||||
DeviceStatusDetail right_motor_current = new DeviceStatusDetail();
|
||||
right_motor_current.setName("right_motor_current");
|
||||
right_motor_current.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRight_motor_current()));
|
||||
right_motor_current.setUnit("");
|
||||
transferData.add(right_motor_current);
|
||||
|
||||
DeviceStatusDetail left_motor_temperature = new DeviceStatusDetail();
|
||||
left_motor_temperature.setName("left_motor_temperature");
|
||||
left_motor_temperature.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLeft_motor_temperature()));
|
||||
left_motor_temperature.setUnit("");
|
||||
transferData.add(left_motor_temperature);
|
||||
|
||||
DeviceStatusDetail right_motor_temperature = new DeviceStatusDetail();
|
||||
right_motor_temperature.setName("right_motor_temperature");
|
||||
right_motor_temperature.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRight_motor_temperature()));
|
||||
right_motor_temperature.setUnit("");
|
||||
transferData.add(right_motor_temperature);
|
||||
|
||||
DeviceStatusDetail main_temperature = new DeviceStatusDetail();
|
||||
main_temperature.setName("main_temperature");
|
||||
main_temperature.setValue(String.valueOf(vehicleRelTimeDTO.getData().getMain_temperature()));
|
||||
main_temperature.setUnit("");
|
||||
transferData.add(main_temperature);
|
||||
|
||||
DeviceStatusDetail yaw = new DeviceStatusDetail();
|
||||
yaw.setName("yaw");
|
||||
yaw.setValue(String.valueOf(vehicleRelTimeDTO.getData().getYaw()));
|
||||
yaw.setUnit("");
|
||||
transferData.add(yaw);
|
||||
|
||||
DeviceStatusDetail pitch = new DeviceStatusDetail();
|
||||
pitch.setName("pitch");
|
||||
pitch.setValue(String.valueOf(vehicleRelTimeDTO.getData().getPitch()));
|
||||
pitch.setUnit("");
|
||||
transferData.add(pitch);
|
||||
|
||||
DeviceStatusDetail heading_status = new DeviceStatusDetail();
|
||||
heading_status.setName("heading_status");
|
||||
heading_status.setValue(String.valueOf(vehicleRelTimeDTO.getData().getHeading_status()));
|
||||
heading_status.setUnit("");
|
||||
transferData.add(heading_status);
|
||||
|
||||
DeviceStatusDetail total_work_area = new DeviceStatusDetail();
|
||||
total_work_area.setName("total_work_area");
|
||||
total_work_area.setValue(String.valueOf(vehicleRelTimeDTO.getData().getTotal_work_area()));
|
||||
total_work_area.setUnit("");
|
||||
transferData.add(total_work_area);
|
||||
|
||||
DeviceStatusDetail total_work_duration = new DeviceStatusDetail();
|
||||
total_work_duration.setName("total_work_duration");
|
||||
total_work_duration.setValue(String.valueOf(vehicleRelTimeDTO.getData().getTotal_work_duration()));
|
||||
total_work_duration.setUnit("");
|
||||
transferData.add(total_work_duration);
|
||||
|
||||
DeviceStatusDetail total_work_distance = new DeviceStatusDetail();
|
||||
total_work_distance.setName("total_work_distance");
|
||||
total_work_distance.setValue(String.valueOf(vehicleRelTimeDTO.getData().getTotal_work_distance()));
|
||||
total_work_distance.setUnit("");
|
||||
transferData.add(total_work_distance);
|
||||
|
||||
DeviceStatusDetail motion = new DeviceStatusDetail();
|
||||
motion.setName("motion");
|
||||
@@ -266,11 +345,71 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
motion.setUnit("");
|
||||
transferData.add(motion);
|
||||
|
||||
DeviceStatusDetail percentage = new DeviceStatusDetail();
|
||||
percentage.setName("percentage");
|
||||
percentage.setValue(String.valueOf(vehicleRelTimeDTO.getData().getBattery_percentage()));
|
||||
percentage.setUnit("");
|
||||
transferData.add(percentage);
|
||||
DeviceStatusDetail emergency_stop = new DeviceStatusDetail();
|
||||
emergency_stop.setName("emergency_stop");
|
||||
emergency_stop.setValue(String.valueOf(vehicleRelTimeDTO.getData().getEmergency_stop()));
|
||||
emergency_stop.setUnit("");
|
||||
transferData.add(emergency_stop);
|
||||
|
||||
DeviceStatusDetail left_target_rpm = new DeviceStatusDetail();
|
||||
left_target_rpm.setName("left_target_rpm");
|
||||
left_target_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLeft_target_rpm()));
|
||||
left_target_rpm.setUnit("");
|
||||
transferData.add(left_target_rpm);
|
||||
|
||||
DeviceStatusDetail right_target_rpm = new DeviceStatusDetail();
|
||||
right_target_rpm.setName("right_target_rpm");
|
||||
right_target_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRight_target_rpm()));
|
||||
right_target_rpm.setUnit("");
|
||||
transferData.add(right_target_rpm);
|
||||
|
||||
DeviceStatusDetail left_measured_rpm = new DeviceStatusDetail();
|
||||
left_measured_rpm.setName("left_measured_rpm");
|
||||
left_measured_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLeft_measured_rpm()));
|
||||
left_measured_rpm.setUnit("");
|
||||
transferData.add(left_measured_rpm);
|
||||
|
||||
DeviceStatusDetail right_measured_rpm = new DeviceStatusDetail();
|
||||
right_measured_rpm.setName("right_measured_rpm");
|
||||
right_measured_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRight_measured_rpm()));
|
||||
right_measured_rpm.setUnit("");
|
||||
transferData.add(right_measured_rpm);
|
||||
|
||||
DeviceStatusDetail left_motor_rpm = new DeviceStatusDetail();
|
||||
left_motor_rpm.setName("left_motor_rpm");
|
||||
left_motor_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLeft_motor_rpm()));
|
||||
left_motor_rpm.setUnit("");
|
||||
transferData.add(left_motor_rpm);
|
||||
|
||||
DeviceStatusDetail right_motor_rpm = new DeviceStatusDetail();
|
||||
right_motor_rpm.setName("right_motor_rpm");
|
||||
right_motor_rpm.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRight_motor_rpm()));
|
||||
right_motor_rpm.setUnit("");
|
||||
transferData.add(right_motor_rpm);
|
||||
|
||||
DeviceStatusDetail roll = new DeviceStatusDetail();
|
||||
roll.setName("roll");
|
||||
roll.setValue(String.valueOf(vehicleRelTimeDTO.getData().getRoll()));
|
||||
roll.setUnit("");
|
||||
transferData.add(roll);
|
||||
|
||||
DeviceStatusDetail control_mode = new DeviceStatusDetail();
|
||||
control_mode.setName("control_mode");
|
||||
control_mode.setValue(String.valueOf(vehicleRelTimeDTO.getData().getControl_mode()));
|
||||
control_mode.setUnit("");
|
||||
transferData.add(control_mode);
|
||||
|
||||
DeviceStatusDetail linear_speed = new DeviceStatusDetail();
|
||||
linear_speed.setName("linear_speed");
|
||||
linear_speed.setValue(String.valueOf(vehicleRelTimeDTO.getData().getLinear_speed()));
|
||||
linear_speed.setUnit("");
|
||||
transferData.add(linear_speed);
|
||||
|
||||
DeviceStatusDetail angular_speed = new DeviceStatusDetail();
|
||||
angular_speed.setName("angular_speed");
|
||||
angular_speed.setValue(String.valueOf(vehicleRelTimeDTO.getData().getAngular_speed()));
|
||||
angular_speed.setUnit("");
|
||||
transferData.add(angular_speed);
|
||||
|
||||
webStatusMessageDTO.setData(transferData);
|
||||
webStatusMessageDTO.setType(MesType.deviceInfo);
|
||||
@@ -287,7 +426,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
if (vehicleRelTimeDTO != null) {
|
||||
|
||||
// todo 更新里程数 里程数 * 割幅0.8
|
||||
vehicleRelTimeDTO.getData().getDistance();
|
||||
vehicleRelTimeDTO.getData().getTotal_work_distance();
|
||||
NettyDevice nettyDevice = deviceSessionManager.getDevice(deviceId);
|
||||
if (nettyDevice != null) {
|
||||
Long orgId = nettyDevice.getDevice().getOrgId();
|
||||
@@ -299,9 +438,11 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
deviceRunStatistics = new DeviceRunStatistics();
|
||||
}
|
||||
deviceRunStatistics.setDeviceId(deviceId);
|
||||
deviceRunStatistics.setDistance(vehicleRelTimeDTO.getData().getDistance());
|
||||
deviceRunStatistics.setWorkArea(vehicleRelTimeDTO.getData().getDistance() * 0.8);
|
||||
deviceRunStatistics.setDistance(vehicleRelTimeDTO.getData().getTotal_work_distance());
|
||||
deviceRunStatistics.setWorkArea(vehicleRelTimeDTO.getData().getTotal_work_distance() * 0.8);
|
||||
siteMemory.saveRunStatistics(deviceRunStatistics);
|
||||
|
||||
siteMemory.saveVehicleMessage(deviceId, vehicleRelTimeDTO.getData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +459,14 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
// todo 推送实时位置和状态消息到外部
|
||||
try {
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.DEVICE_VEHICLE_MESSAGE_TOPIC, deviceId),
|
||||
JsonUtils.toJsonString(vehicleRelTimeDTO));
|
||||
} catch (MqttException e) {
|
||||
log.error("位置实时数据推送失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("实时消息解析失败: deviceId={}, payload={}, error={}", deviceId, payload, e.getMessage());
|
||||
@@ -371,7 +520,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
try {
|
||||
websocketMesDispather.dispather(x.getConnectorId(), JsonUtils.toJsonString(sendDto));
|
||||
} catch (Exception e) {
|
||||
log.error("实时数据websocket推送失败: connectorId={}, error={}", x.getConnectorId(),
|
||||
log.error("实时数据websocket任务状态推送失败: connectorId={}, error={}", x.getConnectorId(),
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -382,8 +531,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
String.format(MqttTopic.DEVICE_TASK_STATUS_TOPIC, taskId),
|
||||
JsonUtils.toJsonString(sendDto));
|
||||
} catch (MqttException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
log.error("实时数据websocket任务状态推送失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -397,7 +545,7 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
if ("failed".equals(dto.getStatus())) {
|
||||
nettyDevice.failedTask();
|
||||
}
|
||||
// if("accepted".equals(dto.getStatus())){
|
||||
// if ("accepted".equals(dto.getStatus())) {
|
||||
// NettyDevice nettyDevice = deviceSessionManager.getDevice(deviceId);
|
||||
// nettyDevice.finishTask();
|
||||
// }
|
||||
@@ -436,6 +584,34 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
if (device != null && device.getTask() != null
|
||||
&& String.valueOf(device.getTask().getId()).equals(replyDTO.getTask_id())) {
|
||||
device.getTask().setTaskAccepted(true);
|
||||
|
||||
WebDeviceTaskStatusMessageDTO sendDto = new WebDeviceTaskStatusMessageDTO();
|
||||
sendDto.setDeviceId(deviceId);
|
||||
sendDto.setTaskId(device.getTask().getId());
|
||||
sendDto.setStatus(DeviceTaskStaus.EXECUTING.toString());
|
||||
sendDto.setType(MesType.device_task_change);
|
||||
|
||||
List<NettyDevice> controlMasters = deviceSessionManager
|
||||
.getAllSlaveControl(deviceId);
|
||||
if (!CollectionUtils.isEmpty(controlMasters)) {
|
||||
for (NettyDevice x : controlMasters) {
|
||||
try {
|
||||
websocketMesDispather.dispather(x.getConnectorId(), JsonUtils.toJsonString(sendDto));
|
||||
} catch (Exception e) {
|
||||
log.error("实时数据websocket推送失败: connectorId={}, error={}", x.getConnectorId(),
|
||||
e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// todo 推送实时位置和状态消息到外部
|
||||
try {
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.DEVICE_TASK_STATUS_TOPIC, device.getTask().getId()),
|
||||
JsonUtils.toJsonString(sendDto));
|
||||
} catch (MqttException e) {
|
||||
log.error("实时数据websocket推送失败: deviceId={}, error={}", deviceId, e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,17 +620,18 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
* 处理控制指令响应
|
||||
*/
|
||||
private void handleUpgradeReply(String deviceId, String topic, String payload) {
|
||||
// log.debug("【路径任务下发响应】deviceId={}, payload={}", deviceId, payload);
|
||||
//
|
||||
// // todo 更新任务接收状态
|
||||
// HostNavigationReplyDTO replyDTO = JsonUtils.parseObject(payload, HostNavigationReplyDTO.class);
|
||||
// NettyDevice device = deviceSessionManager.getDevice(deviceId);
|
||||
// if (replyDTO.isAccepted()) {
|
||||
// if (device != null && device.getTask() != null
|
||||
// && String.valueOf(device.getTask().getId()).equals(replyDTO.getTask_id())) {
|
||||
// device.getTask().setTaskAccepted(true);
|
||||
// }
|
||||
// }
|
||||
// log.debug("【路径任务下发响应】deviceId={}, payload={}", deviceId, payload);
|
||||
//
|
||||
// // todo 更新任务接收状态
|
||||
// HostNavigationReplyDTO replyDTO = JsonUtils.parseObject(payload,
|
||||
// HostNavigationReplyDTO.class);
|
||||
// NettyDevice device = deviceSessionManager.getDevice(deviceId);
|
||||
// if (replyDTO.isAccepted()) {
|
||||
// if (device != null && device.getTask() != null
|
||||
// && String.valueOf(device.getTask().getId()).equals(replyDTO.getTask_id())) {
|
||||
// device.getTask().setTaskAccepted(true);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,7 +687,6 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
if (remaining.equals("/ota/result/post"))
|
||||
return "upgrade_reply";
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,22 @@ package com.maibu.mqtt;
|
||||
|
||||
public class MqttTopic {
|
||||
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_STATUS_TOPIC = "device/%s/realTimeMessage";
|
||||
|
||||
public static final String DEVICE_LOCATION_TOPIC = "device/%s/locationMessage";
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_VEHICLE_MESSAGE_TOPIC = "device/%s/host/realTime/message";
|
||||
|
||||
public static final String DEVICE_LOCATION_MESSAGE_TOPIC = "device/%s/host/location/message";
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_TASK_STATUS_TOPIC = "task/%s/status";
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_TASK_ARRIVE_TOPIC = "task/%s/arrive";
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
/** 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_ERROR_PUSH_TOPIC = "device/%s/error";
|
||||
public static final String DEVICE_ROUTE_PUSH_TOPIC = "device/%s/route/post";
|
||||
|
||||
public static final String DEVICE_STATUS_PUSH_TOPIC = "device/%s/status/change";
|
||||
|
||||
/** 产品标识:割草机 */
|
||||
public static final String MOWER_PRODUCT = "mower";
|
||||
|
||||
@@ -43,7 +47,7 @@ public class MqttTopic {
|
||||
|
||||
// ==================== 远程控制 ====================
|
||||
/** 远程控制指令下发:前进/后退/转向/割草等(平台->设备),对应 TCP 0x00 remoteControl */
|
||||
public static final String MOWER_CONTROL_SET = "mower/%s/action/control/set";
|
||||
public static final String MOWER_CONTROL_SET = "mower/%s/control/remote/set";
|
||||
|
||||
// ==================== 任务管理 ====================
|
||||
/** 路径规划下发(平台->设备),对应 TCP 0x01 path */
|
||||
@@ -71,6 +75,9 @@ public class MqttTopic {
|
||||
/** OTA 升级结果上报(设备->平台) */
|
||||
public static final String MOWER_OTA_RESULT_POST = "mower/+/ota/result/post";
|
||||
|
||||
/** 寻车指令(平台->设备) */
|
||||
public static final String MOWER_SEARCH_DEVICE_SET = "mower/%s/action/search/set";
|
||||
|
||||
// ==================== 设备信息 ====================
|
||||
// /** 查询设备信息(平台->设备) */
|
||||
// public static final String MOWER_INFO_DEVICE_GET =
|
||||
|
||||
@@ -116,7 +116,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
// 过滤请求
|
||||
.authorizeRequests()
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
.antMatchers("/iot/host/upload-path-csv","/api/thermal/**","/iotDA/device/**", "/websocket/allMemory", "/iot/UAV/**", "/iot/api/**", "/iot/device/userDevice", "/external/sms/sendAliSmsCode", "/login", "/register", "/captchaImage", "/iot/tool/register", "/iot/tool/ntp",
|
||||
.antMatchers("/system/param/list","/iot/host/upload-path-csv","/api/thermal/**","/iotDA/device/**", "/websocket/allMemory", "/iot/UAV/**", "/iot/api/**", "/iot/device/userDevice", "/external/sms/sendAliSmsCode", "/login", "/register", "/captchaImage", "/iot/tool/register", "/iot/tool/ntp",
|
||||
"/iot/tool/mqtt/auth", "/iot/workRecord/**", "/iot/tool/mqtt/authv5", "/iot/tool/mqtt/webhook", "/iot/tool/mqtt/webhookv5", "/auth/**/**",
|
||||
"/wechat/mobileLogin", "/wechat/miniLogin", "/wechat/wxBind/callback").permitAll()
|
||||
.antMatchers("/zlmhook/**").permitAll()
|
||||
|
||||
@@ -44,5 +44,4 @@ public class NettyDeviceController extends BaseController {
|
||||
nettyDeviceService.sendCommand(command);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,64 @@
|
||||
package com.maibu.init;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.maibu.core.business.*;
|
||||
import com.maibu.mapper.*;
|
||||
import com.maibu.service.impl.IotDeviceCommonService;
|
||||
import org.checkerframework.checker.units.qual.s;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.constant.FastBeeConstant;
|
||||
import com.maibu.core.business.AlarmOrderConfig;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.DeviceModel;
|
||||
import com.maibu.core.business.DevicePlan;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.business.ErrorIdentificationStandard;
|
||||
import com.maibu.core.business.IoTCommonDevice;
|
||||
import com.maibu.core.business.OrderModel;
|
||||
import com.maibu.core.business.Product;
|
||||
import com.maibu.core.domain.entity.SysParam;
|
||||
import com.maibu.core.domain.entity.SysSite;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.influxdb.util.InfluxDBUtil;
|
||||
import com.maibu.mapper.AlarmOrderConfigMapper;
|
||||
import com.maibu.mapper.DevicePlanMapper;
|
||||
import com.maibu.mapper.DevicePlanTaskMapper;
|
||||
import com.maibu.mapper.DeviceProductMapper;
|
||||
import com.maibu.mapper.DeviceRunParamMapper;
|
||||
import com.maibu.mapper.ErrorIdentificationStandardMapper;
|
||||
import com.maibu.mapper.IotDeviceCommonMapper;
|
||||
import com.maibu.mapper.OrderModelMapper;
|
||||
import com.maibu.mapper.SysDeviceModelMapper;
|
||||
import com.maibu.mapper.SysParamMapper;
|
||||
import com.maibu.mapper.SysSiteMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import com.maibu.mqtt.MqttClientUtil;
|
||||
import com.maibu.mybatis.LambdaQueryWrapperX;
|
||||
import com.maibu.service.DevicePlanTaskMonitorService;
|
||||
import com.maibu.service.DeviceThreadService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import com.maibu.service.impl.IotDeviceCommonService;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@@ -81,6 +111,7 @@ public class InitThread implements ApplicationRunner {
|
||||
@Autowired
|
||||
private ErrorIdentificationStandardMapper errorIdentificationStandardMapper;
|
||||
@Autowired
|
||||
|
||||
private OrderModelMapper orderModelMapper;
|
||||
@Autowired
|
||||
private AlarmOrderConfigMapper alarmOrderConfigMapper;
|
||||
@@ -88,6 +119,12 @@ public class InitThread implements ApplicationRunner {
|
||||
@Autowired
|
||||
private IotDeviceCommonService commonService;
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@Autowired
|
||||
private SysParamMapper sysParamMapper;
|
||||
|
||||
@Value("${influxdb.url}")
|
||||
private String influxDBUrl;
|
||||
|
||||
@@ -119,12 +156,15 @@ public class InitThread implements ApplicationRunner {
|
||||
private String mqttClientId;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws MqttException {
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
recoverMemory();
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() throws MqttException {
|
||||
private void init() throws Exception {
|
||||
//初始化系统参数
|
||||
initSystemParam();
|
||||
|
||||
// 初始化InfluxDBUtil
|
||||
GlobalMemory.influxDBUtil = new InfluxDBUtil(influxDBUrl, influxDBToken, influxDBOrg, influxDBBucket);
|
||||
|
||||
@@ -185,7 +225,7 @@ public class InitThread implements ApplicationRunner {
|
||||
});
|
||||
}
|
||||
|
||||
//外部设备
|
||||
// 外部设备
|
||||
List<IoTCommonDevice> ioTCommonDeviceList = iotDeviceCommonMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(ioTCommonDeviceList)) {
|
||||
ioTCommonDeviceList.forEach(x -> {
|
||||
@@ -197,7 +237,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//产品
|
||||
// 产品
|
||||
List<Product> productList = deviceProductMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(productList)) {
|
||||
productList.forEach(x -> {
|
||||
@@ -209,7 +249,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//设备模型
|
||||
// 设备模型
|
||||
List<DeviceModel> deviceModelList = deviceModelMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(deviceModelList)) {
|
||||
deviceModelList.forEach(x -> {
|
||||
@@ -221,7 +261,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//车辆参数
|
||||
// 车辆参数
|
||||
List<DeviceRunParam> deviceRunParamList = deviceRunParamMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(deviceRunParamList)) {
|
||||
deviceRunParamList.forEach(x -> {
|
||||
@@ -233,7 +273,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//错误标准
|
||||
// 错误标准
|
||||
List<ErrorIdentificationStandard> standadList = errorIdentificationStandardMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(standadList)) {
|
||||
standadList.forEach(x -> {
|
||||
@@ -245,7 +285,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//订单模型
|
||||
// 订单模型
|
||||
List<OrderModel> orderModelList = orderModelMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(orderModelList)) {
|
||||
orderModelList.forEach(x -> {
|
||||
@@ -257,7 +297,7 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
});
|
||||
}
|
||||
//告警订单配置
|
||||
// 告警订单配置
|
||||
List<AlarmOrderConfig> alarmOrderList = alarmOrderConfigMapper.selectList();
|
||||
if (!CollectionUtils.isEmpty(alarmOrderList)) {
|
||||
alarmOrderList.forEach(x -> {
|
||||
@@ -317,4 +357,38 @@ public class InitThread implements ApplicationRunner {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void initSystemParam() throws IOException {
|
||||
LambdaQueryWrapper<SysParam> queryWrapper = new LambdaQueryWrapper<>();
|
||||
List<SysParam> list = sysParamMapper.selectList(queryWrapper);
|
||||
try {
|
||||
// 读取resource目录下的dsystemParam.json文件
|
||||
org.springframework.core.io.Resource resource = resourceLoader
|
||||
.getResource("classpath:systemParam.json");
|
||||
// 使用fastjson2转换为DeviceConfig对象
|
||||
String jsonContent;
|
||||
jsonContent = IoUtil.readUtf8(resource.getInputStream());
|
||||
List<SysParam> params = JSON.parseArray(jsonContent, SysParam.class);
|
||||
List<SysParam> saveList = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
saveList.addAll(params);
|
||||
} else {
|
||||
Map<String, SysParam> map = list.stream()
|
||||
.collect(Collectors.toMap(
|
||||
SysParam::getParamKey,
|
||||
sysParam -> sysParam));
|
||||
if (!CollectionUtils.isEmpty(params)) {
|
||||
params.forEach(x -> {
|
||||
if (!map.containsKey(x.getParamKey())) {
|
||||
saveList.add(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
sysParamMapper.saveOrUpdateBatch(saveList);
|
||||
} catch (Exception e) {
|
||||
log.error("初始化系统参数失败", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.maibu.netty.handler;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.mqtt.MqttTopic;
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,9 +19,13 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.maibu.constant.CommandConstant;
|
||||
import com.maibu.constant.Constant;
|
||||
import com.maibu.core.business.LawnMoverProtocolEntity;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.core.host.DeviceRemoteControlDTO;
|
||||
import com.maibu.core.host.ParamDetail;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -29,7 +37,6 @@ import io.netty.channel.SimpleChannelInboundHandler;
|
||||
@ChannelHandler.Sharable
|
||||
public class CommandForwardHandler extends SimpleChannelInboundHandler<String> {
|
||||
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CommandForwardHandler.class);
|
||||
|
||||
@Autowired
|
||||
@@ -44,12 +51,11 @@ public class CommandForwardHandler extends SimpleChannelInboundHandler<String> {
|
||||
byte[] bytes = Hex.decodeHex(msg.toCharArray());
|
||||
if (bytes.length > 3 && (bytes[2] == CommandConstant.remoteControl
|
||||
|| bytes[2] == CommandConstant.path
|
||||
|| bytes[2] == CommandConstant.status
|
||||
)) {
|
||||
|| bytes[2] == CommandConstant.status)) {
|
||||
|
||||
String senderDeviceId = deviceSessionManager.getDeviceIdByChannel(currentChannel);
|
||||
NettyDevice senderNettyDevice =
|
||||
senderDeviceId != null ? deviceSessionManager.getDevice(senderDeviceId) : null;
|
||||
NettyDevice senderNettyDevice = senderDeviceId != null ? deviceSessionManager.getDevice(senderDeviceId)
|
||||
: null;
|
||||
|
||||
if (senderNettyDevice == null) {
|
||||
logger.debug("发送拒绝,设备:{}未发送上线指令", senderDeviceId);
|
||||
@@ -76,22 +82,73 @@ public class CommandForwardHandler extends SimpleChannelInboundHandler<String> {
|
||||
return;
|
||||
}
|
||||
for (Connector target : connectedDevices) {
|
||||
if (!target.isOnline()) {
|
||||
logger.debug("发送拒绝master:{},消息到达的salve设备:{},已离线", senderDeviceId, target.getConnectorId());
|
||||
continue;
|
||||
}
|
||||
if (!target.canReceive()) {
|
||||
|
||||
if (target == null || !target.canReceive()) {
|
||||
logger.debug("发送拒绝master:{},消息到达的slave设备:{},处于禁止接收状态", senderDeviceId, target.getConnectorId());
|
||||
continue;
|
||||
}
|
||||
// todo 向上位机发送控制消息
|
||||
NettyDevice targetDevice = deviceSessionManager.getDevice(target.getConnectorId());
|
||||
if (targetDevice == null)
|
||||
continue;
|
||||
// 区分有上位机的还有无上位机的 有上位机的通过上位机下发 没有上位机的按照原来的方式下发
|
||||
if (targetDevice.getDevice().getHasHost()) {
|
||||
if (bytes[2] == CommandConstant.remoteControl) {
|
||||
// todo 转换 原先的报文重新组装成上位机的报文格式
|
||||
DeviceRemoteControlDTO deviceRemoteControlDTO = new DeviceRemoteControlDTO();
|
||||
LawnMoverProtocolEntity pEntity = LawnMoverProtocolEntity.parseControlCommand(bytes);
|
||||
if (pEntity != null) {
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId, String.format(MqttTopic.MOWER_CONTROL_SET, target.getConnectorId()), msg);
|
||||
// Channel targetChannel = target.getChannel();
|
||||
// if (targetChannel != null && targetChannel.isActive()) {
|
||||
// targetChannel.writeAndFlush(msg);
|
||||
// logger.debug("从master:{},向slave:{}, 转发消息:{}", senderDeviceId, target.getConnectorId(), msg);
|
||||
// }
|
||||
ParamDetail data = new ParamDetail();
|
||||
// data.setLeft_wheel_rpm(pEntity.getLeftWheelSpeed());
|
||||
// data.setRight_wheel_rpm(pEntity.getRightWheelSpeed());
|
||||
|
||||
double angularSpeed = BigDecimal.valueOf(pEntity.getAngularSpeed())
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
.doubleValue();
|
||||
|
||||
double linearSpeed = BigDecimal.valueOf(pEntity.getLinearSpeed())
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
.doubleValue();
|
||||
|
||||
data.setLinear_x(linearSpeed);
|
||||
data.setAngular_z(angularSpeed);
|
||||
|
||||
data.setChassis_lift(pEntity.getChassisLiftFlag());
|
||||
data.setCutter(pEntity.getMowerSpeedFlag());
|
||||
data.setIgnition(pEntity.getIgnitionFlag());
|
||||
data.setEmergency_stop(pEntity.getEmergencyStopFlag());
|
||||
data.setValid_for_ms(500);
|
||||
deviceRemoteControlDTO.setData(data);
|
||||
deviceRemoteControlDTO
|
||||
.setCommand_id(Constant.remote_control_cmd_prefix + System.currentTimeMillis());
|
||||
deviceRemoteControlDTO.setSn(target.getConnectorId());
|
||||
deviceRemoteControlDTO.setTimestamp(System.currentTimeMillis());
|
||||
deviceRemoteControlDTO
|
||||
.setMessage_id(Constant.remote_control_msg_prefix + System.currentTimeMillis());
|
||||
deviceRemoteControlDTO.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_CONTROL_SET, target.getConnectorId()),
|
||||
JsonUtils.toJsonString(deviceRemoteControlDTO));
|
||||
logger.debug("master:{},向slave:{} 有上位机, 转发遥控指令:{}", senderDeviceId,
|
||||
target.getConnectorId(),
|
||||
JsonUtils.toJsonString(deviceRemoteControlDTO));
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (!target.isOnline()) {
|
||||
logger.debug("发送拒绝master:{},消息到达的salve设备:{},已离线", senderDeviceId,
|
||||
target.getConnectorId());
|
||||
continue;
|
||||
}
|
||||
Channel targetChannel = target.getChannel();
|
||||
if (targetChannel != null && targetChannel.isActive()) {
|
||||
targetChannel.writeAndFlush(msg);
|
||||
logger.debug("从master:{},向slave:{} 无上位机, 转发消息:{}", senderDeviceId,
|
||||
target.getConnectorId(), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ConnectorType.SLAVE.equals(senderNettyDevice.getDeviceType())) {
|
||||
List<NettyDevice> masters = deviceSessionManager.getMastersBySlaveId(senderDeviceId);
|
||||
|
||||
@@ -140,13 +140,13 @@ public class DataToDataBaseHandler extends SimpleChannelInboundHandler<String> {
|
||||
nettyDevice.setLatestStatus(latestStatus);
|
||||
}
|
||||
} else if (bytes[2] == CommandConstant.readConfig) {
|
||||
DeviceRunParam runParam = DeviceRunParam.fromBytes(bytes);
|
||||
logger.debug("收到返回的设备运行参数: {}", JsonUtils.toJsonString(runParam));
|
||||
CompletableFuture<DeviceRunParam> future = ctx.channel().attr(Constant.READ_CONFIG_KEY).get();
|
||||
if (future != null) {
|
||||
future.complete(runParam);
|
||||
ctx.channel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
}
|
||||
// DeviceRunParam runParam = DeviceRunParam.fromBytes(bytes);
|
||||
// logger.debug("收到返回的设备运行参数: {}", JsonUtils.toJsonString(runParam));
|
||||
// CompletableFuture<DeviceRunParam> future = ctx.channel().attr(Constant.READ_CONFIG_KEY).get();
|
||||
// if (future != null) {
|
||||
// future.complete(runParam);
|
||||
// ctx.channel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
// }
|
||||
}
|
||||
ctx.fireChannelRead(msg);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -75,20 +75,20 @@ public class ScheduledTask {
|
||||
System.out.println("0点定时刷新状态执行完成");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws DecoderException {
|
||||
String hex = "AB AA 05 88 4D 43 37 30 30 50 4C 55 53 2D 43 4E 2D 4A 53 2D 31 37 38 34 38 37 31 39 37 39 31 39 30 2D 30 30 30 30 30 30 30 41 2D 36 30 00 B1 FB 7F FE FE FE 00 00 00 00 00 00 00 00 00 00 00 00 00 12 01 48 95 E8 03 E8 03 28 32 91 53 24 4D 43 37 30 30 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 31 32 33 34 35 36 37 38 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 CD CC A4 41 00 00 80 3F 33 33 33 3F B8 1E 05 3F 33 33 33 3F 9A 99 19 3E 00 00 80 3F 00 00 80 3F 00 00 80 3F 32 36 2D 34 2D 32 37 00 2D 32 37 00 50 B1 BF 00 00 AA AB";
|
||||
String cleanHex = hex.replaceAll("\\s+", ""); // 移除所有空白字符
|
||||
byte[] bytes = Hex.decodeHex(cleanHex);
|
||||
DeviceRunParam runParam = DeviceRunParam.fromBytes(bytes);
|
||||
System.out.println(JsonUtils.toJsonString(runParam));
|
||||
// public static void main(String[] args) throws DecoderException {
|
||||
// String hex = "AB AA 05 88 4D 43 37 30 30 50 4C 55 53 2D 43 4E 2D 4A 53 2D 31 37 38 34 38 37 31 39 37 39 31 39 30 2D 30 30 30 30 30 30 30 41 2D 36 30 00 B1 FB 7F FE FE FE 00 00 00 00 00 00 00 00 00 00 00 00 00 12 01 48 95 E8 03 E8 03 28 32 91 53 24 4D 43 37 30 30 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 31 32 33 34 35 36 37 38 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 CD CC A4 41 00 00 80 3F 33 33 33 3F B8 1E 05 3F 33 33 33 3F 9A 99 19 3E 00 00 80 3F 00 00 80 3F 00 00 80 3F 32 36 2D 34 2D 32 37 00 2D 32 37 00 50 B1 BF 00 00 AA AB";
|
||||
// String cleanHex = hex.replaceAll("\\s+", ""); // 移除所有空白字符
|
||||
// byte[] bytes = Hex.decodeHex(cleanHex);
|
||||
// DeviceRunParam runParam = DeviceRunParam.fromBytes(bytes);
|
||||
// System.out.println(JsonUtils.toJsonString(runParam));
|
||||
|
||||
runParam.setLeftBackwardGain(0.2f);
|
||||
runParam.setLeftForwardGain(0.2f);
|
||||
runParam.setRightForwardGain(0.2f);
|
||||
runParam.setRightBackwardGain(0.2f);
|
||||
// runParam.setLeftBackwardGain(0.2f);
|
||||
// runParam.setLeftForwardGain(0.2f);
|
||||
// runParam.setRightForwardGain(0.2f);
|
||||
// runParam.setRightBackwardGain(0.2f);
|
||||
|
||||
byte[] newB = runParam.toWriteBytes();
|
||||
System.out.println(Hex.encodeHexString(newB));
|
||||
// byte[] newB = runParam.toWriteBytes();
|
||||
// System.out.println(Hex.encodeHexString(newB));
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import com.maibu.core.business.dto.DeviceMapPushDTO;
|
||||
import com.maibu.core.business.dto.WebMapMessageDTO;
|
||||
import com.maibu.core.business.dto.WebOlineStatusMessageDTO;
|
||||
import com.maibu.core.enums.*;
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -43,6 +44,7 @@ import com.maibu.core.host.HeartBeatDTO;
|
||||
import com.maibu.core.host.LocationMessage;
|
||||
import com.maibu.core.redis.RedisCache;
|
||||
import com.maibu.dto.DeviceErrorPushDTO;
|
||||
import com.maibu.dto.DeviceTaskStatusMessageDTO;
|
||||
import com.maibu.mapper.DeviceRunStatisticsMapper;
|
||||
import com.maibu.mapper.ErrorIdentificationStandardMapper;
|
||||
import com.maibu.mapper.HostLocationMapper;
|
||||
@@ -297,7 +299,7 @@ public class DeviceThreadService {
|
||||
}
|
||||
if (nowTime - lastActiveTime >= Constant.hostOfflineInterval) {
|
||||
// 超时了判断离线
|
||||
if (nettyDevice != null) {
|
||||
if (nettyDevice != null && nettyDevice.getOnlineStatus() == 1) {
|
||||
nettyDevice.status(DeviceStatus.offline.getType());
|
||||
// todo 推送设备离线
|
||||
String key = NettyCacheKey.latestPositonKey + deviceId;
|
||||
@@ -309,7 +311,10 @@ public class DeviceThreadService {
|
||||
LocationMessage existing = hostLocationMapper.selectOne(queryWrapper);
|
||||
if (existing != null) {
|
||||
locationMessage.setId(existing.getId());
|
||||
} else {
|
||||
locationMessage.setCreateTime(LocalDateTime.now());
|
||||
}
|
||||
locationMessage.setUpdateTime(LocalDateTime.now());
|
||||
hostLocationMapper.saveOrUpdate(locationMessage);
|
||||
}
|
||||
Device device = deviceService.selectDeviceBySerialNumber(deviceId);
|
||||
@@ -345,8 +350,10 @@ public class DeviceThreadService {
|
||||
}
|
||||
// todo 删除实时消息推送里面的数据
|
||||
siteMemory.removeMapPushDTO(deviceId);
|
||||
siteMemory.removeVehicleMessage(deviceId);
|
||||
}
|
||||
|
||||
statusChangePush(deviceId, siteId, 0);
|
||||
sessionManager.removeDevice(deviceId);
|
||||
// TODO 统计总里程、总作业面积
|
||||
|
||||
@@ -380,11 +387,14 @@ public class DeviceThreadService {
|
||||
if (slaveDevice != null) {
|
||||
slaveDevice.setOnlineStatus(1);
|
||||
slaveDevice.setDevice(device);
|
||||
statusChangePush(deviceId, device.getSiteId(), 1);
|
||||
}
|
||||
} else {
|
||||
// todo 推送设备上线
|
||||
nettyDevice.status(1);
|
||||
nettyDevice.setDevice(device);
|
||||
nettyDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
statusChangePush(deviceId, device.getSiteId(), 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -395,8 +405,30 @@ public class DeviceThreadService {
|
||||
}, 0, 500, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void statusChangePush(String deviceId, Long siteId, Integer status) {
|
||||
// todo 推送设备离线
|
||||
WebOlineStatusMessageDTO dto = new WebOlineStatusMessageDTO();
|
||||
dto.setDeviceId(deviceId);
|
||||
dto.setType(MesType.device_status_changed);
|
||||
dto.setOnlineStatus(status);
|
||||
try {
|
||||
// 当前控制的web端
|
||||
websocketMesDispather.dispather(deviceId, JsonUtils.toJsonString(dto));
|
||||
// 地图监控页面推送
|
||||
websocketMesDispather.mapMessageDispather(siteId,
|
||||
JsonUtils.toJsonString(dto));
|
||||
// 推送到mqtt服务器
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.DEVICE_STATUS_PUSH_TOPIC, deviceId), JsonUtils.toJsonString(dto));
|
||||
} catch (Exception e) {
|
||||
log.error("机器状态变化推送失败: siteId={}, error={}", siteId,
|
||||
e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 监控心跳
|
||||
* 地图监控
|
||||
*/
|
||||
public void mapMessagePush() {
|
||||
executor.scheduleWithFixedDelay(() -> {
|
||||
|
||||
@@ -43,12 +43,11 @@ public class TransferDeviceService {
|
||||
@Autowired
|
||||
private DeviceMapper deviceMapper;
|
||||
|
||||
|
||||
public AjaxResult bind(DeviceBindDTO bindDTO, LoginUser user) {
|
||||
try {
|
||||
String deviceId = bindDTO.getDeviceId();
|
||||
String deviceAlias = bindDTO.getDeviceAlias();
|
||||
//判断当前设备是否存
|
||||
// 判断当前设备是否存
|
||||
Device device = iDeviceService.selectDeviceBySerialNumber(deviceId);
|
||||
if (device == null) {
|
||||
return AjaxResult.error("设备不存在");
|
||||
@@ -65,7 +64,7 @@ public class TransferDeviceService {
|
||||
device.setDeviceAlias(deviceAlias);
|
||||
device.setActiveTime(new Date());
|
||||
iDeviceService.updateDeviceBySelf(device);
|
||||
// deviceMapper.updateById(device);
|
||||
// deviceMapper.updateById(device);
|
||||
return AjaxResult.success(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -77,7 +76,7 @@ public class TransferDeviceService {
|
||||
public AjaxResult unbind(DeviceBindDTO bindDTO, LoginUser user) {
|
||||
try {
|
||||
String deviceId = bindDTO.getDeviceId();
|
||||
//判断当前设备是否存
|
||||
// 判断当前设备是否存
|
||||
Device device = iDeviceService.selectDeviceBySerialNumber(deviceId);
|
||||
if (device == null) {
|
||||
return AjaxResult.error("设备不存在");
|
||||
@@ -93,9 +92,9 @@ public class TransferDeviceService {
|
||||
device.setTenantName("");
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
device.setDeviceAlias("");
|
||||
// deviceMapper.updateById(device);
|
||||
// deviceMapper.updateById(device);
|
||||
iDeviceService.updateDeviceBySelf(device);
|
||||
//判断是否正在控制 如果正在控制,删除控制状态
|
||||
// 判断是否正在控制 如果正在控制,删除控制状态
|
||||
LambdaQueryWrapper<UserClient> lambdaWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaWrapper.eq(UserClient::getDeviceName, deviceId);
|
||||
List<UserClient> users = userClientMapper.selectList(lambdaWrapper);
|
||||
@@ -108,12 +107,15 @@ public class TransferDeviceService {
|
||||
NettyDevice deviceMaster = sessionManager.getDevice(masterId);
|
||||
if (deviceMaster != null) {
|
||||
String oldSlave = userClient.getDeviceName();
|
||||
//删除主的连接关系
|
||||
deviceMaster.getConnectedConnectors().removeIf(x -> x.getConnectorId().equals(oldSlave));
|
||||
//删除从的连接关系
|
||||
// 删除主的连接关系
|
||||
deviceMaster.getConnectedConnectors()
|
||||
.removeIf(x -> x.getConnectorId().equals(oldSlave));
|
||||
// 删除从的连接关系
|
||||
NettyDevice oldSlaveDevice = sessionManager.getDevice(oldSlave);
|
||||
if (oldSlaveDevice != null && !CollectionUtils.isEmpty(oldSlaveDevice.getConnectedConnectors())) {
|
||||
Set<com.maibu.core.business.device.Connector> connectedDevices = oldSlaveDevice.getConnectedConnectors();
|
||||
if (oldSlaveDevice != null
|
||||
&& !CollectionUtils.isEmpty(oldSlaveDevice.getConnectedConnectors())) {
|
||||
Set<com.maibu.core.business.device.Connector> connectedDevices = oldSlaveDevice
|
||||
.getConnectedConnectors();
|
||||
connectedDevices.removeIf(x -> x.getConnectorId().equals(masterId));
|
||||
}
|
||||
}
|
||||
@@ -130,21 +132,20 @@ public class TransferDeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public AjaxResult updateDeviceAlias(DeviceBindDTO bindDTO, LoginUser user) {
|
||||
try {
|
||||
String deviceId = bindDTO.getDeviceId();
|
||||
//判断当前设备是否存
|
||||
// 判断当前设备是否存
|
||||
Device device = iDeviceService.selectDeviceBySerialNumber(deviceId);
|
||||
if (device == null) {
|
||||
return AjaxResult.error("设备不存在");
|
||||
} else {
|
||||
// Long tenantId = device.getTenantId();
|
||||
// if (tenantId == -1) {
|
||||
// return AjaxResult.error("设备未绑定");
|
||||
// return AjaxResult.error("设备未绑定");
|
||||
// }
|
||||
// if (!tenantId.equals(user.getUserId())) {
|
||||
// return AjaxResult.error("无操作权限");
|
||||
// return AjaxResult.error("无操作权限");
|
||||
// }
|
||||
device.setDeviceAlias(bindDTO.getDeviceAlias());
|
||||
device.setUpdateTime(LocalDateTime.now());
|
||||
@@ -158,76 +159,76 @@ public class TransferDeviceService {
|
||||
}
|
||||
}
|
||||
|
||||
// public synchronized boolean switchDevice(DeviceBindDTO bindDTO, LoginUser user) {
|
||||
// try {
|
||||
// String slaveId = bindDTO.getDeviceId();
|
||||
// String platform = bindDTO.getPlatform();
|
||||
// String userName = user.getUsername();
|
||||
// String masterId = userName + ":" + platform;
|
||||
// //todo 判断是否有权限 正在控制才能切
|
||||
// //todo 离线没有控制权的怎么切
|
||||
// log.info("switchDevice:{}", masterId);
|
||||
// NettyDevice deviceMaster = sessionManager.getDevice(masterId);
|
||||
// log.info("deviceMaster:{}", deviceMaster);
|
||||
// if (deviceMaster != null) {
|
||||
// log.info("ConnectorStatus:{}", deviceMaster.getConnectorStatus());
|
||||
// if (ConnectorStatus.RECEIVER.equals(deviceMaster.getConnectorStatus())) {
|
||||
// //当前账号没有控制则可以切换为控制?
|
||||
// NettyDevice activeDevice = sessionManager.getUserControl(userName);
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// if (activeDevice == null) {
|
||||
// log.info("bindConnector ACTIVE :{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
|
||||
// } else {
|
||||
// log.info("bindConnector RECEIVER :{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
|
||||
// }
|
||||
// } else {
|
||||
// //从关联其他设备切换到 当前禁言 假如有控制且不是当前更新为2
|
||||
// List<NettyDevice> controls = sessionManager.getSlaveControl(slaveId);
|
||||
// if (CollectionUtils.isEmpty(controls)) {
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// log.info("bindConnector 1:{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
|
||||
// } else {
|
||||
// NettyDevice controlDevice = controls.get(0);
|
||||
// if (!masterId.equals(controlDevice.getConnectorId())) {
|
||||
// //当前的设备有控制 的主机
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// log.info("bindConnector RECEIVER 2:{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
|
||||
// }
|
||||
// //当前 切当前不做操作
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("切换设备失败: {}", e.getMessage(), e);
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// public synchronized boolean switchDevice(DeviceBindDTO bindDTO, LoginUser
|
||||
// user) {
|
||||
// try {
|
||||
// String slaveId = bindDTO.getDeviceId();
|
||||
// String platform = bindDTO.getPlatform();
|
||||
// String userName = user.getUsername();
|
||||
// String masterId = userName + ":" + platform;
|
||||
// //todo 判断是否有权限 正在控制才能切
|
||||
// //todo 离线没有控制权的怎么切
|
||||
// log.info("switchDevice:{}", masterId);
|
||||
// NettyDevice deviceMaster = sessionManager.getDevice(masterId);
|
||||
// log.info("deviceMaster:{}", deviceMaster);
|
||||
// if (deviceMaster != null) {
|
||||
// log.info("ConnectorStatus:{}", deviceMaster.getConnectorStatus());
|
||||
// if (ConnectorStatus.RECEIVER.equals(deviceMaster.getConnectorStatus())) {
|
||||
// //当前账号没有控制则可以切换为控制?
|
||||
// NettyDevice activeDevice = sessionManager.getUserControl(userName);
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// if (activeDevice == null) {
|
||||
// log.info("bindConnector ACTIVE :{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
|
||||
// } else {
|
||||
// log.info("bindConnector RECEIVER :{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
|
||||
// }
|
||||
// } else {
|
||||
// //从关联其他设备切换到 当前禁言 假如有控制且不是当前更新为2
|
||||
// List<NettyDevice> controls = sessionManager.getSlaveControl(slaveId);
|
||||
// if (CollectionUtils.isEmpty(controls)) {
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// log.info("bindConnector 1:{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 1);
|
||||
// } else {
|
||||
// NettyDevice controlDevice = controls.get(0);
|
||||
// if (!masterId.equals(controlDevice.getConnectorId())) {
|
||||
// //当前的设备有控制 的主机
|
||||
// deviceMaster.getConnectedConnectors().clear();
|
||||
// log.info("bindConnector RECEIVER 2:{}", masterId);
|
||||
// sessionManager.bindConnector(masterId, slaveId);
|
||||
// deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
|
||||
// deviceMaster.setCurrentSlaveId(slaveId);
|
||||
// sysUserClientService.updateAliveStatus(masterId, slaveId, 2);
|
||||
// }
|
||||
// //当前 切当前不做操作
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("切换设备失败: {}", e.getMessage(), e);
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public synchronized boolean switchDevice(DeviceBindDTO bindDTO) {
|
||||
try {
|
||||
String slaveId = bindDTO.getDeviceId();
|
||||
// String platform = bindDTO.getPlatform();
|
||||
// String userName = user.getUsername();
|
||||
|
||||
// String masterId = userName + ":" + platform;
|
||||
// String platform = bindDTO.getPlatform();
|
||||
// String userName = user.getUsername();
|
||||
|
||||
// String masterId = userName + ":" + platform;
|
||||
|
||||
String token = bindDTO.getToken();
|
||||
|
||||
@@ -247,9 +248,10 @@ public class TransferDeviceService {
|
||||
sessionManager.lock(slaveId, token);
|
||||
log.info("switchDevice bindConnector slaveId:{},token:{}", slaveId, token);
|
||||
} else {
|
||||
List<String> connectorIds = controls.stream().map(NettyDevice::getConnectorId).collect(Collectors.toList());
|
||||
List<String> connectorIds = controls.stream().map(NettyDevice::getConnectorId)
|
||||
.collect(Collectors.toList());
|
||||
if (!connectorIds.contains(token)) {
|
||||
//当前的设备有控制 的主机
|
||||
// 当前的设备有控制 的主机
|
||||
deviceMaster.getConnectedConnectors().clear();
|
||||
sessionManager.bindConnector(token, slaveId);
|
||||
deviceMaster.setConnectorStatus(ConnectorStatus.RECEIVER);
|
||||
@@ -260,16 +262,15 @@ public class TransferDeviceService {
|
||||
deviceMaster.setCurrentSlaveId(slaveId);
|
||||
sessionManager.lock(slaveId, token);
|
||||
}
|
||||
//当前 切当前不做操作
|
||||
// 当前 切当前不做操作
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("切换设备失败: {}", e.getMessage(), e);
|
||||
log.error("切换设备失败", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public DeviceControlDTO remoteControl(DeviceBindDTO bindDTO) {
|
||||
try {
|
||||
String token = bindDTO.getToken();
|
||||
@@ -290,7 +291,6 @@ public class TransferDeviceService {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public DeviceSwitchControlDTO switchControl(DeviceBindDTO bindDTO, LoginUser user) {
|
||||
try {
|
||||
String slaveId = bindDTO.getDeviceId();
|
||||
@@ -299,11 +299,11 @@ public class TransferDeviceService {
|
||||
String masterId = userName + ":" + platform;
|
||||
|
||||
DeviceSwitchControlDTO dto = new DeviceSwitchControlDTO();
|
||||
//收到明确的切换设备请求了 从哪边切换到另一边
|
||||
//判断当前是否有控制的设备
|
||||
// 收到明确的切换设备请求了 从哪边切换到另一边
|
||||
// 判断当前是否有控制的设备
|
||||
NettyDevice masterDevice = sessionManager.getDevice(masterId);
|
||||
if (masterDevice == null || !masterDevice.getChannel().isActive()) {
|
||||
//主机已离线
|
||||
// 主机已离线
|
||||
dto.setSwitchControl(false);
|
||||
dto.setReason("主机已离线");
|
||||
return dto;
|
||||
@@ -311,8 +311,8 @@ public class TransferDeviceService {
|
||||
|
||||
NettyDevice slaveDevice = sessionManager.getDevice(slaveId);
|
||||
if (slaveDevice == null || !masterDevice.getChannel().isActive()) {
|
||||
//从机已离线
|
||||
//主机已离线
|
||||
// 从机已离线
|
||||
// 主机已离线
|
||||
dto.setSwitchControl(false);
|
||||
dto.setReason("从机已离线");
|
||||
return dto;
|
||||
@@ -321,7 +321,7 @@ public class TransferDeviceService {
|
||||
List<NettyDevice> controlList = sessionManager.getSlaveControl(slaveId);
|
||||
|
||||
if (!CollectionUtils.isEmpty(controlList)) {
|
||||
//如果当前设备有控制
|
||||
// 如果当前设备有控制
|
||||
controlList.forEach(c -> {
|
||||
if (!c.getConnectorId().equals(masterId)) {
|
||||
c.setCurrentSlaveId(null);
|
||||
@@ -333,7 +333,8 @@ public class TransferDeviceService {
|
||||
}
|
||||
masterDevice.setCurrentSlaveId(slaveId);
|
||||
masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
// sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
|
||||
// sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(),
|
||||
// slaveId, 1);
|
||||
|
||||
dto.setSwitchControl(true);
|
||||
dto.setHolder(platform);
|
||||
|
||||
65
maibu-netty-server/src/main/resources/systemParam.json
Normal file
65
maibu-netty-server/src/main/resources/systemParam.json
Normal file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "systemName",
|
||||
"nameTranslateKey": "system.param.systemName.name",
|
||||
"paramValue": "光伏机器人环境感知服务平台",
|
||||
"descTranslateKey": "system.param.systemName.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "defaultStationName",
|
||||
"nameTranslateKey": "system.param.defaultStationName.name",
|
||||
"paramValue": "",
|
||||
"descTranslateKey": "system.param.defaultStationName.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "defaultLanguage",
|
||||
"nameTranslateKey": "system.param.defaultLanguage.name",
|
||||
"paramValue": "zh_CN",
|
||||
"descTranslateKey": "system.param.defaultLanguage.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "defaultZoneId",
|
||||
"nameTranslateKey": "system.param.defaultZoneId.name",
|
||||
"paramValue": "Asia/Shanghai",
|
||||
"descTranslateKey": "system.param.defaultZoneId.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "daylightSavingTime",
|
||||
"nameTranslateKey": "system.param.daylightSavingTime.name",
|
||||
"paramValue": "true",
|
||||
"descTranslateKey": "system.param.daylightSavingTime.desc",
|
||||
"dataType": "Boolean",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "defaultUnit",
|
||||
"nameTranslateKey": "system.param.defaultUnit.name",
|
||||
"paramValue": "公制",
|
||||
"descTranslateKey": "system.param.defaultUnit.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
},
|
||||
{
|
||||
"paramType": "global",
|
||||
"paramKey": "defaultDateFormat",
|
||||
"nameTranslateKey": "system.param.defaultDateFormat.name",
|
||||
"paramValue": "YYYY-MM-DD HH:mm:ss",
|
||||
"descTranslateKey": "system.param.defaultDateFormat.desc",
|
||||
"dataType": "String",
|
||||
"range": ""
|
||||
}
|
||||
]
|
||||
@@ -8,13 +8,20 @@ import com.maibu.dto.BaseQueryDTO;
|
||||
import com.maibu.service.impl.DeviceRunParamService;
|
||||
import com.maibu.utils.poi.ExcelUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/iot/deviceRunParam")
|
||||
public class DeviceRunParamController extends BaseController {
|
||||
@@ -23,7 +30,7 @@ public class DeviceRunParamController extends BaseController {
|
||||
private DeviceRunParamService service;
|
||||
|
||||
@PostMapping("/save")
|
||||
public AjaxResult save(@RequestBody DeviceRunParam deviceRunParam) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
public AjaxResult save(@RequestBody DeviceRunParam deviceRunParam) {
|
||||
|
||||
return AjaxResult.success(service.save(deviceRunParam));
|
||||
}
|
||||
@@ -35,7 +42,8 @@ public class DeviceRunParamController extends BaseController {
|
||||
}
|
||||
|
||||
@GetMapping("/selectByDeviceId")
|
||||
public AjaxResult selectByDeviceId(@RequestParam String deviceId) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
public AjaxResult selectByDeviceId(@RequestParam String deviceId)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
return AjaxResult.success(service.selectByDeviceId(deviceId));
|
||||
}
|
||||
|
||||
@@ -43,7 +51,7 @@ public class DeviceRunParamController extends BaseController {
|
||||
public AjaxResult delete(@RequestBody List<Long> ids) {
|
||||
return AjaxResult.success(service.delete(ids));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(MultipartFile file) throws Exception {
|
||||
ExcelUtil<DeviceRunParam> util = new ExcelUtil<DeviceRunParam>(DeviceRunParam.class);
|
||||
@@ -51,4 +59,31 @@ public class DeviceRunParamController extends BaseController {
|
||||
boolean message = service.importParam(paramList);
|
||||
return success(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载机器属性导入模板
|
||||
*/
|
||||
@GetMapping("/downloadTemplate")
|
||||
public void downloadTemplate(HttpServletResponse response) throws IOException {
|
||||
String fileName = "机器属性导入模板.xlsx";
|
||||
|
||||
try (InputStream inputStream = new ClassPathResource("机器属性导入模板.xlsx").getInputStream()) {
|
||||
|
||||
response.setContentType(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader(
|
||||
"Content-Disposition",
|
||||
"attachment; filename*=UTF-8''" +
|
||||
URLEncoder.encode(fileName, "UTF-8").replace("+", "%20"));
|
||||
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int len;
|
||||
while ((len = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, len);
|
||||
}
|
||||
outputStream.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
@@ -18,11 +19,13 @@ import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.business.dto.WebRouteStatusMessageDTO;
|
||||
import com.maibu.core.business.inter.WebsocketMesDispather;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.domain.R;
|
||||
import com.maibu.core.enums.MesType;
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
@@ -245,4 +248,12 @@ public class HostComputerController extends BaseController {
|
||||
String.format("%.6f", minLng), String.format("%.6f", maxLng));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/searchDevice")
|
||||
public AjaxResult searchDevice(@RequestParam String deviceId) throws Exception {
|
||||
hostComputerService.searchDevice(deviceId);
|
||||
return success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,11 @@ package com.maibu.controller;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.business.OrderModel;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.maibu.service.impl;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -39,47 +42,55 @@ public class DeviceRunParamService {
|
||||
@Autowired
|
||||
private DeviceSessionManager sessionManager;
|
||||
|
||||
public boolean save(DeviceRunParam deviceRunParam)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
// public boolean save(DeviceRunParam deviceRunParam)
|
||||
// throws ExecutionException, InterruptedException, TimeoutException {
|
||||
|
||||
NettyDevice nettyDevice = sessionManager.getDevice(deviceRunParam.getDeviceId());
|
||||
if (nettyDevice == null || !nettyDevice.getChannel().isActive()) {
|
||||
throw new ServiceException("设备不在线,无法操作!");
|
||||
}
|
||||
// NettyDevice nettyDevice =
|
||||
// sessionManager.getDevice(deviceRunParam.getDeviceId());
|
||||
// if (nettyDevice == null || !nettyDevice.getChannel().isActive()) {
|
||||
// throw new ServiceException("设备不在线,无法操作!");
|
||||
// }
|
||||
|
||||
CompletableFuture<DeviceRunParam> future = new CompletableFuture<>();
|
||||
nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(future);
|
||||
// CompletableFuture<DeviceRunParam> future = new CompletableFuture<>();
|
||||
// nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(future);
|
||||
|
||||
try {
|
||||
nettyDevice.readConfigCommand();
|
||||
// try {
|
||||
// nettyDevice.readConfigCommand();
|
||||
|
||||
DeviceRunParam param = future.get(5, TimeUnit.SECONDS);
|
||||
// DeviceRunParam param = future.get(5, TimeUnit.SECONDS);
|
||||
|
||||
if (param == null) {
|
||||
throw new ServiceException("获取设备当前属性失败!");
|
||||
}
|
||||
// if (param == null) {
|
||||
// throw new ServiceException("获取设备当前属性失败!");
|
||||
// }
|
||||
|
||||
param.setLeftForwardGain(deviceRunParam.getLeftForwardGain());
|
||||
param.setLeftBackwardGain(deviceRunParam.getLeftBackwardGain());
|
||||
param.setRightForwardGain(deviceRunParam.getRightForwardGain());
|
||||
param.setRightBackwardGain(deviceRunParam.getRightBackwardGain());
|
||||
// param.setLeftForwardGain(deviceRunParam.getLeftForwardGain());
|
||||
// param.setLeftBackwardGain(deviceRunParam.getLeftBackwardGain());
|
||||
// param.setRightForwardGain(deviceRunParam.getRightForwardGain());
|
||||
// param.setRightBackwardGain(deviceRunParam.getRightBackwardGain());
|
||||
|
||||
nettyDevice.writeConfigCommand(param);
|
||||
// nettyDevice.writeConfigCommand(param);
|
||||
|
||||
param.setRunSpeed(deviceRunParam.getRunSpeed());
|
||||
param.setDeviceId(deviceRunParam.getDeviceId());
|
||||
param.setSiteId(deviceRunParam.getSiteId());
|
||||
param.setOrgId(deviceRunParam.getOrgId());
|
||||
param.setId(deviceRunParam.getId());
|
||||
// param.setRunSpeed(deviceRunParam.getRunSpeed());
|
||||
// param.setDeviceId(deviceRunParam.getDeviceId());
|
||||
// param.setSiteId(deviceRunParam.getSiteId());
|
||||
// param.setOrgId(deviceRunParam.getOrgId());
|
||||
// param.setId(deviceRunParam.getId());
|
||||
|
||||
// SiteMemory siteMemory = GlobalMemory.getSiteMemory(deviceRunParam.getOrgId(),
|
||||
// deviceRunParam.getSiteId());
|
||||
// if (siteMemory != null) {
|
||||
// siteMemory.saveDeviceRunParam(param);
|
||||
// }
|
||||
// return deviceRunParamMapper.saveOrUpdate(param);
|
||||
// } finally {
|
||||
// nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
// }
|
||||
// }
|
||||
|
||||
public boolean save(DeviceRunParam deviceRunParam) {
|
||||
|
||||
return deviceRunParamMapper.saveOrUpdate(deviceRunParam);
|
||||
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(deviceRunParam.getOrgId(), deviceRunParam.getSiteId());
|
||||
if (siteMemory != null) {
|
||||
siteMemory.saveDeviceRunParam(param);
|
||||
}
|
||||
return deviceRunParamMapper.saveOrUpdate(param);
|
||||
} finally {
|
||||
nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
}
|
||||
}
|
||||
|
||||
public List<DeviceRunParam> list(BaseQueryDTO dto) {
|
||||
@@ -127,6 +138,49 @@ public class DeviceRunParamService {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public DeviceRunParam selectByDeviceId(String deviceId)
|
||||
// throws ExecutionException, InterruptedException, TimeoutException {
|
||||
|
||||
// LambdaQueryWrapper<DeviceRunParam> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// if (!StringUtils.isEmpty(deviceId)) {
|
||||
// queryWrapper.eq(DeviceRunParam::getDeviceId, deviceId);
|
||||
// }
|
||||
// DeviceRunParam result = deviceRunParamMapper.selectOne(queryWrapper);
|
||||
// if (result != null && result.getHasHost() != null && result.getHasHost() ==
|
||||
// 1) {
|
||||
// return result;
|
||||
// } else {
|
||||
// NettyDevice nettyDevice = sessionManager.getDevice(deviceId);
|
||||
// CompletableFuture<DeviceRunParam> future = new CompletableFuture<>();
|
||||
// if (nettyDevice != null && nettyDevice.getChannel() != null &&
|
||||
// nettyDevice.getChannel().isActive()) {
|
||||
// nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(future);
|
||||
// try {
|
||||
// nettyDevice.readConfigCommand();
|
||||
// DeviceRunParam param = future.get(5, TimeUnit.SECONDS);
|
||||
|
||||
// // LambdaQueryWrapper<DeviceRunParam> queryWrapper = new
|
||||
// LambdaQueryWrapper<>();
|
||||
// // if (!StringUtils.isEmpty(deviceId)) {
|
||||
// // queryWrapper.eq(DeviceRunParam::getDeviceId, deviceId);
|
||||
// // }
|
||||
// // DeviceRunParam result = deviceRunParamMapper.selectOne(queryWrapper);
|
||||
// if (result != null) {
|
||||
// param.setId(result.getId());
|
||||
// param.setDeviceId(result.getDeviceId());
|
||||
// param.setRunSpeed(result.getRunSpeed());
|
||||
// param.setOrgId(nettyDevice.getDevice().getOrgId());
|
||||
// param.setSiteId(nettyDevice.getDevice().getSiteId());
|
||||
// }
|
||||
// return param;
|
||||
// } finally {
|
||||
// nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public DeviceRunParam selectByDeviceId(String deviceId)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
|
||||
@@ -135,36 +189,7 @@ public class DeviceRunParamService {
|
||||
queryWrapper.eq(DeviceRunParam::getDeviceId, deviceId);
|
||||
}
|
||||
DeviceRunParam result = deviceRunParamMapper.selectOne(queryWrapper);
|
||||
if (result != null && result.getHasHost() != null && result.getHasHost() == 1) {
|
||||
return result;
|
||||
} else {
|
||||
NettyDevice nettyDevice = sessionManager.getDevice(deviceId);
|
||||
CompletableFuture<DeviceRunParam> future = new CompletableFuture<>();
|
||||
if (nettyDevice != null && nettyDevice.getChannel() != null && nettyDevice.getChannel().isActive()) {
|
||||
nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(future);
|
||||
try {
|
||||
nettyDevice.readConfigCommand();
|
||||
DeviceRunParam param = future.get(5, TimeUnit.SECONDS);
|
||||
|
||||
// LambdaQueryWrapper<DeviceRunParam> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// if (!StringUtils.isEmpty(deviceId)) {
|
||||
// queryWrapper.eq(DeviceRunParam::getDeviceId, deviceId);
|
||||
// }
|
||||
// DeviceRunParam result = deviceRunParamMapper.selectOne(queryWrapper);
|
||||
if (result != null) {
|
||||
param.setId(result.getId());
|
||||
param.setDeviceId(result.getDeviceId());
|
||||
param.setRunSpeed(result.getRunSpeed());
|
||||
param.setOrgId(nettyDevice.getDevice().getOrgId());
|
||||
param.setSiteId(nettyDevice.getDevice().getSiteId());
|
||||
}
|
||||
return param;
|
||||
} finally {
|
||||
nettyDevice.getChannel().attr(Constant.READ_CONFIG_KEY).set(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int delete(List<Long> ids) {
|
||||
@@ -211,19 +236,51 @@ public class DeviceRunParamService {
|
||||
}
|
||||
if (deviceRunParam != null) {
|
||||
deviceRunParam.setCapabilityList(x.getCapabilityList());
|
||||
|
||||
deviceRunParam.setDeviceId(x.getDeviceId());
|
||||
|
||||
parseSn(x.getDeviceId(), deviceRunParam);
|
||||
|
||||
deviceRunParam.setProductModel(x.getProductModel());
|
||||
deviceRunParam.setRtkMode(x.getRtkMode());
|
||||
deviceRunParam.setDeviceType(x.getDeviceType());
|
||||
deviceRunParam.setPowerType(x.getPowerType());
|
||||
deviceRunParam.setRtkMode(x.getRtkMode());
|
||||
deviceRunParam.setCameraNum(x.getCameraNum());
|
||||
deviceRunParam.setPowerType(x.getPowerType());
|
||||
deviceRunParam.setWheelType(x.getWheelType());
|
||||
deviceRunParam.setEngineType(x.getEngineType());
|
||||
deviceRunParam.setHasHost(x.getHasHost());
|
||||
|
||||
deviceRunParam.setBatteryType(x.getBatteryType());
|
||||
deviceRunParam.setWalkingDriveType(x.getWalkingDriveType());
|
||||
deviceRunParam.setCutterDriveType(x.getCutterDriveType());
|
||||
deviceRunParam.setRtkAntennasNum(x.getRtkAntennasNum());
|
||||
deviceRunParam.setHandleType(x.getHandleType());
|
||||
deviceRunParam.setPcbVersion(x.getPcbVersion());
|
||||
deviceRunParam.setDimensions(x.getDimensions());
|
||||
deviceRunParam.setBladeWidth(x.getBladeWidth());
|
||||
deviceRunParam.setTyreSize(x.getTyreSize());
|
||||
deviceRunParam.setSpeedRatio(x.getSpeedRatio());
|
||||
deviceRunParam.setCellularInfo(x.getCellularInfo());
|
||||
deviceRunParam.setWifiName(x.getWifiName());
|
||||
deviceRunParam.setBluetoothName(x.getBluetoothName());
|
||||
deviceRunParam.setHardwareIdentifiers(x.getHardwareIdentifiers());
|
||||
deviceRunParam.setImuModel(x.getImuModel());
|
||||
deviceRunParam.setTempHumiditySensor(x.getTempHumiditySensor());
|
||||
deviceRunParam.setBarometerPresent(x.getBarometerPresent());
|
||||
deviceRunParam.setUltrasonicPresent(x.getUltrasonicPresent());
|
||||
deviceRunParam.setDacPresent(x.getDacPresent());
|
||||
deviceRunParam.setOperator(x.getOperator());
|
||||
deviceRunParam.setInspectionNo(x.getInspectionNo());
|
||||
deviceRunParam.setFirmwareVersion(x.getFirmwareVersion());
|
||||
deviceRunParam.setDealer(x.getDealer());
|
||||
|
||||
saveList.add(deviceRunParam);
|
||||
} else {
|
||||
parseSn(x.getDeviceId(), x);
|
||||
saveList.add(x);
|
||||
}
|
||||
});
|
||||
// todo 增加 解析sn码的功能
|
||||
return deviceRunParamMapper.saveOrUpdateBatch(saveList);
|
||||
}
|
||||
}
|
||||
@@ -233,4 +290,21 @@ public class DeviceRunParamService {
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseSn(String sn, DeviceRunParam deviceRunParam) {
|
||||
if (sn == null || sn.length() != 21) {
|
||||
throw new IllegalArgumentException("SN 必须是 21 位字符串");
|
||||
}
|
||||
|
||||
deviceRunParam.setProductModel(sn.substring(0, 2));
|
||||
deviceRunParam.setFactoryCode(sn.substring(2, 4));
|
||||
deviceRunParam.setLineNum(sn.substring(4, 6));
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMdd");
|
||||
LocalDate date = LocalDate.parse(sn.substring(6, 12), formatter);
|
||||
deviceRunParam.setProductionDate(date);
|
||||
|
||||
deviceRunParam.setSerialNumber(sn.substring(12, 17));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
package com.maibu.service.impl;
|
||||
|
||||
import com.maibu.core.business.WorkRecord;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class HostComputerService {
|
||||
|
||||
@Autowired
|
||||
private WorkRecordService workRecordService;
|
||||
private DeviceSessionManager deviceSessionManager;
|
||||
|
||||
public void searchDevice(String deviceId) throws Exception {
|
||||
NettyDevice device = deviceSessionManager.getDevice(deviceId);
|
||||
if (device != null && device.getOnlineStatus() == 1) {
|
||||
device.searchDevice(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIN
maibu-service/maibu-iot-service/src/main/resources/机器属性导入模板.xlsx
Executable file
BIN
maibu-service/maibu-iot-service/src/main/resources/机器属性导入模板.xlsx
Executable file
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.maibu.core.domain.entity.SysParam;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
|
||||
/**
|
||||
* 设备历史状态
|
||||
*/
|
||||
@Repository
|
||||
public interface SysParamMapper extends BaseMapperX<SysParam> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.maibu.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.domain.entity.SysParam;
|
||||
import com.maibu.core.enums.SysParamType;
|
||||
import com.maibu.mapper.SysParamMapper;
|
||||
import com.maibu.utils.MessageUtils;
|
||||
|
||||
@Service
|
||||
public class SysParamService {
|
||||
|
||||
@Autowired
|
||||
private SysParamMapper sysParamMapper;
|
||||
|
||||
public Map<SysParamType, List<SysParam>> list() {
|
||||
LambdaQueryWrapper<SysParam> queryWrapper = new LambdaQueryWrapper<>();
|
||||
List<SysParam> sysParams = sysParamMapper.selectList(queryWrapper);
|
||||
translateSysParam(sysParams);
|
||||
Map<SysParamType, List<SysParam>> result = sysParams.stream()
|
||||
.collect(Collectors.groupingBy(SysParam::getParamType));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void translateSysParam(List<SysParam> sysParams) {
|
||||
if (!CollectionUtils.isEmpty(sysParams)) {
|
||||
sysParams.forEach(x -> {
|
||||
x.setNameTranslate(MessageUtils.message(x.getNameTranslateKey()));
|
||||
x.setDescTranslate(MessageUtils.message(x.getDescTranslateKey()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean save(List<SysParam> sysParam) {
|
||||
return sysParamMapper.saveOrUpdateBatch(sysParam);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,6 @@
|
||||
package com.maibu.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.domain.entity.SysRole;
|
||||
import com.maibu.core.domain.entity.SysSite;
|
||||
import com.maibu.core.domain.model.LoginUser;
|
||||
import com.maibu.exception.ServiceException;
|
||||
import com.maibu.mapper.SysRegionMapper;
|
||||
import com.maibu.mapper.SysSiteMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -17,8 +8,13 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.maibu.core.domain.entity.SysRole;
|
||||
import com.maibu.core.domain.entity.SysSite;
|
||||
import com.maibu.core.domain.model.LoginUser;
|
||||
import com.maibu.mapper.SysSiteMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
|
||||
@Service
|
||||
public class SysSiteService {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.maibu.control;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DiffSteer {
|
||||
|
||||
public static final int Polarity_High = 0; //0
|
||||
public static final int Polarity_Low = 0; //1
|
||||
public static final int Polarity_High = 0; // 0
|
||||
public static final int Polarity_Low = 0; // 1
|
||||
|
||||
private float turnSpeedScale;
|
||||
private float forwardSpeedScale;
|
||||
@@ -15,6 +18,9 @@ public class DiffSteer {
|
||||
private int leftWheelSpeed;
|
||||
private int rightWheelSpeed;
|
||||
|
||||
private double linearSpeed;
|
||||
private double angularSpeed;
|
||||
|
||||
public int getLeftWheelSpeed() {
|
||||
return leftWheelSpeed;
|
||||
}
|
||||
@@ -63,6 +69,14 @@ public class DiffSteer {
|
||||
rightWheelSpeed = clamp(rightWheelSpeed, -speedAmplLimit, speedAmplLimit);
|
||||
}
|
||||
|
||||
// 计算线速度和轮速度
|
||||
public void calcLinearAngularSpeed(int x, int y, int maxLinear, int maxAngular) {
|
||||
|
||||
this.linearSpeed = y * maxLinear / 1000.0;
|
||||
this.angularSpeed = x * maxAngular / 1000.0;
|
||||
|
||||
}
|
||||
|
||||
// 设置前向速比
|
||||
public void setTurnSpeedScale(int turnSpeedMax, int xMax) {
|
||||
this.turnSpeedScale = (float) turnSpeedMax / (float) xMax;
|
||||
@@ -88,5 +102,4 @@ public class DiffSteer {
|
||||
return (val < min) ? min : ((val > max) ? max : val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.maibu.core.business.dto.WebDeviceTaskStatusMessageDTO;
|
||||
import com.maibu.core.business.dto.WebOlineStatusMessageDTO;
|
||||
import com.maibu.core.business.dto.WebStatusMessageDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.java_websocket.WebSocket;
|
||||
@@ -24,7 +25,6 @@ import com.maibu.dto.DeviceRespondDTO;
|
||||
import com.maibu.dto.NettySwitchDeviceDTO;
|
||||
import com.maibu.dto.ResultDTO;
|
||||
import com.maibu.dto.WebAuthResponseDTO;
|
||||
import com.maibu.dto.WebOlineStatusMessageDTO;
|
||||
import com.maibu.dto.WebSwitchControlResponseDTO;
|
||||
import com.maibu.memory.MiddleGlobalMemory;
|
||||
import com.maibu.netty.NettyClient;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.maibu.utils;
|
||||
|
||||
|
||||
import com.maibu.common.MiddleCommandConstant;
|
||||
import com.maibu.control.DiffSteer;
|
||||
import com.maibu.dto.LawnMoverProtocolEntity;
|
||||
import com.maibu.core.business.LawnMoverProtocolEntity;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -11,24 +10,29 @@ import java.util.List;
|
||||
|
||||
public class ControlUtils {
|
||||
|
||||
|
||||
public static LawnMoverProtocolEntity getCarControlMessage(DiffSteer diffSteer, int originX, int originY, List<Boolean> buttons) {
|
||||
public static LawnMoverProtocolEntity getCarControlMessage(DiffSteer diffSteer, int originX, int originY,
|
||||
List<Boolean> buttons, int maxLinear, int maxAngular) {
|
||||
LawnMoverProtocolEntity state = new LawnMoverProtocolEntity();
|
||||
diffSteer.calcWheelSpeed(originX, originY);
|
||||
diffSteer.calcLinearAngularSpeed(originX, originY, maxLinear, maxAngular);
|
||||
state.setCommandType(MiddleCommandConstant.remoteControl);
|
||||
state.setLeftWheelSpeed((short) diffSteer.getLeftWheelSpeed());
|
||||
state.setRightWheelSpeed((short) diffSteer.getRightWheelSpeed());
|
||||
|
||||
//对应的 button数组 L1 button【4】 R1 button【5】 A对应的button【0】 B对应button【1】 X对应button【2】 Y对应button【3】 button[7]急停
|
||||
//A升B降底盘 X割刀加速Y减速 L1点火 R1熄火
|
||||
state.setLinearSpeed(diffSteer.getLinearSpeed());
|
||||
state.setAngularSpeed(diffSteer.getAngularSpeed());
|
||||
|
||||
// 对应的 button数组 L1 button【4】 R1 button【5】 A对应的button【0】 B对应button【1】
|
||||
// X对应button【2】 Y对应button【3】 button[7]急停
|
||||
// A升B降底盘 X割刀加速Y减速 L1点火 R1熄火
|
||||
Boolean A = buttons.get(0);
|
||||
Boolean B = buttons.get(1);
|
||||
Boolean X = buttons.get(2);
|
||||
Boolean Y = buttons.get(3);
|
||||
Boolean L1 = buttons.get(4);
|
||||
Boolean R1 = buttons.get(5);
|
||||
Boolean eStop = buttons.get(8); //急停
|
||||
//底盘升降
|
||||
Boolean eStop = buttons.get(8); // 急停
|
||||
// 底盘升降
|
||||
int chassisLiftFlag = 0;
|
||||
if (A & !B) {
|
||||
chassisLiftFlag = 1;
|
||||
@@ -36,7 +40,7 @@ public class ControlUtils {
|
||||
chassisLiftFlag = 2;
|
||||
}
|
||||
state.setChassisLiftFlag((byte) chassisLiftFlag);
|
||||
//割刀加减速
|
||||
// 割刀加减速
|
||||
int mowerSpeedFlag = 0;
|
||||
if (X & !Y) {
|
||||
mowerSpeedFlag = 1;
|
||||
@@ -44,7 +48,7 @@ public class ControlUtils {
|
||||
mowerSpeedFlag = 2;
|
||||
}
|
||||
state.setMowerSpeedFlag((byte) mowerSpeedFlag);
|
||||
//点火熄火
|
||||
// 点火熄火
|
||||
int ignitionFlag = 0;
|
||||
if (L1 & !R1) {
|
||||
ignitionFlag = 1;
|
||||
@@ -55,26 +59,29 @@ public class ControlUtils {
|
||||
|
||||
int emergencyStopFlag = eStop ? 1 : 0;
|
||||
state.setEmergencyStopFlag((byte) emergencyStopFlag);
|
||||
// val toBytes = state.toBytes()
|
||||
// println("toBytes==" + LawnMoverProtocolEntity.printBytesToHex(toBytes))
|
||||
// val toBytes = state.toBytes()
|
||||
// println("toBytes==" + LawnMoverProtocolEntity.printBytesToHex(toBytes))
|
||||
return state;
|
||||
}
|
||||
|
||||
public static byte[] buildControlCommand(LawnMoverProtocolEntity entity) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(15);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(27); // 15
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
buffer.put(entity.getHeader1());
|
||||
buffer.put(entity.getHeader2());
|
||||
buffer.put(entity.getCommandType());
|
||||
|
||||
buffer.putShort(entity.getLeftWheelSpeed());//左轮速度
|
||||
buffer.putShort(entity.getRightWheelSpeed());//右轮速度
|
||||
// buffer.putShort(entity.getLeftWheelSpeed());//左轮速度
|
||||
// buffer.putShort(entity.getRightWheelSpeed());//右轮速度
|
||||
|
||||
buffer.put(entity.getChassisLiftFlag());//底盘升降
|
||||
buffer.put(entity.getMowerSpeedFlag());//割刀加减速
|
||||
buffer.put(entity.getIgnitionFlag());//点火状态
|
||||
buffer.put(entity.getEmergencyStopFlag());//急停
|
||||
buffer.putDouble(entity.getAngularSpeed());// 左轮速度
|
||||
buffer.putDouble(entity.getLinearSpeed());// 右轮速度
|
||||
|
||||
buffer.put(entity.getChassisLiftFlag());// 底盘升降
|
||||
buffer.put(entity.getMowerSpeedFlag());// 割刀加减速
|
||||
buffer.put(entity.getIgnitionFlag());// 点火状态
|
||||
buffer.put(entity.getEmergencyStopFlag());// 急停
|
||||
|
||||
buffer.put((byte) 0x00);
|
||||
buffer.put((byte) 0x00);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.maibu.websocket;
|
||||
|
||||
import com.maibu.constant.CommandConstant;
|
||||
import com.maibu.common.MiddleConstant;
|
||||
import com.maibu.core.business.LawnMoverProtocolEntity;
|
||||
import com.maibu.core.enums.CommandRequestType;
|
||||
import com.maibu.core.enums.MesType;
|
||||
import com.maibu.dto.*;
|
||||
@@ -36,7 +37,6 @@ import java.util.concurrent.TimeUnit;
|
||||
public class WebsocketHandler extends WebSocketServer {
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebsocketHandler.class);
|
||||
|
||||
|
||||
// 存储客户端连接:key=WebSocket连接对象,value=最后一次活跃时间(毫秒)
|
||||
private final Map<WebSocket, Long> clientActiveTimeMap = new ConcurrentHashMap<>();
|
||||
// 空闲超时时间(10秒):超过10秒无消息则判定为断开
|
||||
@@ -44,17 +44,17 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
// 定时检测线程池(每隔10秒检测一次空闲连接)
|
||||
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
|
||||
|
||||
|
||||
public WebsocketHandler(int port) {
|
||||
super(new InetSocketAddress(port));
|
||||
|
||||
// 启动空闲连接检测任务
|
||||
// startIdleCheckTask();
|
||||
// startIdleCheckTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket conn, ClientHandshake handshake) {
|
||||
logger.info("客户端连接成功: remoteAddress={}, 当前在线数: {}", conn.getRemoteSocketAddress(), MiddleGlobalMemory.onlineSockets.size());
|
||||
logger.info("客户端连接成功: remoteAddress={}, 当前在线数: {}", conn.getRemoteSocketAddress(),
|
||||
MiddleGlobalMemory.onlineSockets.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +62,8 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
String key = MiddleGlobalMemory.findBySocket(conn);
|
||||
if (key != null) {
|
||||
releaseResource(key);
|
||||
logger.info("客户端断开连接: remoteAddress={}, code={}, reason={}, 当前在线数: {}", conn.getRemoteSocketAddress(), code, reason, MiddleGlobalMemory.onlineSockets.size());
|
||||
logger.info("客户端断开连接: remoteAddress={}, code={}, reason={}, 当前在线数: {}", conn.getRemoteSocketAddress(), code,
|
||||
reason, MiddleGlobalMemory.onlineSockets.size());
|
||||
}
|
||||
MiddleGlobalMemory.removeByWebSocket(conn);
|
||||
}
|
||||
@@ -100,32 +101,34 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
client.initConnect(MiddleConstant.vertxIp, 9001);
|
||||
}
|
||||
} else if (MesType.path.equals(type)) {
|
||||
//todo下发路径 预留
|
||||
// todo下发路径 预留
|
||||
pathDistribute();
|
||||
} else if (MesType.remoteControl.equals(type)) {
|
||||
//遥控
|
||||
// 遥控
|
||||
RemoteData remoteData = webMessageBaseDTO.getRemoteData();
|
||||
if (remoteData != null) {
|
||||
List<Double> axes = remoteData.getAxes();
|
||||
List<Boolean> buttons = remoteData.getButtons();
|
||||
Double y = axes.get(1) * 1000 * -1; //前后值反了
|
||||
Double y = axes.get(1) * 1000 * -1; // 前后值反了
|
||||
Double x = axes.get(2) * 1000;
|
||||
int intX = (int) x.doubleValue();
|
||||
int intY = (int) y.doubleValue();
|
||||
// todo 计算线速度和角速度 还需要根据车型来给线速度 角速度范围最大值
|
||||
MiddleGlobalMemory.initDiff();
|
||||
LawnMoverProtocolEntity entity = ControlUtils.getCarControlMessage(MiddleGlobalMemory.diffSteer, intX, intY, buttons);
|
||||
LawnMoverProtocolEntity entity = ControlUtils.getCarControlMessage(MiddleGlobalMemory.diffSteer,
|
||||
intX, intY, buttons, 1, 2);
|
||||
byte[] buf = ControlUtils.buildControlCommand(entity);
|
||||
logger.debug("Netty客户端:{}发送遥控数据: {}", userName, JsonUtils.toJsonString(entity));
|
||||
NettyClient nettyClient = MiddleGlobalMemory.nettyClientMap.get(key);
|
||||
if (nettyClient != null && nettyClient.isConnected()) {
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
nettyClient.sendData(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if(MesType.heartbeat.equals(type)){
|
||||
// clientActiveTimeMap.put(conn,System.currentTimeMillis());
|
||||
// }
|
||||
// else if(MesType.heartbeat.equals(type)){
|
||||
// clientActiveTimeMap.put(conn,System.currentTimeMillis());
|
||||
// }
|
||||
else if (MesType.switchPermission.equals(type)) {
|
||||
DeviceRequestDTO requestDTO = new DeviceRequestDTO();
|
||||
requestDTO.setRequest(CommandRequestType.switch_control);
|
||||
@@ -138,7 +141,7 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
CommandUtils.buildCommand(buf, requestDTO, CommandConstant.interaction);
|
||||
if (nettyClient != null && nettyClient.isConnected()) {
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
nettyClient.sendData(buf.array());
|
||||
}
|
||||
} else if (MesType.switchResult.equals(type)) {
|
||||
@@ -156,7 +159,7 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
CommandUtils.buildCommand(buf, requestDTO, CommandConstant.interaction);
|
||||
if (nettyClient != null && nettyClient.isConnected()) {
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
// if (!nettyClient.isConnected()) nettyClient.connect();
|
||||
nettyClient.sendData(buf.array());
|
||||
}
|
||||
}
|
||||
@@ -186,7 +189,8 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
@Override
|
||||
public void onError(WebSocket conn, Exception ex) {
|
||||
String key = MiddleGlobalMemory.findBySocket(conn);
|
||||
logger.error("WebSocket错误: clientId={}, remoteAddress={}, error={}", key, conn != null ? conn.getRemoteSocketAddress() : null, ex.getMessage(), ex);
|
||||
logger.error("WebSocket错误: clientId={}, remoteAddress={}, error={}", key,
|
||||
conn != null ? conn.getRemoteSocketAddress() : null, ex.getMessage(), ex);
|
||||
// 发生错误时清理连接
|
||||
if (key != null) {
|
||||
releaseResource(key);
|
||||
@@ -222,7 +226,6 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
logger.debug("广播消息给所有客户端: message={}, 客户端数量: {}", message, connections.size());
|
||||
}
|
||||
|
||||
|
||||
// 核心:定时检测空闲连接(每隔10秒执行一次)
|
||||
private void startIdleCheckTask() {
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
@@ -261,21 +264,21 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
}
|
||||
}
|
||||
}
|
||||
// clientActiveTimeMap.clear(); // 清空空闲记录
|
||||
//
|
||||
// // 2. 关闭定时检测线程池(核心:终止非守护线程)
|
||||
// if (!idleCheckExecutor.isShutdown()) {
|
||||
// idleCheckExecutor.shutdownNow(); // 立即关闭线程池
|
||||
// try {
|
||||
// // 等待线程池终止,最多等3秒
|
||||
// if (!idleCheckExecutor.awaitTermination(3, TimeUnit.SECONDS)) {
|
||||
// logger.warn("空闲检测线程池未正常终止");
|
||||
// }
|
||||
// } catch (InterruptedException e) {
|
||||
// idleCheckExecutor.shutdownNow();
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
// }
|
||||
// clientActiveTimeMap.clear(); // 清空空闲记录
|
||||
//
|
||||
// // 2. 关闭定时检测线程池(核心:终止非守护线程)
|
||||
// if (!idleCheckExecutor.isShutdown()) {
|
||||
// idleCheckExecutor.shutdownNow(); // 立即关闭线程池
|
||||
// try {
|
||||
// // 等待线程池终止,最多等3秒
|
||||
// if (!idleCheckExecutor.awaitTermination(3, TimeUnit.SECONDS)) {
|
||||
// logger.warn("空闲检测线程池未正常终止");
|
||||
// }
|
||||
// } catch (InterruptedException e) {
|
||||
// idleCheckExecutor.shutdownNow();
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
// }
|
||||
|
||||
// 3. 批量关闭所有Netty客户端连接
|
||||
for (NettyClient client : MiddleGlobalMemory.nettyClientMap.values()) {
|
||||
@@ -300,5 +303,3 @@ public class WebsocketHandler extends WebSocketServer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user