Compare commits
45 Commits
main
...
dev_custom
| Author | SHA1 | Date | |
|---|---|---|---|
| c3a2aee8fb | |||
| 99c7a3ab87 | |||
| f25a0b5018 | |||
| e501d58563 | |||
| 965b38158f | |||
| 372b1a2d11 | |||
| e57699dbdf | |||
| 9e3ec6a1dd | |||
| 11984316d4 | |||
| 11e209bcb3 | |||
| bde6b89965 | |||
| 13eefaf152 | |||
| 4fad6cc929 | |||
| 99d4be4ee4 | |||
| eb1884b972 | |||
| c69e89fa7d | |||
| 9cd3b8e496 | |||
| 25a05ae9d8 | |||
| 5c0ee1f811 | |||
| fce873b662 | |||
| 1d2636f641 | |||
| 40c6edda36 | |||
| 64f54c4191 | |||
| be27d2b56e | |||
| f690786847 | |||
| 4f7f32eeb2 | |||
| cfd2906b71 | |||
| 985f501e76 | |||
| a6f662b15b | |||
| 4ee3f6be90 | |||
| fda1060b38 | |||
| 5f369a159d | |||
| a92ec91cd2 | |||
| 9ff685e0c1 | |||
| 544efbd0f9 | |||
| 33df2ff0f7 | |||
| 27f4796c55 | |||
| 16ec98e36a | |||
| 2f94639f0a | |||
| 3eb7f7bc31 | |||
| 1b19e32aa5 | |||
| 80bfdd134d | |||
| ffd9720939 | |||
| 5f3929ae16 | |||
| 3ba32b19ce |
105
.idea/workspace.xml
generated
105
.idea/workspace.xml
generated
@@ -6,21 +6,14 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="84ac1b15-3cfa-4375-9957-45b7b581d04e" name="Changes" comment="# commit">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-admin/src/main/resources/application-dev.yml" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-admin/src/main/resources/application-dev.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/Device.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/Device.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/controller/UAVController.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/controller/UAVController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/dto/UavDeviceStateResponseDetailDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/dto/UavDeviceStateResponseDetailDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/service/UAVService.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-external/src/main/java/com/maibu/uav/service/UAVService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-framework/src/main/java/com/maibu/config/SecurityConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-framework/src/main/java/com/maibu/config/SecurityConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/NettyServer.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/NettyServer.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/core/business/device/NettyDevice.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/memory/DeviceSessionManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-common/src/main/java/com/maibu/memory/DeviceSessionManager.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/dto/DeviceBindDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/dto/DeviceBindDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/CommandForwardHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/CommandForwardHandler.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/DeviceConnectHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/DeviceConnectHandler.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/HeaderFooterDecoder.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/HeaderFooterDecoder.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/HexEncoder.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/netty/handler/HexEncoder.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/DeviceController.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/IDeviceService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/service/impl/DeviceServiceImpl.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/resources/mapper/iot/DeviceMapper.xml" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/resources/mapper/iot/DeviceMapper.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/common/MiddleConstant.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/common/MiddleConstant.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/service/TransferDeviceService.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-netty-server/src/main/java/com/maibu/service/TransferDeviceService.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/dto/NettySwitchDeviceDTO.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/dto/NettySwitchDeviceDTO.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/netty/handler/ClientHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/maibu-web-middleware/src/main/java/com/maibu/netty/handler/ClientHandler.java" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -40,6 +33,11 @@
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="main" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="HttpClientEndpointsTabState">
|
||||
@@ -79,40 +77,40 @@
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"Application.test.executor": "Debug",
|
||||
"HTTP Request.MiddlePlatformApplication | #1.executor": "Run",
|
||||
"HTTP Request.MiddlePlatformApplication | #2.executor": "Run",
|
||||
"HTTP Request.MiddlePlatformApplication | #3.executor": "Run",
|
||||
"Maven.MiddlePlatform [clean].executor": "Run",
|
||||
"Maven.MiddlePlatform [install].executor": "Run",
|
||||
"Maven.maibu-netty-server [clean].executor": "Run",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RequestMappingsPanelOrder0": "0",
|
||||
"RequestMappingsPanelOrder1": "1",
|
||||
"RequestMappingsPanelWidth0": "75",
|
||||
"RequestMappingsPanelWidth1": "75",
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"Spring Boot.MiddlePlatformApplication.executor": "Debug",
|
||||
"git-widget-placeholder": "main",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "/home/maibu/Test/MiddlePlatform/maibu-external/src/main/java/com/maibu/uav",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"onboarding.tips.debug.path": "D:/code/MiddlePlatform/maibu-service/maibu-system-service/src/main/java/com/maibu/Main.java",
|
||||
"settings.editor.selected.configurable": "project.propVCSSupport.CommitDialog",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||
"Application.test.executor": "Debug",
|
||||
"HTTP Request.MiddlePlatformApplication | #1.executor": "Run",
|
||||
"HTTP Request.MiddlePlatformApplication | #2.executor": "Run",
|
||||
"HTTP Request.MiddlePlatformApplication | #3.executor": "Run",
|
||||
"Maven.MiddlePlatform [clean].executor": "Run",
|
||||
"Maven.MiddlePlatform [install].executor": "Run",
|
||||
"Maven.maibu-netty-server [clean].executor": "Run",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RequestMappingsPanelOrder0": "0",
|
||||
"RequestMappingsPanelOrder1": "1",
|
||||
"RequestMappingsPanelWidth0": "75",
|
||||
"RequestMappingsPanelWidth1": "75",
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"Spring Boot.MiddlePlatformApplication.executor": "Debug",
|
||||
"git-widget-placeholder": "dev__control",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "/home/maibu/Test/MiddlePlatform/maibu-external/src/main/java/com/maibu/uav",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"onboarding.tips.debug.path": "D:/code/MiddlePlatform/maibu-service/maibu-system-service/src/main/java/com/maibu/Main.java",
|
||||
"settings.editor.selected.configurable": "project.propVCSSupport.CommitDialog",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
}]]></component>
|
||||
<component name="RdControllerToolWindowsLayoutState" isNewUi="true">
|
||||
<layout>
|
||||
<window_info id="Bookmarks" side_tool="true" />
|
||||
@@ -190,17 +188,6 @@
|
||||
<configuration name="MiddlePlatformApplication | #3" type="HttpClient.HttpRequestRunConfigurationType" factoryName="HTTP Request" temporary="true" nameIsGenerated="true" path="$APPLICATION_CONFIG_DIR$/scratches/MiddlePlatformApplication.http" executionIdentifier="#3" index="3" runType="Run single request">
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="true" type="JetRunConfigurationType">
|
||||
<module name="maibu-iot-service" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="KotlinStandaloneScriptRunConfigurationType">
|
||||
<module name="maibu-iot-service" />
|
||||
<option name="filePath" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="MiddlePlatformApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" temporary="true" nameIsGenerated="true">
|
||||
<option name="FRAME_DEACTIVATION_UPDATE_POLICY" value="UpdateClassesAndResources" />
|
||||
<module name="maibu-admin" />
|
||||
@@ -725,7 +712,7 @@
|
||||
<line-breakpoint enabled="true" type="java-method">
|
||||
<url>file://$PROJECT_DIR$/maibu-service/maibu-iot-service/src/main/java/com/maibu/controller/IOTWorkOrderController.java</url>
|
||||
<line>58</line>
|
||||
<properties class="com.maibu.controller.IOTWorkOrderController" method="edit">
|
||||
<properties class="com.maibu.controller.IOTWorkOrderController" method="list">
|
||||
<option name="EMULATED" value="true" />
|
||||
<option name="WATCH_EXIT" value="false" />
|
||||
</properties>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.maibu.web.controller.system;
|
||||
|
||||
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.controller.BaseController;
|
||||
import com.maibu.core.domain.AjaxResult;
|
||||
import com.maibu.core.domain.map.SiteMapInfo;
|
||||
import com.maibu.service.SiteMapInfoService;
|
||||
|
||||
/**
|
||||
* 区域/场站
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/siteMapInfo")
|
||||
public class SiteMapInfoController extends BaseController {
|
||||
@Autowired
|
||||
private SiteMapInfoService siteMapInfoService;
|
||||
|
||||
/**
|
||||
* 新增或者修改组织
|
||||
*/
|
||||
|
||||
@PostMapping("/save")
|
||||
public AjaxResult save(@RequestBody SiteMapInfo siteMapInfo) {
|
||||
try {
|
||||
return AjaxResult.success(siteMapInfoService.save(siteMapInfo));
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("新增修改场站出错", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询场站详情
|
||||
*/
|
||||
|
||||
@GetMapping("/selectById")
|
||||
public AjaxResult selectById(@RequestParam Long id) {
|
||||
try {
|
||||
return AjaxResult.success(siteMapInfoService.selectById(id));
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("查询场站详情出错", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织下所有的区域场站
|
||||
*/
|
||||
|
||||
@GetMapping("/selectBySiteId")
|
||||
public AjaxResult selectBySiteId(@RequestParam Long siteId) {
|
||||
try {
|
||||
return AjaxResult.success(siteMapInfoService.selectBySiteId(siteId));
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("查询组织下所有场站出错", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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,16 +1,19 @@
|
||||
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.RequestParam;
|
||||
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.SysRegion;
|
||||
import com.maibu.core.domain.entity.SysSite;
|
||||
import com.maibu.core.page.TableDataInfo;
|
||||
import com.maibu.service.SysRegionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 区域/场站
|
||||
@@ -23,20 +26,6 @@ public class SysRegionController extends BaseController {
|
||||
@Autowired
|
||||
private SysRegionService sysRegionService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询组织列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysRegion region) {
|
||||
try {
|
||||
startPage();
|
||||
return getDataTable(sysRegionService.list(region));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或者修改组织
|
||||
*/
|
||||
@@ -81,9 +70,9 @@ public class SysRegionController extends BaseController {
|
||||
*/
|
||||
|
||||
@GetMapping("/selectBySiteId")
|
||||
public AjaxResult selectBySiteId(@RequestParam Long id) {
|
||||
public AjaxResult selectBySiteId(@RequestParam Long siteId) {
|
||||
try {
|
||||
return AjaxResult.success(sysRegionService.selectBySiteId(id));
|
||||
return AjaxResult.success(sysRegionService.selectBySiteId(siteId));
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("保存组织出错", e.getMessage());
|
||||
}
|
||||
|
||||
@@ -84,3 +84,6 @@ influxdb:
|
||||
org: maibu
|
||||
token: maibu-token
|
||||
url: http://localhost:8086
|
||||
|
||||
minio:
|
||||
endpoint : https://oss.satabot.com
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,37 +30,37 @@ public class DeviceTask {
|
||||
|
||||
private int keepAlive;
|
||||
|
||||
/*设备状态池*/
|
||||
/* 设备状态池 */
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_STATUS_TASK)
|
||||
public Executor deviceStatusTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_STATUS_TASK);
|
||||
}
|
||||
|
||||
/*平台自动获取线程池(例如定时获取设备信息)*/
|
||||
/* 平台自动获取线程池(例如定时获取设备信息) */
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK)
|
||||
public Executor deviceFetchTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_FETCH_PROP_TASK);
|
||||
}
|
||||
|
||||
/*设备回调信息(下发指令(服务)设备应答信息)*/
|
||||
/* 设备回调信息(下发指令(服务)设备应答信息) */
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK)
|
||||
public Executor deviceReplyTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_REPLY_MESSAGE_TASK);
|
||||
}
|
||||
|
||||
/*设备主动上报(设备数据有变化主动上报)*/
|
||||
/* 设备主动上报(设备数据有变化主动上报) */
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK)
|
||||
public Executor deviceUpMessageTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_UP_MESSAGE_TASK);
|
||||
}
|
||||
|
||||
/*指令下发(服务下发)*/
|
||||
/* 指令下发(服务下发) */
|
||||
@Bean(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK)
|
||||
public Executor functionInvokeTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.FUNCTION_INVOKE_TASK);
|
||||
}
|
||||
|
||||
/*内部消费线程*/
|
||||
/* 内部消费线程 */
|
||||
@Bean(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK)
|
||||
public Executor messageConsumeTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.MESSAGE_CONSUME_TASK);
|
||||
@@ -81,7 +81,7 @@ public class DeviceTask {
|
||||
return builder(FastBeeConstant.TASK.DELAY_UPGRADE_TASK);
|
||||
}
|
||||
|
||||
/*设备其他消息处理*/
|
||||
/* 设备其他消息处理 */
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_OTHER_TASK)
|
||||
public Executor deviceOtherTaskExecutor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_OTHER_TASK);
|
||||
@@ -97,6 +97,26 @@ public class DeviceTask {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_ERROR_MONITOR);
|
||||
}
|
||||
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_HEARTBEAT_MONITOR)
|
||||
public Executor deviceHeartBeatMonitor() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_HEARTBEAT_MONITOR);
|
||||
}
|
||||
|
||||
@Bean(FastBeeConstant.TASK.AUTO_RULE)
|
||||
public Executor autoRule() {
|
||||
return builder(FastBeeConstant.TASK.AUTO_RULE);
|
||||
}
|
||||
|
||||
@Bean(FastBeeConstant.TASK.REGION_CONSECUTIVE_TASK)
|
||||
public Executor regionConsecutiveTask() {
|
||||
return builder(FastBeeConstant.TASK.REGION_CONSECUTIVE_TASK);
|
||||
}
|
||||
|
||||
@Bean(FastBeeConstant.TASK.MAP_MESSAGE_PUSH)
|
||||
public Executor mapMessagePush() {
|
||||
return builder(FastBeeConstant.TASK.MAP_MESSAGE_PUSH);
|
||||
}
|
||||
|
||||
@Bean(FastBeeConstant.TASK.DEVICE_TASK_HANDLER)
|
||||
public Executor deviceTaskHandler() {
|
||||
return builder(FastBeeConstant.TASK.DEVICE_TASK_HANDLER);
|
||||
@@ -107,8 +127,7 @@ public class DeviceTask {
|
||||
return builder(FastBeeConstant.TASK.COMMON_DEVICE_MONITOR);
|
||||
}
|
||||
|
||||
|
||||
/*组装线程池*/
|
||||
/* 组装线程池 */
|
||||
private ThreadPoolTaskExecutor builder(String threadNamePrefix) {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(coreSize);
|
||||
@@ -117,7 +136,7 @@ public class DeviceTask {
|
||||
executor.setQueueCapacity(queueCapacity);
|
||||
// 线程池对拒绝任务的处理策略
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
//线程池名的前缀
|
||||
// 线程池名的前缀
|
||||
executor.setThreadNamePrefix(threadNamePrefix);
|
||||
executor.initialize();
|
||||
return executor;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -21,7 +21,16 @@ public class Constant {
|
||||
|
||||
public static final AttributeKey<String> ATT_SITE_ID = AttributeKey.valueOf("siteId");
|
||||
|
||||
public static final String WheelGainCoefficients = "WheelGainCoefficients";
|
||||
public static final String WheelGainCoefficients = "WheelGainCoefficients";
|
||||
|
||||
public static final String mqttClientPrefix = "common-device-client-";
|
||||
public static final String mqttClientPrefix = "common-device-client-";
|
||||
|
||||
public static final String mqttHandleKey = "hostHandle";
|
||||
|
||||
public static final Long hostOfflineInterval = 10000L; // 单位毫秒
|
||||
|
||||
// ==================== 远程控制 ====================
|
||||
public static final String protocol_version = "1.4.5";
|
||||
public static final String remote_control_msg_prefix = "remote-msg";
|
||||
public static final String remote_control_cmd_prefix = "remote-cmd";
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ public interface FastBeeConstant {
|
||||
String UFT8 = "UTF-8";
|
||||
String GB2312 = "GB2312";
|
||||
|
||||
|
||||
String MQTT = "mqtt";
|
||||
String PORT = "port";
|
||||
String ADAPTER = "adapter";
|
||||
@@ -27,16 +26,16 @@ public interface FastBeeConstant {
|
||||
String WM_PREFIX = "server-";
|
||||
String FAST_PHONE = "phone-";
|
||||
|
||||
/*MQTT平台判定离线时间 keepAlive*1.5 */
|
||||
/* MQTT平台判定离线时间 keepAlive*1.5 */
|
||||
Long DEVICE_PING_EXPIRED = 90000L;
|
||||
}
|
||||
|
||||
interface CLIENT {
|
||||
//加盐
|
||||
// 加盐
|
||||
String TOKEN = "fastbee-smart!@#$123";
|
||||
}
|
||||
|
||||
/*webSocket配置*/
|
||||
/* webSocket配置 */
|
||||
interface WS {
|
||||
String HEART_BEAT = "heartbeat";
|
||||
String HTTP_SERVER_CODEC = "httpServerCodec";
|
||||
@@ -87,19 +86,40 @@ public interface FastBeeConstant {
|
||||
* 消息消费线程
|
||||
*/
|
||||
String MESSAGE_CONSUME_TASK = "messageConsumeTask";
|
||||
/*内部消费线程publish*/
|
||||
/* 内部消费线程publish */
|
||||
String MESSAGE_CONSUME_TASK_PUB = "messageConsumeTaskPub";
|
||||
/*内部消费线程Fetch*/
|
||||
/* 内部消费线程Fetch */
|
||||
String MESSAGE_CONSUME_TASK_FETCH = "messageConsumeTaskFetch";
|
||||
/*OTA升级延迟队列*/
|
||||
/* OTA升级延迟队列 */
|
||||
String DELAY_UPGRADE_TASK = "delayUpgradeTask";
|
||||
/*OTA升级线程池*/
|
||||
/* OTA升级线程池 */
|
||||
String OTA_THREAD_POOL = "otaThreadPoolTaskExecutor";
|
||||
|
||||
/**
|
||||
* 设备错误
|
||||
*/
|
||||
String DEVICE_ERROR_MONITOR = "deviceErrorMonitor";
|
||||
|
||||
/**
|
||||
* 设备错误
|
||||
*/
|
||||
String DEVICE_HEARTBEAT_MONITOR = "deviceHeartBeatMonitor";
|
||||
|
||||
/**
|
||||
* 设备错误
|
||||
*/
|
||||
String MAP_MESSAGE_PUSH = "mapMessagePush";
|
||||
|
||||
/**
|
||||
* 规则触发任务
|
||||
*/
|
||||
String AUTO_RULE = "autoRule";
|
||||
|
||||
/**
|
||||
* 区域连续任务处理
|
||||
*/
|
||||
String REGION_CONSECUTIVE_TASK = "regionConsecutiveTaskHandler";
|
||||
|
||||
/**
|
||||
* 设备任务处理线程
|
||||
*/
|
||||
@@ -116,67 +136,66 @@ public interface FastBeeConstant {
|
||||
|
||||
String PREDIX = "/+/+";
|
||||
|
||||
/*OTA消息回复*/
|
||||
/* OTA消息回复 */
|
||||
String OTA_REPLY = "upgrade/reply";
|
||||
|
||||
}
|
||||
|
||||
/*集群,全局发布的消息类型*/
|
||||
/* 集群,全局发布的消息类型 */
|
||||
interface CHANNEL {
|
||||
/*设备状态*/
|
||||
/* 设备状态 */
|
||||
String DEVICE_STATUS = "device_status";
|
||||
/*平台读取属性*/
|
||||
/* 平台读取属性 */
|
||||
String PROP_READ = "prop_read";
|
||||
/*推送消息*/
|
||||
/* 推送消息 */
|
||||
String PUBLISH = "publish";
|
||||
/*服务下发*/
|
||||
/* 服务下发 */
|
||||
String FUNCTION_INVOKE = "function_invoke";
|
||||
/*事件*/
|
||||
/* 事件 */
|
||||
String EVENT = "event";
|
||||
/*other*/
|
||||
/* other */
|
||||
String OTHER = "other";
|
||||
/*Qos1 推送应答*/
|
||||
/* Qos1 推送应答 */
|
||||
String PUBLISH_ACK = "publish_ack";
|
||||
/*Qos2 发布消息收到*/
|
||||
/* Qos2 发布消息收到 */
|
||||
String PUB_REC = "pub_rec";
|
||||
/*Qos 发布消息释放*/
|
||||
/* Qos 发布消息释放 */
|
||||
String PUB_REL = "pub_rel";
|
||||
/*Qos2 发布消息完成*/
|
||||
/* Qos2 发布消息完成 */
|
||||
String PUB_COMP = "pub_comp";
|
||||
|
||||
String UPGRADE = "upgrade";
|
||||
|
||||
/*-------------------------ROCKETMQ-------------------------*/
|
||||
String SUFFIX = "group";
|
||||
/*设备状态*/
|
||||
/* 设备状态 */
|
||||
String DEVICE_STATUS_GROUP = DEVICE_STATUS + SUFFIX;
|
||||
String PROP_READ_GROUP = PROP_READ + SUFFIX;
|
||||
/*服务下发*/
|
||||
/* 服务下发 */
|
||||
String FUNCTION_INVOKE_GROUP = FUNCTION_INVOKE + SUFFIX;
|
||||
/*推送消息*/
|
||||
/* 推送消息 */
|
||||
String PUBLISH_GROUP = PUBLISH + SUFFIX;
|
||||
/*Qos1 推送应答*/
|
||||
/* Qos1 推送应答 */
|
||||
String PUBLISH_ACK_GROUP = PUBLISH_ACK + SUFFIX;
|
||||
/*Qos2 发布消息收到*/
|
||||
/* Qos2 发布消息收到 */
|
||||
String PUB_REC_GROUP = PUB_REC + SUFFIX;
|
||||
/*Qos 发布消息释放*/
|
||||
/* Qos 发布消息释放 */
|
||||
String PUB_REL_GROUP = PUB_REL + SUFFIX;
|
||||
/*Qos2 发布消息完成*/
|
||||
/* Qos2 发布消息完成 */
|
||||
String PUB_COMP_GROUP = PUB_COMP + SUFFIX;
|
||||
/*OTA升级*/
|
||||
/* OTA升级 */
|
||||
String UPGRADE_GROUP = UPGRADE + SUFFIX;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* redisKey 定义
|
||||
*/
|
||||
interface REDIS {
|
||||
/*在线设备列表*/
|
||||
/* 在线设备列表 */
|
||||
String DEVICE_ONLINE_LIST = "device:online:list";
|
||||
/*设备实时状态key*/
|
||||
/* 设备实时状态key */
|
||||
String DEVICE_RUNTIME_DATA = "device:runtime:";
|
||||
/*通讯协议参数*/
|
||||
/* 通讯协议参数 */
|
||||
String DEVICE_PROTOCOL_PARAM = "device:param:";
|
||||
/**
|
||||
* 设备消息id缓存key
|
||||
@@ -215,11 +234,11 @@ public interface FastBeeConstant {
|
||||
*/
|
||||
String MESSAGE_RETAIN_TOTAL = "message:retain:total";
|
||||
|
||||
/*发送消息数*/
|
||||
/* 发送消息数 */
|
||||
String MESSAGE_SEND_TOTAL = "message:send:total";
|
||||
/*接收消息数*/
|
||||
/* 接收消息数 */
|
||||
String MESSAGE_RECEIVE_TOTAL = "message:receive:total";
|
||||
/*连接次数*/
|
||||
/* 连接次数 */
|
||||
String MESSAGE_CONNECT_TOTAL = "message:connect:total";
|
||||
/**
|
||||
* 认证次数
|
||||
@@ -304,7 +323,6 @@ public interface FastBeeConstant {
|
||||
String CH = "CH";
|
||||
String ModbusTcp = "MODBUS-TCP";
|
||||
|
||||
|
||||
}
|
||||
|
||||
interface URL {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.maibu.common;
|
||||
|
||||
import lombok.Data;
|
||||
package com.maibu.constant;
|
||||
|
||||
public class NettyCacheKey {
|
||||
|
||||
public static final String deviceRunningStatusKey = "running_status:";
|
||||
|
||||
public static final String latestPositonKey = "latest_position:";
|
||||
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.maibu.annotation.Excel;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.core.host.LocationMessage;
|
||||
import com.maibu.core.host.VehicleMessage;
|
||||
import com.maibu.influxdb.MowerRealTimeData;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
@@ -72,7 +74,6 @@ public class Device extends BaseDO {
|
||||
@Excel(name = "产品名称")
|
||||
private String productName;
|
||||
|
||||
|
||||
/**
|
||||
* 租户名称
|
||||
*/
|
||||
@@ -85,8 +86,7 @@ public class Device extends BaseDO {
|
||||
*/
|
||||
@ApiModelProperty("固件版本")
|
||||
@Excel(name = "固件版本")
|
||||
private BigDecimal firmwareVersion;
|
||||
|
||||
private String firmwareVersion;
|
||||
|
||||
/**
|
||||
* WIFI固件版本
|
||||
@@ -95,7 +95,6 @@ public class Device extends BaseDO {
|
||||
@Excel(name = "HTTP推送固件版本")
|
||||
private BigDecimal wirelessVersion;
|
||||
|
||||
|
||||
/**
|
||||
* 设备状态(1-未激活,2-禁用,3-在线,4-离线)
|
||||
*/
|
||||
@@ -106,12 +105,12 @@ public class Device extends BaseDO {
|
||||
/**
|
||||
* 设备在线状态(1-在线,2-离线)
|
||||
*/
|
||||
@ApiModelProperty("设备状态(1-在线,2-离线)")
|
||||
@ApiModelProperty("设备状态(1-在线,0-离线)")
|
||||
@Excel(name = "设备在线状态")
|
||||
private Integer onlineStatus;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Integer feStatus; //前端大屏显示 1任务中/2空闲
|
||||
private Integer feStatus; // 前端大屏显示 1任务中/2空闲
|
||||
|
||||
/**
|
||||
* wifi信号强度(信号极好4格[-55— 0],信号好3格[-70— -55],信号一般2格[-85— -70],信号差1格[-100— -85])
|
||||
@@ -194,7 +193,6 @@ public class Device extends BaseDO {
|
||||
@ApiModelProperty("设备摘要")
|
||||
private String summary;
|
||||
|
||||
|
||||
/**
|
||||
* 是否是模拟设备
|
||||
*/
|
||||
@@ -206,12 +204,12 @@ public class Device extends BaseDO {
|
||||
@ApiModelProperty("子设备地址")
|
||||
private Integer slaveId;
|
||||
|
||||
|
||||
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||
private Long siteId;
|
||||
|
||||
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||
private Long orgId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@@ -220,7 +218,6 @@ public class Device extends BaseDO {
|
||||
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||
private Long tenantId;
|
||||
|
||||
|
||||
@TableField(exist = false)
|
||||
private DeviceRunningStatusHistory lastRunningStatus;
|
||||
|
||||
@@ -228,12 +225,25 @@ public class Device extends BaseDO {
|
||||
private MowerRealTimeData lastMowerRealTimeData;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Map<Integer,Integer> statusStatistics;
|
||||
private Map<Integer, Integer> statusStatistics;
|
||||
|
||||
@TableField(exist = false)
|
||||
private DeviceRunParam runParam;
|
||||
|
||||
private Boolean hasRegistered;
|
||||
|
||||
private boolean hasRegistered = false;
|
||||
private Boolean hasHost;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String productModel;// 产品型号
|
||||
|
||||
@TableField(exist = false)
|
||||
private String deviceType;
|
||||
|
||||
@TableField(exist = false)
|
||||
private LocationMessage locationMessage;
|
||||
|
||||
@TableField(exist = false)
|
||||
private VehicleMessage vehicleMessage;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
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.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.core.enums.ConnectType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
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.BaseDO;
|
||||
import com.maibu.core.domain.OrgBaseDO;
|
||||
import com.maibu.core.domain.map.RestPoint;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.enums.RouteType;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("iot_device_task")
|
||||
@@ -24,6 +26,12 @@ public class DevicePlanTask extends OrgBaseDO {
|
||||
|
||||
private String deviceId;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String deviceAlias; // 别名
|
||||
|
||||
@TableField(exist = false)
|
||||
private String workName; // 路径规划名称
|
||||
|
||||
private DeviceTaskStaus taskStaus; // 任务状态
|
||||
|
||||
@TableField(exist = false)
|
||||
@@ -39,4 +47,12 @@ public class DevicePlanTask extends OrgBaseDO {
|
||||
|
||||
private LocalDateTime canExecuteTime; // 这个时间之前都不能执行
|
||||
|
||||
@TableField(exist = false)
|
||||
private volatile boolean taskAccepted = false; // 任务被上位机接收
|
||||
|
||||
private RouteType routeType;
|
||||
|
||||
@TableField(exist = false)
|
||||
private RestPoint backTaskPoint;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +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.maibu.constant.CommandConstant;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.maibu.annotation.Excel;
|
||||
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;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "iot_device_run_param", autoResultMap = true)
|
||||
@@ -22,438 +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;// 设备序列号
|
||||
|
||||
@Excel(name = "产品型号", cellType = Excel.ColumnType.STRING, prompt = "产品型号")
|
||||
private String productModel;// 产品型号
|
||||
|
||||
@Excel(name = "设备类型", cellType = Excel.ColumnType.STRING, prompt = "设备类型")
|
||||
private String deviceType;// 设备类型:mower-割草机器人
|
||||
|
||||
@Excel(name = "RTK模式", cellType = Excel.ColumnType.STRING, prompt = "RTK模式")
|
||||
private String rtkMode;// RTK模式:network-4G网络差分
|
||||
|
||||
@Excel(name = "摄像头数量", cellType = Excel.ColumnType.STRING, prompt = "摄像头数量")
|
||||
private Integer cameraNum;// 摄像头数量
|
||||
|
||||
@Excel(name = "动力类型", cellType = Excel.ColumnType.STRING, prompt = "动力类型")
|
||||
private String powerType;// 动力类型:hybrid-混动
|
||||
|
||||
@Excel(name = "车轮类型", cellType = Excel.ColumnType.STRING, prompt = "车轮类型")
|
||||
private String wheelType;// 车轮类型:track-履带式
|
||||
|
||||
@Excel(name = "发动机类型", cellType = Excel.ColumnType.STRING, prompt = "发动机类型")
|
||||
private String engineType;// 发动机类型:honda-本田发动机
|
||||
|
||||
@Excel(name = "是否搭载上位机", cellType = Excel.ColumnType.NUMERIC)
|
||||
private Integer hasHost = 1;// 是否搭载上位机
|
||||
|
||||
@Excel(name = "设备能力列表")
|
||||
@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 static byte[] toWriteBytes(DeviceRunParam p) {
|
||||
//
|
||||
// ByteBuffer buffer = ByteBuffer.allocate(178);
|
||||
// buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
//
|
||||
// // 包头
|
||||
// buffer.put((byte) 0xAB);
|
||||
// buffer.put((byte) 0xAA);
|
||||
//
|
||||
// // 指令
|
||||
// buffer.put(CommandConstant.writeConfig);
|
||||
//
|
||||
// // UID固化标志
|
||||
// buffer.put(p.getChipUidSign());
|
||||
//
|
||||
// // UID
|
||||
// putFixedString(buffer, p.getChipUid(), 45);
|
||||
//
|
||||
// // Byte68
|
||||
// byte remote = 0;
|
||||
// remote |= (p.getKnifeMotorMode() & 0x03);
|
||||
// remote |= (p.getWalkMotorMode() & 0x03) << 2;
|
||||
// remote |= (p.getLeftMotorReverse() & 0x01) << 4;
|
||||
// remote |= (p.getRightMotorReverse() & 0x01) << 5;
|
||||
// remote |= (p.getSwapChannel() & 0x01) << 6;
|
||||
// remote |= (p.getUse4G() & 0x01) << 7;
|
||||
// buffer.put(remote);
|
||||
//
|
||||
// // 69~72
|
||||
// buffer.putShort((short) p.getForwardSpeedLimit());
|
||||
// buffer.putShort((short) p.getTurnSpeedLimit());
|
||||
//
|
||||
// //73
|
||||
// byte b73 = 0;
|
||||
// b73 |= (p.getKnifePolarity() & 1);
|
||||
// b73 |= (p.getFanPolarity() & 1) << 1;
|
||||
// b73 |= (p.getThrottlePolarity() & 1) << 2;
|
||||
// b73 |= (p.getLiftProtectTime() & 0x0F) << 3;
|
||||
// b73 |= (p.getDualRtk() & 1) << 7;
|
||||
// buffer.put(b73);
|
||||
//
|
||||
// //74
|
||||
// byte b74 = 0;
|
||||
// b74 |= (p.getKnifeChannel() & 0x0F);
|
||||
// b74 |= (p.getFanChannel() & 0x0F) << 4;
|
||||
// buffer.put(b74);
|
||||
//
|
||||
// //75
|
||||
// byte b75 = 0;
|
||||
// b75 |= (p.getThrottleChannel() & 0x0F);
|
||||
// b75 |= (p.getRemoteType() & 0x07) << 4;
|
||||
// if (p.isRelayBoard()) {
|
||||
// b75 |= 1 << 7;
|
||||
// }
|
||||
// buffer.put(b75);
|
||||
//
|
||||
// //76
|
||||
// byte b76 = 0;
|
||||
// b76 |= (p.getLiftChannel() & 0x0F);
|
||||
// b76 |= (p.getChassisChannel() & 0x0F) << 4;
|
||||
// buffer.put(b76);
|
||||
//
|
||||
// //77
|
||||
// byte b77 = 0;
|
||||
// b77 |= (p.getArmChannel() & 0x0F);
|
||||
// b77 |= (p.getFuelPumpChannel() & 0x0F) << 4;
|
||||
// buffer.put(b77);
|
||||
//
|
||||
// //wifi
|
||||
// putFixedString(buffer, p.getWifiName(), 20);
|
||||
// putFixedString(buffer, p.getWifiPassword(), 20);
|
||||
//
|
||||
// //118
|
||||
// byte b118 = 0;
|
||||
// b118 |= (p.getBatteryType() & 0x03);
|
||||
// b118 |= (p.getDriveType() & 0x03) << 2;
|
||||
// buffer.put(b118);
|
||||
//
|
||||
// //119~158 float
|
||||
// buffer.putFloat(p.getGearRatio());
|
||||
// buffer.putFloat(p.getRobotLength());
|
||||
// buffer.putFloat(p.getRobotWidth());
|
||||
// buffer.putFloat(p.getRobotHeight());
|
||||
// buffer.putFloat(p.getKnifeWidth());
|
||||
// buffer.putFloat(p.getTyreSize());
|
||||
// buffer.putFloat(p.getLeftForwardGain());
|
||||
// buffer.putFloat(p.getLeftBackwardGain());
|
||||
// buffer.putFloat(p.getRightForwardGain());
|
||||
// buffer.putFloat(p.getRightBackwardGain());
|
||||
//
|
||||
// //159~173
|
||||
// putFixedString(buffer, p.getFirmwareVersion(), 15);
|
||||
//
|
||||
// //CRC
|
||||
//
|
||||
// / / byte[] bytes = buffer.array();
|
||||
// / / int crc = CRC16Util.crc16(bytes, 0, 174);
|
||||
// buffer.putShort((short) 0);
|
||||
//
|
||||
// //Tail
|
||||
// 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();
|
||||
private String capabilities;
|
||||
|
||||
p.setOriginalData(data);
|
||||
private String factoryCode; // 工厂码
|
||||
|
||||
p.setHeader1(buffer.get());
|
||||
p.setHeader2(buffer.get());
|
||||
private String lineNum;// 产线号
|
||||
|
||||
p.setCmd(buffer.get());
|
||||
private LocalDate productionDate;// 生产日期
|
||||
|
||||
p.setChipUidSign(buffer.get());
|
||||
private String serialNumber;// 流水号
|
||||
|
||||
p.setChipUid(readString(buffer, 45));
|
||||
@Excel(name = "电池类型", cellType = Excel.ColumnType.STRING, prompt = "电池类型")
|
||||
private String batteryType;// 电池类型
|
||||
|
||||
// 跳过字节49-67(共19字节,预留不用)
|
||||
buffer.position(buffer.position() + 19);
|
||||
@Excel(name = "行走驱动类型", cellType = Excel.ColumnType.STRING, prompt = "行走驱动类型")
|
||||
private String walkingDriveType;// 行走驱动类型
|
||||
|
||||
byte remote = buffer.get();
|
||||
@Excel(name = "割刀驱动类型", cellType = Excel.ColumnType.STRING, prompt = "割刀驱动类型")
|
||||
private String cutterDriveType;// 割刀驱动类型
|
||||
|
||||
// p.setRemoteConfig(remote);
|
||||
@Excel(name = "RTK天线数", cellType = Excel.ColumnType.STRING, prompt = "RTK天线数")
|
||||
private String rtkAntennasNum;// RTK天线数
|
||||
|
||||
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);
|
||||
@Excel(name = "手柄类型", cellType = Excel.ColumnType.STRING, prompt = "手柄类型")
|
||||
private String handleType;// 手柄类型
|
||||
|
||||
p.setForwardSpeedLimit(buffer.getShort());
|
||||
p.setTurnSpeedLimit(buffer.getShort());
|
||||
@Excel(name = "PCB硬件版本", cellType = Excel.ColumnType.STRING, prompt = "PCB硬件版本")
|
||||
private String pcbVersion;// PCB硬件版本
|
||||
|
||||
byte b73 = buffer.get();
|
||||
@Excel(name = "长宽高", cellType = Excel.ColumnType.STRING, prompt = "长宽高")
|
||||
private String dimensions;// 长宽高
|
||||
|
||||
p.setKnifePolarity(b73 & 1);
|
||||
p.setFanPolarity((b73 >> 1) & 1);
|
||||
p.setThrottlePolarity((b73 >> 2) & 1);
|
||||
p.setLiftProtectTime((b73 >> 3) & 0x0F);
|
||||
p.setDualRtk((b73 >> 7) & 1);
|
||||
@Excel(name = "割刀宽度", cellType = Excel.ColumnType.STRING, prompt = "割刀宽度")
|
||||
private String bladeWidth;// 割刀宽度
|
||||
|
||||
byte b74 = buffer.get();
|
||||
@Excel(name = "轮胎尺寸", cellType = Excel.ColumnType.STRING, prompt = "轮胎尺寸")
|
||||
private String tyreSize;// 轮胎尺寸
|
||||
|
||||
p.setKnifeChannel(b74 & 0x0F);
|
||||
p.setFanChannel((b74 >> 4) & 0x0F);
|
||||
@Excel(name = "转速比", cellType = Excel.ColumnType.STRING, prompt = "转速比")
|
||||
private String speedRatio;// 转速比
|
||||
|
||||
byte b75 = buffer.get();
|
||||
@Excel(name = "蜂窝网络通信信息", cellType = Excel.ColumnType.STRING, prompt = "蜂窝网络通信信息")
|
||||
private String cellularInfo;// 蜂窝网络通信信息
|
||||
|
||||
p.setThrottleChannel(b75 & 0x0F);
|
||||
p.setRemoteType((b75 >> 4) & 0x07);
|
||||
p.setRelayBoard(((b75 >> 7) & 1) == 1);
|
||||
@Excel(name = "wifi名称", cellType = Excel.ColumnType.STRING, prompt = "wifi名称")
|
||||
private String wifiName;// wifi名称
|
||||
|
||||
byte b76 = buffer.get();
|
||||
@Excel(name = "蓝牙广播名", cellType = Excel.ColumnType.STRING, prompt = "蓝牙广播名")
|
||||
private String bluetoothName;// 蓝牙广播名
|
||||
|
||||
p.setLiftChannel(b76 & 0x0F);
|
||||
p.setChassisChannel((b76 >> 4) & 0x0F);
|
||||
@Excel(name = "硬件标识信息", cellType = Excel.ColumnType.STRING, prompt = "硬件标识信息")
|
||||
private String hardwareIdentifiers;// 硬件标识信息
|
||||
|
||||
byte b77 = buffer.get();
|
||||
@Excel(name = "IMU型号", cellType = Excel.ColumnType.STRING, prompt = "IMU型号")
|
||||
private String imuModel;// IMU型号
|
||||
|
||||
p.setArmChannel(b77 & 0x0F);
|
||||
p.setFuelPumpChannel((b77 >> 4) & 0x0F);
|
||||
@Excel(name = "温湿度传感器", cellType = Excel.ColumnType.STRING, prompt = "温湿度传感器")
|
||||
private String tempHumiditySensor;// 温湿度传感器
|
||||
|
||||
p.setWifiName(readString(buffer, 20));
|
||||
p.setWifiPassword(readString(buffer, 20));
|
||||
@Excel(name = "气压计在位", cellType = Excel.ColumnType.STRING, prompt = "气压计在位")
|
||||
private String barometerPresent;// 气压计在位
|
||||
|
||||
byte b118 = buffer.get();
|
||||
@Excel(name = "超声波在位", cellType = Excel.ColumnType.STRING, prompt = "超声波在位")
|
||||
private String ultrasonicPresent;// 超声波在位
|
||||
|
||||
p.setBatteryType(b118 & 0x03);
|
||||
p.setDriveType((b118 >> 2) & 0x03);
|
||||
@Excel(name = "DAC在位", cellType = Excel.ColumnType.STRING, prompt = "DAC在位")
|
||||
private String dacPresent;// DAC在位
|
||||
|
||||
// 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());
|
||||
@Excel(name = "质检员", cellType = Excel.ColumnType.STRING, prompt = "质检员")
|
||||
private String operator;// 质检员
|
||||
|
||||
p.setFirmwareVersion(readString(buffer, 15));
|
||||
@Excel(name = "检测报告号", cellType = Excel.ColumnType.STRING, prompt = "检测报告号")
|
||||
private String inspectionNo;// 检测报告号
|
||||
|
||||
p.setCrc16(Short.toUnsignedInt(buffer.getShort()));
|
||||
@Excel(name = "固件版本", cellType = Excel.ColumnType.STRING, prompt = "固件版本")
|
||||
private String firmwareVersion;// 固件版本
|
||||
|
||||
p.setTail1(buffer.get());
|
||||
p.setTail2(buffer.get());
|
||||
@Excel(name = "经销商", cellType = Excel.ColumnType.STRING, prompt = "经销商")
|
||||
private String dealer;// DAC在位
|
||||
|
||||
return p;
|
||||
}
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<String> capabilityList;// 设备能力列表:heartbeat-上报心跳/location-上报位置/vehicle_status-上报整机状态/task_control-任务控制/single_point-单点作业/coverage-全覆盖割草作业/path_upload-作业路径上传
|
||||
|
||||
public static String readString(ByteBuffer buffer, int len) {
|
||||
byte[] bytes = new byte[len];
|
||||
buffer.get(bytes);
|
||||
// @TableField(exist = false)
|
||||
// public byte header1;
|
||||
// @TableField(exist = false)
|
||||
// public byte header2;
|
||||
// @TableField(exist = false)
|
||||
// public byte cmd;
|
||||
|
||||
int end = 0;
|
||||
while (end < bytes.length && bytes[end] != 0) {
|
||||
end++;
|
||||
}
|
||||
// public byte chipUidSign;// 芯片UID固化标志位
|
||||
// public String chipUid;// 芯片UID
|
||||
|
||||
return new String(bytes, 0, end, StandardCharsets.UTF_8);
|
||||
}
|
||||
// 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);
|
||||
|
||||
// p.setHeader1(buffer.get());
|
||||
// p.setHeader2(buffer.get());
|
||||
|
||||
// p.setCmd(buffer.get());
|
||||
|
||||
// p.setChipUidSign(buffer.get());
|
||||
|
||||
// p.setChipUid(readString(buffer, 45));
|
||||
|
||||
// // 跳过字节49-67(共19字节,预留不用)
|
||||
// buffer.position(buffer.position() + 19);
|
||||
|
||||
// byte remote = buffer.get();
|
||||
|
||||
// // p.setRemoteConfig(remote);
|
||||
|
||||
// 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.setForwardSpeedLimit(buffer.getShort());
|
||||
// p.setTurnSpeedLimit(buffer.getShort());
|
||||
|
||||
// byte b73 = 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);
|
||||
|
||||
// byte b74 = buffer.get();
|
||||
|
||||
// p.setKnifeChannel(b74 & 0x0F);
|
||||
// p.setFanChannel((b74 >> 4) & 0x0F);
|
||||
|
||||
// byte b75 = buffer.get();
|
||||
|
||||
// p.setThrottleChannel(b75 & 0x0F);
|
||||
// p.setRemoteType((b75 >> 4) & 0x07);
|
||||
// p.setRelayBoard(((b75 >> 7) & 1) == 1);
|
||||
|
||||
// byte b76 = buffer.get();
|
||||
|
||||
// p.setLiftChannel(b76 & 0x0F);
|
||||
// p.setChassisChannel((b76 >> 4) & 0x0F);
|
||||
|
||||
// byte b77 = buffer.get();
|
||||
|
||||
// p.setArmChannel(b77 & 0x0F);
|
||||
// p.setFuelPumpChannel((b77 >> 4) & 0x0F);
|
||||
|
||||
// p.setWifiName(readString(buffer, 20));
|
||||
// p.setWifiPassword(readString(buffer, 20));
|
||||
|
||||
// byte b118 = buffer.get();
|
||||
|
||||
// p.setBatteryType(b118 & 0x03);
|
||||
// p.setDriveType((b118 >> 2) & 0x03);
|
||||
|
||||
// // 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.setFirmwareVersion(readString(buffer, 15));
|
||||
|
||||
// p.setCrc16(Short.toUnsignedInt(buffer.getShort()));
|
||||
|
||||
// p.setTail1(buffer.get());
|
||||
// p.setTail2(buffer.get());
|
||||
|
||||
// return p;
|
||||
// }
|
||||
|
||||
// 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);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
// 割刀速度标志位
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.maibu.core.business;
|
||||
|
||||
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.maibu.core.domain.OrgNoUserDO;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.utils.LongListTypeHandler;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName("iot_region_consecutive_task_record")
|
||||
public class RegionConsecutiveTaskRecord extends OrgNoUserDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private Long regionId;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String deviceAlias; // 别名
|
||||
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> routeIds; // 线路id
|
||||
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> taskIds; // 线路id
|
||||
|
||||
private DeviceTaskStaus taskStatus; // 任务状态
|
||||
|
||||
private int currentIndex; // 当前执行到哪一个
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.maibu.core.domain.OrgBaseDO;
|
||||
import com.maibu.core.enums.RouteType;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -20,10 +21,16 @@ public class WorkRecord extends OrgBaseDO {
|
||||
private String workName;
|
||||
private Long userId;
|
||||
|
||||
// private String jsonData;
|
||||
private String mode;// 导航任务模式 single_point|coverage |predefined_path
|
||||
|
||||
// private String jsonData;
|
||||
|
||||
private RouteType routeType;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private PlanPath jsonData; //计划
|
||||
private PlanPath jsonData; // 计划
|
||||
|
||||
private String imgUrl;
|
||||
|
||||
private String fileUrl; // 存放的 路径规划的id
|
||||
}
|
||||
|
||||
@@ -1,35 +1,41 @@
|
||||
package com.maibu.core.business.device;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.core.business.DeviceRunParam;
|
||||
import com.maibu.core.business.DeviceRunStatistics;
|
||||
import com.maibu.core.business.PlanPath;
|
||||
import com.maibu.core.business.WorkRecord;
|
||||
import com.maibu.constant.Constant;
|
||||
import com.maibu.core.business.*;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.business.path.RoutePlanSendEntity;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.enums.RouteType;
|
||||
import com.maibu.core.host.HostModeChangeDTO;
|
||||
import com.maibu.core.host.HostWorkRecordCreateDTO;
|
||||
import com.maibu.core.host.MutiPointEntity;
|
||||
import com.maibu.core.host.PointEntity;
|
||||
import com.maibu.core.ota.DeviceOtaFirmware;
|
||||
import com.maibu.mapper.DevicePlanTaskMapper;
|
||||
import com.maibu.mapper.RegionConsecutiveTaskRecordMapper;
|
||||
import com.maibu.mapper.WorkRecordMapper;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.memory.SiteMemory;
|
||||
import com.maibu.mqtt.MqttTopic;
|
||||
import com.maibu.utils.StringUtils;
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
import com.maibu.utils.spring.SpringUtils;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Slf4j
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@@ -58,15 +64,24 @@ public class NettyDevice extends Connector {
|
||||
// todo 注册的时候更新 siteId
|
||||
private Device device;
|
||||
|
||||
//todo 假如设置一个当前控制的token
|
||||
private String currentControlToken;
|
||||
// todo 当前登录的账号的token 以token为控制的权限
|
||||
private String token;
|
||||
|
||||
@JsonIgnore
|
||||
private DevicePlanTaskMapper devicePlanTaskMapper = SpringUtils.getBean(DevicePlanTaskMapper.class);
|
||||
|
||||
@JsonIgnore
|
||||
private RegionConsecutiveTaskRecordMapper regionConsecutiveTaskRecordMapper = SpringUtils
|
||||
.getBean(RegionConsecutiveTaskRecordMapper.class);
|
||||
|
||||
@JsonIgnore
|
||||
private WorkRecordMapper workRecordMapper = SpringUtils.getBean(WorkRecordMapper.class);
|
||||
|
||||
@JsonIgnore
|
||||
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
|
||||
|
||||
private static final String mqttClientId = "maibu-mqtt-client";
|
||||
|
||||
public NettyDevice(String connectorId) {
|
||||
super(connectorId);
|
||||
this.deviceType = ConnectorType.MASTER; // 默认上位机角色
|
||||
@@ -77,6 +92,10 @@ public class NettyDevice extends Connector {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
public void status(Integer onlineStatus) {
|
||||
this.onlineStatus = onlineStatus;
|
||||
}
|
||||
|
||||
// todo 如何确定命令已收到?
|
||||
public void sendNextPoint() {
|
||||
if (task.getTaskStaus().equals(DeviceTaskStaus.PAUSE))
|
||||
@@ -109,13 +128,30 @@ public class NettyDevice extends Connector {
|
||||
}
|
||||
|
||||
public synchronized Long finishTask() {
|
||||
sendPathCommand((byte) 0x01, (short) 0, 0.00d, 0.00d, (short) 0);
|
||||
// sendPathCommand((byte) 0x01, (short) 0, 0.00d, 0.00d, (short) 0);
|
||||
long finishId = task.getId();
|
||||
task.setTaskStaus(DeviceTaskStaus.FINISH);
|
||||
task.setFinishTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId());
|
||||
|
||||
// 更新当前任务的执行索引
|
||||
RegionConsecutiveTaskRecord record = siteMemory.getRegionConsecutiveTask(device.getSerialNumber());
|
||||
if (record != null && DeviceTaskStaus.EXECUTING.equals(record.getTaskStatus())) {
|
||||
int maxIndex = record.getRouteIds().size() - 1;
|
||||
int currentIndex = record.getCurrentIndex();
|
||||
record.setUpdateTime(LocalDateTime.now());
|
||||
if (currentIndex >= maxIndex) {
|
||||
record.setTaskStatus(DeviceTaskStaus.FINISH);
|
||||
siteMemory.removeRegionConsecutiveTask(device.getSerialNumber());
|
||||
} else {
|
||||
record.setCurrentIndex(currentIndex + 1);
|
||||
}
|
||||
regionConsecutiveTaskRecordMapper.saveOrUpdate(record);
|
||||
}
|
||||
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
GlobalMemory.taskPathMap.remove(task.getId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
currentPoint = null;
|
||||
@@ -124,22 +160,69 @@ public class NettyDevice extends Connector {
|
||||
return finishId;
|
||||
}
|
||||
|
||||
public synchronized boolean cancelTask() {
|
||||
public synchronized boolean cancelingTask() throws MqttException {
|
||||
if (task != null) {
|
||||
sendPathCommand((byte) 0x01, (short) 0, 0.00d, 0.00d, (short) 0);
|
||||
WorkRecord workRecord = workRecordMapper.selectById(task.getRouteId());
|
||||
if (workRecord != null) {
|
||||
HostWorkRecordCreateDTO dto = new HostWorkRecordCreateDTO();
|
||||
dto.setAction("cancel");
|
||||
dto.setCommand_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setTask_id(String.valueOf(task.getId()));
|
||||
dto.setSn(task.getDeviceId());
|
||||
dto.setMode(workRecord.getMode());
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
JsonUtils.toJsonString(dto));
|
||||
task.setTaskStaus(DeviceTaskStaus.CANCELING);
|
||||
task.setUpdateTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized Long canceledTask() {
|
||||
if (task != null) {
|
||||
Long taskId = task.getId();
|
||||
task.setTaskStaus(DeviceTaskStaus.CANCELED);
|
||||
task.setUpdateTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId());
|
||||
siteMemory.removeDevicePlanPrepare(task);
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
GlobalMemory.taskPathMap.remove(task.getId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
currentPoint = null;
|
||||
locationQueue.clear();
|
||||
executingTask = false;
|
||||
return taskId;
|
||||
}
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized Long failedTask() {
|
||||
if (task != null) {
|
||||
Long taskId = task.getId();
|
||||
task.setTaskStaus(DeviceTaskStaus.FAILED);
|
||||
task.setUpdateTime(LocalDateTime.now());
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
SiteMemory siteMemory = GlobalMemory.getSiteMemory(task.getOrgId(), task.getSiteId());
|
||||
siteMemory.removeDevicePlanPrepare(task);
|
||||
siteMemory.removeDevicePlanExecute(task.getDeviceId());
|
||||
GlobalMemory.taskPathMap.remove(task.getId());
|
||||
task = null;
|
||||
currentTaskId = null;
|
||||
currentPoint = null;
|
||||
locationQueue.clear();
|
||||
executingTask = false;
|
||||
return taskId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void sendPathCommand(byte commandType, short pointCounts, double lat, double lng, short speed) {
|
||||
@@ -156,8 +239,9 @@ public class NettyDevice extends Connector {
|
||||
}
|
||||
}
|
||||
|
||||
//配置左右轮增益系数
|
||||
public void sendWheelGainCoefficientsCommand(double leftForwardGain, double leftBackwardGain, double rightForwardGain, double rightBackwardGain) {
|
||||
// 配置左右轮增益系数
|
||||
public void sendWheelGainCoefficientsCommand(double leftForwardGain, double leftBackwardGain,
|
||||
double rightForwardGain, double rightBackwardGain) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(39);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
@@ -189,32 +273,46 @@ 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() {
|
||||
public synchronized boolean pauseTask() throws MqttException {
|
||||
if (executingTask) {
|
||||
task.setTaskStaus(DeviceTaskStaus.PAUSE);
|
||||
sendPathCommand((byte) 0x01, (short) 2, 0.00d, 0.00d, (short) 0);
|
||||
// executingTask = false;
|
||||
HostWorkRecordCreateDTO dto = new HostWorkRecordCreateDTO();
|
||||
dto.setAction("pause");
|
||||
dto.setCommand_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setTask_id(String.valueOf(task.getId()));
|
||||
dto.setSn(task.getDeviceId());
|
||||
// TODO 存内存
|
||||
WorkRecord workRecord = workRecordMapper.selectById(task.getRouteId());
|
||||
log.debug("发送开始任务 workRecord {}", workRecord);
|
||||
if (workRecord != null) {
|
||||
dto.setMode(workRecord.getMode());
|
||||
}
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
JsonUtils.toJsonString(dto));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -223,15 +321,26 @@ public class NettyDevice extends Connector {
|
||||
}
|
||||
|
||||
// todo 优化
|
||||
public synchronized boolean recoveryTask() throws InterruptedException {
|
||||
public synchronized boolean recoveryTask() throws InterruptedException, MqttException {
|
||||
if (task.getTaskStaus().equals(DeviceTaskStaus.PAUSE)) {
|
||||
task.setTaskStaus(DeviceTaskStaus.EXECUTING);
|
||||
executingTask = true;
|
||||
sendPathCommand((byte) 0x01, (short) 3, 0.00d, 0.00d, (short) 0);
|
||||
// Thread.sleep(1000);
|
||||
// sendPathCommand((byte) 0x01, (short) 1, currentPoint.getLat(),
|
||||
// currentPoint.getLng(), (short) 0);
|
||||
// sendNextPoint();
|
||||
task.setTaskStaus(DeviceTaskStaus.PAUSE);
|
||||
HostWorkRecordCreateDTO dto = new HostWorkRecordCreateDTO();
|
||||
dto.setAction("resume");
|
||||
dto.setCommand_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setTask_id(String.valueOf(task.getId()));
|
||||
dto.setSn(task.getDeviceId());
|
||||
// TODO 存内存
|
||||
WorkRecord workRecord = workRecordMapper.selectById(task.getRouteId());
|
||||
log.debug("发送开始任务 workRecord {}", workRecord);
|
||||
if (workRecord != null) {
|
||||
dto.setMode(workRecord.getMode());
|
||||
}
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
JsonUtils.toJsonString(dto));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -242,24 +351,208 @@ public class NettyDevice extends Connector {
|
||||
try {
|
||||
if (executingTask)
|
||||
return;
|
||||
if (task != null) {
|
||||
Long routeId = task.getRouteId();
|
||||
WorkRecord workRecord = workRecordMapper.selectById(routeId);
|
||||
if (workRecord != null) {
|
||||
PlanPath planPath = workRecord.getJsonData();
|
||||
if (planPath != null && !CollectionUtils.isEmpty(planPath.getPath())) {
|
||||
planPath.getPath().forEach(x -> {
|
||||
locationQueue.offer(x);
|
||||
});
|
||||
}
|
||||
}
|
||||
task.setStartTime(LocalDateTime.now());
|
||||
}
|
||||
executingTask = true;
|
||||
sendNextPoint();
|
||||
if (task != null) {
|
||||
// startTime 在启动前记录
|
||||
task.setStartTime(LocalDateTime.now());
|
||||
|
||||
AtomicInteger count = new AtomicInteger(0);
|
||||
ScheduledFuture<?>[] futureHolder = new ScheduledFuture<?>[1];
|
||||
futureHolder[0] = executor.scheduleWithFixedDelay(() -> {
|
||||
int current = count.incrementAndGet();
|
||||
try {
|
||||
if (task.isTaskAccepted()) {
|
||||
// 成功,停止后续执行
|
||||
futureHolder[0].cancel(false);
|
||||
log.info("任务执行成功,停止重试,执行次数={}", current);
|
||||
return;
|
||||
}
|
||||
sendNavigationCommand();
|
||||
// 达到最大次数
|
||||
if (current >= 10) {
|
||||
futureHolder[0].cancel(false);
|
||||
log.warn("任务执行达到最大次数,停止执行");
|
||||
executingTask = false;
|
||||
task.setTaskStaus(DeviceTaskStaus.FAILED);
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
task = null;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("任务执行异常,次数={}", current, e);
|
||||
|
||||
// 异常是否算一次,可以根据你的业务决定
|
||||
if (current >= 10) {
|
||||
futureHolder[0].cancel(false);
|
||||
}
|
||||
executingTask = false;
|
||||
task.setTaskStaus(DeviceTaskStaus.FAILED);
|
||||
devicePlanTaskMapper.saveOrUpdate(task);
|
||||
task = null;
|
||||
}
|
||||
|
||||
}, 0, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
log.error("发送开始任务:error {} ", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendNavigationCommand() throws MqttException {
|
||||
|
||||
log.debug("发送开始任务 taskStatus:{},routeId:{}", task.getTaskStaus(), task.getRouteId());
|
||||
if (!task.getTaskStaus().equals(DeviceTaskStaus.EXECUTING))
|
||||
return;
|
||||
|
||||
WorkRecord workRecord = workRecordMapper.selectById(task.getRouteId());
|
||||
log.debug("发送开始任务 workRecord {}", workRecord);
|
||||
if (workRecord != null) {
|
||||
HostWorkRecordCreateDTO dto = new HostWorkRecordCreateDTO();
|
||||
dto.setAction("start");
|
||||
dto.setCommand_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setTask_id(String.valueOf(task.getId()));
|
||||
dto.setSn(task.getDeviceId());
|
||||
dto.setMode(workRecord.getMode());
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
PointEntity point = new PointEntity();
|
||||
// TODO 增加其他系统任务类型 写死的code
|
||||
if (RouteType.BACK_TO_REST_POINT.equals(task.getRouteType())) {
|
||||
point.setLongitude(task.getBackTaskPoint().getPosition().getLng());
|
||||
point.setLatitude(task.getBackTaskPoint().getPosition().getLat());
|
||||
} else {
|
||||
if (!StringUtils.isEmpty(workRecord.getMode())) {
|
||||
if (workRecord.getMode().equals("single_point")) {
|
||||
point.setLongitude(workRecord.getJsonData().getPath().get(0).getLng());
|
||||
point.setLatitude(workRecord.getJsonData().getPath().get(0).getLat());
|
||||
}
|
||||
if (workRecord.getMode().equals("coverage")) {
|
||||
List<MutiPointEntity> boundary_points = new ArrayList<>();
|
||||
List<LatAndLngEntity> path = workRecord.getJsonData().getPath();
|
||||
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
LatAndLngEntity x = path.get(i);
|
||||
|
||||
MutiPointEntity mutiPoint = new MutiPointEntity();
|
||||
mutiPoint.setLongitude(x.getLng());
|
||||
mutiPoint.setLatitude(x.getLat());
|
||||
mutiPoint.setIndex(i);
|
||||
boundary_points.add(mutiPoint);
|
||||
}
|
||||
point.setBoundary_points(boundary_points);
|
||||
}
|
||||
if (workRecord.getMode().equals("predefined_path")) {
|
||||
point.setPath_id(workRecord.getId());
|
||||
point.setUrl(workRecord.getFileUrl());
|
||||
point.setVersion("v2");
|
||||
}
|
||||
}
|
||||
}
|
||||
point.setExecute(true);
|
||||
dto.setData(point);
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
JsonUtils.toJsonString(dto));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void sendPredefined(WorkRecord workRecord) throws MqttException {
|
||||
|
||||
log.debug("发送开始任务 taskStatus:{},routeId:{}", task.getTaskStaus(), task.getRouteId());
|
||||
if (task != null)
|
||||
return;
|
||||
|
||||
if (workRecord != null) {
|
||||
HostWorkRecordCreateDTO dto = new HostWorkRecordCreateDTO();
|
||||
dto.setAction("start");
|
||||
dto.setCommand_id(task.getId() + "_" + System.currentTimeMillis());
|
||||
dto.setTask_id(String.valueOf(task.getId()));
|
||||
dto.setSn(task.getDeviceId());
|
||||
|
||||
dto.setMode(workRecord.getMode());
|
||||
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
dto.setMessage_id("predefined" + "_" + System.currentTimeMillis());
|
||||
dto.setProtocol_version(Constant.protocol_version);
|
||||
|
||||
PointEntity point = new PointEntity();
|
||||
|
||||
List<MutiPointEntity> boundary_points = new ArrayList<>();
|
||||
List<LatAndLngEntity> path = workRecord.getJsonData().getPath();
|
||||
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
LatAndLngEntity x = path.get(i);
|
||||
|
||||
MutiPointEntity mutiPoint = new MutiPointEntity();
|
||||
mutiPoint.setLongitude(x.getLng());
|
||||
mutiPoint.setLatitude(x.getLat());
|
||||
mutiPoint.setIndex(i);
|
||||
boundary_points.add(mutiPoint);
|
||||
}
|
||||
point.setBoundary_points(boundary_points);
|
||||
point.setPath_id(workRecord.getId());
|
||||
point.setVersion("v2");
|
||||
point.setExecute(false);
|
||||
|
||||
dto.setData(point);
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.MOWER_TASK_ROUTE_SET, task.getDeviceId()),
|
||||
JsonUtils.toJsonString(dto));
|
||||
}
|
||||
}
|
||||
|
||||
public void upgrade(String deviceId, DeviceOtaFirmware firmware) throws MqttException {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("action", "ota_upgrade");
|
||||
payload.put("version", firmware.getVersion());
|
||||
payload.put("file_url", firmware.getFileUrl());
|
||||
payload.put("firmware_id", firmware.getId());
|
||||
payload.put("sn", deviceId);
|
||||
payload.put("timestamp", System.currentTimeMillis());
|
||||
payload.put("message_id", firmware.getId() + "_" + System.currentTimeMillis());
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(
|
||||
mqttClientId,
|
||||
String.format(MqttTopic.MOWER_OTA_UPGRADE_SET, deviceId),
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发模式切换指令
|
||||
*
|
||||
* @param deviceId
|
||||
* @param controlMode
|
||||
* @throws MqttException
|
||||
*/
|
||||
public void modeChage(String deviceId, Integer controlMode) throws MqttException {
|
||||
HostModeChangeDTO payload = new HostModeChangeDTO();
|
||||
payload.setSn(deviceId);
|
||||
payload.setTimestamp(System.currentTimeMillis());
|
||||
payload.setMessage_id("modeChange_" + System.currentTimeMillis());
|
||||
payload.setCommand_id("modeChangeCommand_ " + System.currentTimeMillis());
|
||||
payload.setProtocol_version(Constant.protocol_version);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("control_mode", controlMode);
|
||||
payload.setData(data);
|
||||
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(
|
||||
mqttClientId,
|
||||
String.format(MqttTopic.MOWER_MODE_CHANGE_SET, deviceId),
|
||||
JsonUtils.toJsonString(payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConsecutiveTaskDTO {
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private List<Long> routeIds; // 线路id
|
||||
|
||||
private Long orgId;
|
||||
|
||||
private Long siteId;
|
||||
|
||||
private Long regionId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConsecutiveTaskQueryDTO {
|
||||
|
||||
private Long siteId;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private DeviceTaskStaus taskStatus;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
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 p; // 任务进度
|
||||
private String wk; // 任务进度
|
||||
private double b; // 电量
|
||||
private boolean ha = false;// hasAlarm 有无告警
|
||||
|
||||
private Integer cm;// 控制模式 manual_remote|auto
|
||||
|
||||
private String ms; // 运动状态 moving|stopped|blocked
|
||||
|
||||
}
|
||||
@@ -20,4 +20,8 @@ public class DeviceTaskCommandDTO {
|
||||
|
||||
private Long taskId;
|
||||
|
||||
private Long regionId;
|
||||
|
||||
private boolean forceCancel = false; //强制取消 不等回复
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.maibu.dto;
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.enums.MesType;
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import com.maibu.core.enums.MesType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class WebMapMessageDTO {
|
||||
private List<DeviceMapPushDTO> data;
|
||||
private MesType type;
|
||||
}
|
||||
@@ -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,16 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.enums.MesType;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WebRouteStatusMessageDTO {
|
||||
private List<LatAndLngEntity> data;
|
||||
private String deviceId;
|
||||
private Long taskId;
|
||||
private MesType type;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.maibu.dto;
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.maibu.core.business.inter;
|
||||
|
||||
public interface DeviceWebSocketInterace {
|
||||
|
||||
void sendWebsoketMes(String key, String data);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.maibu.core.business.inter;
|
||||
|
||||
public interface DeviceWebSocketInterface {
|
||||
|
||||
void sendWebsocketMes(String key, String data);
|
||||
|
||||
|
||||
void sendMapWebsocketMes(Long siteId,String data);
|
||||
|
||||
}
|
||||
@@ -14,10 +14,19 @@ public class WebsocketMesDispather {
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public void dispather(String key, String data) {
|
||||
Map<String, DeviceWebSocketInterace> beanMap = applicationContext.getBeansOfType(DeviceWebSocketInterace.class);
|
||||
Map<String, DeviceWebSocketInterface> beanMap = applicationContext.getBeansOfType(DeviceWebSocketInterface.class);
|
||||
// 遍历
|
||||
beanMap.values().forEach(x -> {
|
||||
x.sendWebsoketMes(key, data);
|
||||
x.sendWebsocketMes(key, data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void mapMessageDispather(Long siteId, String data) {
|
||||
Map<String, DeviceWebSocketInterface> beanMap = applicationContext.getBeansOfType(DeviceWebSocketInterface.class);
|
||||
// 遍历
|
||||
beanMap.values().forEach(x -> {
|
||||
x.sendMapWebsocketMes(siteId, data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class MowerCommandDispather {
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public Long dispathDeviceTask(DeviceTaskCommandDTO dto) {
|
||||
public Long dispathDeviceTask(DeviceTaskCommandDTO dto) throws Exception {
|
||||
Map<String, MowerCommandInter> beanMap = applicationContext.getBeansOfType(MowerCommandInter.class);
|
||||
// 遍历
|
||||
Long id = null;
|
||||
|
||||
@@ -4,6 +4,6 @@ import com.maibu.core.business.dto.DeviceTaskCommandDTO;
|
||||
|
||||
public interface MowerCommandInter {
|
||||
|
||||
Long createDeviceTask(DeviceTaskCommandDTO dto);
|
||||
Long createDeviceTask(DeviceTaskCommandDTO dto) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.maibu.core.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
@@ -14,6 +15,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 基类,时间类型改为LocalDateTime
|
||||
*
|
||||
* @author fastb
|
||||
* @date 2023-08-22 9:11
|
||||
*/
|
||||
@@ -23,20 +25,24 @@ public class BaseDO implements Serializable {
|
||||
|
||||
/** 创建者 */
|
||||
@ApiModelProperty("创建者")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@ApiModelProperty("创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新者 */
|
||||
@ApiModelProperty("更新者")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@ApiModelProperty("更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/** 逻辑删除 */
|
||||
|
||||
@@ -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,17 +1,22 @@
|
||||
package com.maibu.core.domain.entity;
|
||||
|
||||
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.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.utils.LongListTypeHandler;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "sys_region")
|
||||
@TableName(value = "sys_region", autoResultMap = true)
|
||||
public class SysRegion extends BaseDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
@@ -27,6 +32,14 @@ public class SysRegion extends BaseDO {
|
||||
|
||||
private String remark;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<LatAndLngEntity> scope; // 区域范围
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Long defaultRoute;// 绑定的线路id
|
||||
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> bindRoutes;// 绑定的线路id
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package com.maibu.core.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
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.BaseDO;
|
||||
import com.maibu.core.domain.map.SiteMapInfo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "sys_site")
|
||||
@TableName(value = "sys_site", autoResultMap = true)
|
||||
public class SysSite extends BaseDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
@@ -43,4 +46,12 @@ public class SysSite extends BaseDO {
|
||||
|
||||
private boolean dingTalkOrderPush = false;// 工单是否推送
|
||||
|
||||
private String siteMapName; // geoserver 地图名称
|
||||
|
||||
/**
|
||||
* 场站相关的地图信息 比如停车点,充电点,临时不可走点 等等 待拓展
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private SiteMapInfo siteMapInfo;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.maibu.core.domain.map;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RestPoint {
|
||||
|
||||
private LatAndLngEntity position;
|
||||
|
||||
private String bindDeviceId;
|
||||
|
||||
private String alias;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.maibu.core.domain.map;
|
||||
|
||||
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.core.domain.OrgNoUserDO;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "sys_site_map_info", autoResultMap = true)
|
||||
public class SiteMapInfo extends OrgNoUserDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<RestPoint> restPoints; // 休息点
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<TempObstaclePoint> tempObstaclePoints; // 临时不可走点
|
||||
|
||||
// todo 拓展 安全区 充电区?
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.maibu.core.domain.map;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TempObstaclePoint {
|
||||
|
||||
private LatAndLngEntity center;
|
||||
|
||||
private String alias;
|
||||
|
||||
private double radius; // 半径
|
||||
|
||||
private double size_x; // x方向的长度
|
||||
|
||||
private double size_y; // y方向的长度
|
||||
|
||||
private String source = "platform"; // 数据来源 默认给平台
|
||||
|
||||
}
|
||||
@@ -48,6 +48,12 @@ public class LoginUser implements UserDetails {
|
||||
*/
|
||||
private String token;
|
||||
|
||||
|
||||
/**
|
||||
* 用户唯一标识 用户控制设备
|
||||
*/
|
||||
private String realToken;
|
||||
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
@@ -108,7 +114,7 @@ public class LoginUser implements UserDetails {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public LoginUser(Long userId, Long deptId, Long orgId, Long siteId, Long roleId,String language, SysUser user, Set<String> permissions) {
|
||||
public LoginUser(Long userId, Long deptId, Long orgId, Long siteId, Long roleId, String language, SysUser user, Set<String> permissions) {
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.orgId = orgId;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.maibu.core.domain.rule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.maibu.core.enums.ActionType;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
||||
public class ActionConfig {
|
||||
|
||||
/**
|
||||
* 触发任务类型
|
||||
*/
|
||||
private ActionType actionType;
|
||||
|
||||
/**
|
||||
* 参数值
|
||||
*/
|
||||
private Map<String, Object> args;
|
||||
|
||||
private Long routeId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.maibu.core.domain.rule;
|
||||
|
||||
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.core.domain.OrgNoUserDO;
|
||||
import com.maibu.core.enums.DeviceScope;
|
||||
import com.maibu.core.enums.RuleType;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 自动化规则配置
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "iot_auto_rule", autoResultMap = true)
|
||||
public class IotAutoRule extends OrgNoUserDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则类型,如 LOW_BATTERY_RETURN
|
||||
*/
|
||||
private RuleType ruleType;
|
||||
|
||||
/**
|
||||
* 适用设备、分组、全部
|
||||
*/
|
||||
private DeviceScope deviceScope;
|
||||
|
||||
/**
|
||||
* 触发条件
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private TriggerConditions conditions;
|
||||
|
||||
/**
|
||||
* 执行动作及参数
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private ActionConfig actionConfig;
|
||||
|
||||
/**
|
||||
* 是否启用:0-禁用,1-启用
|
||||
*/
|
||||
private Boolean enabled = false;
|
||||
|
||||
// 是否强制执行 比如车子当前有任务
|
||||
private Boolean ForceExecute = false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.maibu.core.domain.rule;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
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.core.domain.OrgNoUserDO;
|
||||
import com.maibu.core.enums.RuleType;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 自动化规则触发记录
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@TableName(value = "iot_auto_rule_record", autoResultMap = true)
|
||||
public class IotAutoRuleRecord extends OrgNoUserDO {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则 ID
|
||||
*/
|
||||
private Long ruleId;
|
||||
|
||||
private RuleType ruleType;
|
||||
|
||||
/**
|
||||
* 触发设备 ID
|
||||
*/
|
||||
private String deviceId;
|
||||
|
||||
private String triggerValue;
|
||||
|
||||
/**
|
||||
* 触发时间
|
||||
*/
|
||||
private LocalDateTime triggerTime;
|
||||
|
||||
/**
|
||||
* 关联的返航任务 ID
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 执行失败原因
|
||||
*/
|
||||
private String errorMessage;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.maibu.core.domain.rule;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.maibu.core.enums.CompareEnum;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
|
||||
public class TriggerConditions {
|
||||
|
||||
/**
|
||||
* 触发条件判断的字段key 电量 battery /temperature/offline_duration/voltage
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 比较运算符:GT、GTE、LT、LTE、EQ、NE
|
||||
*/
|
||||
private CompareEnum operator;
|
||||
|
||||
/**
|
||||
* 比较阈值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ActionType {
|
||||
|
||||
AUTO_TASK("AUTO_TASK", "路径规划任务"),
|
||||
|
||||
BACK_TO_REST("BACK_TO_REST", "回休息区"),
|
||||
|
||||
SEND_COMMAND("SEND_COMMAND", "下发指令"),
|
||||
|
||||
ALARM("ALARM", "告警"),
|
||||
|
||||
WORK_ORDER("WORK_ORDER", "工单下发");
|
||||
|
||||
/** 订单类型值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 订单类型名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
}
|
||||
@@ -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 DeviceScope {
|
||||
|
||||
ALL("ALL", "所有设备"),
|
||||
|
||||
GROUP("GROUP", "设备组"),
|
||||
|
||||
SOME("SOME", "特定的");
|
||||
|
||||
/** 订单类型值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 订单类型名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
}
|
||||
@@ -7,12 +7,13 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public enum DeviceTaskStaus {
|
||||
|
||||
NEW("NEW","新建"),
|
||||
EXECUTING("EXECUTING","执行中"),
|
||||
PAUSE("PAUSE","暂停中"),
|
||||
CANCELED("CANCELED","已取消"),
|
||||
FINISH("FINISH","执行成功"),
|
||||
FAILED("FAILED","执行失败");
|
||||
NEW("NEW", "新建"),
|
||||
EXECUTING("EXECUTING", "执行中"),
|
||||
PAUSE("PAUSE", "暂停中"),
|
||||
CANCELED("CANCELED", "已取消"),
|
||||
CANCELING("CANCELING", "取消中"),
|
||||
FINISH("FINISH", "执行成功"),
|
||||
FAILED("FAILED", "执行失败");
|
||||
|
||||
|
||||
private final String code;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.maibu.core.enums;
|
||||
public enum MesType {
|
||||
AUTH, // 登录连接权限web->be
|
||||
deviceInfo, // 设备状态 be->web
|
||||
locationInfo,
|
||||
path, // 路径下发 web->be
|
||||
have_logged_in, // 消息
|
||||
device_status_changed, // 上下线状态变化
|
||||
@@ -13,5 +14,7 @@ public enum MesType {
|
||||
remoteControl,
|
||||
detectionReport, // 障碍物消息
|
||||
switchPermission, // 切换控制申请
|
||||
switchResult;// 切换结果
|
||||
switchResult,// 切换结果
|
||||
route_post,// 路径规划 点位推送
|
||||
mapPush;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OtaOperate {
|
||||
|
||||
upload("upload", "上传"),
|
||||
upgrade("upgrade", "升级"),
|
||||
rollback("rollback", "回滚"),
|
||||
reboot("reboot", "重启");
|
||||
|
||||
private final String name;
|
||||
private final String value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RouteType {
|
||||
|
||||
MOWING_TASK("MOWING_TASK", "割草任务"),
|
||||
|
||||
INSPECTION_TASK("INSPECTION_TASK", "巡检任务"),
|
||||
|
||||
BACK_TO_REST_POINT("BACK_TO_REST_POINT", "返航任务"),
|
||||
|
||||
OTHER("OTHER", "其他类型");
|
||||
|
||||
/** 订单类型值(存储在数据库中) */
|
||||
private final String value;
|
||||
|
||||
/** 订单类型名称(用于前端显示) */
|
||||
private final String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.maibu.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RuleType {
|
||||
|
||||
LOW_BATTERY_RETURN("LOW_BATTERY_RETURN", "低电量返航");
|
||||
|
||||
/** 错误来源值(存储在数据库中) */
|
||||
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,10 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DetectionStamp {
|
||||
|
||||
private Long sec;
|
||||
private Long nanosec;
|
||||
}
|
||||
@@ -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,12 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HeartBeatDTO extends HostBase {
|
||||
private String status;
|
||||
|
||||
private Long sysTimestamp; //服务器的时间
|
||||
}
|
||||
13
maibu-common/src/main/java/com/maibu/core/host/HostBase.java
Normal file
13
maibu-common/src/main/java/com/maibu/core/host/HostBase.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class HostBase {
|
||||
|
||||
private String protocol_version;
|
||||
private String message_id;
|
||||
private String sn;
|
||||
private Long timestamp; //上位机的时间
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostLocationRelTimeDTO extends HostBase {
|
||||
|
||||
private LocationMessage data;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostModeChangeDTO extends HostBase {
|
||||
|
||||
private String command_id;
|
||||
|
||||
private Map<String, Object> data; // map key control_mode 2=自动任务,3=远程遥控
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostModeChangeReplyDTO extends HostBase {
|
||||
|
||||
private Boolean accepted;
|
||||
|
||||
private String code;
|
||||
|
||||
private String message;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostNavigationReplyDTO extends HostBase {
|
||||
|
||||
private String task_id; //任务唯一编号
|
||||
private String command_id;//指令唯一编号
|
||||
private boolean accepted;//是否接收
|
||||
private String code;//任务动作 OK|INVALID|BUSY|ERROR
|
||||
|
||||
private String message;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostTaskStatusDTO extends HostBase{
|
||||
|
||||
private String task_id; //任务唯一编号
|
||||
private String command_id;//指令唯一编号
|
||||
private String mode;//导航任务模式 single_point|coverage
|
||||
private String status;//任务动作 accepted|running|paused|completed|cancelled|failed
|
||||
|
||||
private HostTaskStatusDetailDTO data;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class HostTaskStatusDetailDTO {
|
||||
private double progress;// 已完成作业路径比例,转移段持平且任务内不回退。规划完成前的 0 不代表已开始覆盖。
|
||||
|
||||
private double distance_remaining; // 整任务剩余作业路径
|
||||
private Integer number_of_recoveries;// 恢复行为次数,不代表障碍数量。
|
||||
private double elapsed_s;
|
||||
private double eta_s;
|
||||
private Integer current_cell_index;
|
||||
private Integer total_cells;
|
||||
private double distance_traveled;
|
||||
private double speed;
|
||||
private Integer task_phase;
|
||||
|
||||
private String error_code;
|
||||
private String error_message;
|
||||
private double total_distance_m;
|
||||
private double distance_traveled_m;
|
||||
private double execution_time_s;
|
||||
private Integer cells_completed;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostVehicleRelTimeDTO extends HostBase {
|
||||
|
||||
private VehicleMessage data;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class HostWorkRecordCreateDTO extends HostBase {
|
||||
|
||||
private String task_id; // 任务唯一编号
|
||||
private String command_id;// 指令唯一编号
|
||||
private String mode;// 导航任务模式 single_point|coverage
|
||||
private String action;// 任务动作 start/pause/resume/cancel
|
||||
// private String frame_id; //WGS84
|
||||
|
||||
private PointEntity data;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.maibu.core.domain.OrgNoUserDO;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("iot_host_location_message")
|
||||
public class LocationMessage extends OrgNoUserDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private double yaw;// 目标航向,正北0°、顺时针正、0-360°
|
||||
private String fix_status;
|
||||
private double altitude;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MutiPointEntity {
|
||||
|
||||
private int index;
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private double yaw;//目标航向,正北0°、顺时针正、0-360°
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.maibu.core.enums.MesType;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ObstacleDetectionData {
|
||||
|
||||
private MesType type;
|
||||
|
||||
/**
|
||||
* 融合状态
|
||||
*/
|
||||
private String fusion_status;
|
||||
|
||||
private String fusion_status_code;
|
||||
|
||||
private String fusion_status_reason;
|
||||
|
||||
/**
|
||||
* 障碍物检测状态
|
||||
*/
|
||||
private String obstacle_status;
|
||||
|
||||
/**
|
||||
* 检测目标数量
|
||||
*/
|
||||
private Integer object_count;
|
||||
|
||||
/**
|
||||
* 检测目标列表
|
||||
*/
|
||||
private List<ObstacleObject> objects;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ObstacleObject {
|
||||
|
||||
private Integer class_id;
|
||||
private String class_name;
|
||||
private Double confidence;
|
||||
|
||||
private Integer x1;
|
||||
private Integer y1;
|
||||
private Integer x2;
|
||||
private Integer y2;
|
||||
|
||||
private Double x;
|
||||
private Double y;
|
||||
private Double z;
|
||||
|
||||
private Double distance;
|
||||
private Double angle;
|
||||
|
||||
private Double latitude;
|
||||
private Double longitude;
|
||||
|
||||
private Integer track_id;
|
||||
|
||||
private Double size_x;
|
||||
private Double size_y;
|
||||
private Double size_z;
|
||||
|
||||
private DetectionStamp det_stamp;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ObstaclePostDTO extends HostBase {
|
||||
|
||||
private ObstacleDetectionData fusion_obstacle;
|
||||
|
||||
}
|
||||
@@ -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; // 指令有效时间,单位毫秒
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PointEntity {
|
||||
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private double yaw;// 目标航向,正北0°、顺时针正、0-360°
|
||||
|
||||
private List<MutiPointEntity> boundary_points;
|
||||
|
||||
private double cell_size;// 覆盖分辨率,单位m
|
||||
|
||||
private double angle;// 覆盖作业方向,单位度
|
||||
|
||||
private String url; // minio 存放文件的地址
|
||||
private Long path_id; // 路径id 系统保存用的routeId;
|
||||
private String version;
|
||||
private boolean execute = true; // 是直接执行还是创建自定义任务
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.maibu.core.host;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VehicleMessage {
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private double cutter_speed;// 割刀实际转速
|
||||
|
||||
private double battery_percentage;// 实时电量百分比
|
||||
private double battery_voltage;// 实时电压
|
||||
|
||||
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 String mcu_time; // 下位机状态中的 MCU 时间
|
||||
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 Integer control_mode;// 遥控器拨杆对应的当前控制模式 0=无控制|1=本地遥控|2=自动任务|3=远程遥控
|
||||
|
||||
private double linear_speed; // 实时线速度
|
||||
private double angular_speed; // 实时角速度
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import com.maibu.core.ota.OtaPackageCode;
|
||||
import com.maibu.core.protocol.Message;
|
||||
import com.maibu.core.protocol.modbus.ModbusCode;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 消息解析model
|
||||
* @author gsb
|
||||
* @date 2022/10/10 15:53
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Builder
|
||||
public class DeviceData extends Message {
|
||||
|
||||
/*topic*/
|
||||
private String topicName;
|
||||
|
||||
/*设备编号*/
|
||||
private String serialNumber;
|
||||
|
||||
/*原数据*/
|
||||
private byte[] data;
|
||||
|
||||
private ByteBuf buf;
|
||||
|
||||
private Object body;
|
||||
/*MQTT OR 其他*/
|
||||
private int type;
|
||||
/*Modbus*/
|
||||
private ModbusCode code;
|
||||
/**产品id*/
|
||||
private Long productId;
|
||||
|
||||
private OtaPackageCode netModbusCode;
|
||||
|
||||
private int bitCount;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import com.maibu.core.protocol.modbus.ModbusCode;
|
||||
import com.maibu.enums.ServerType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备下发指令model
|
||||
*
|
||||
* @author gsb
|
||||
* @date 2022/10/10 16:18
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeviceDownMessage {
|
||||
|
||||
private String messageId;
|
||||
/**
|
||||
* 时间戳,单位毫秒
|
||||
*/
|
||||
private Long timestamp;
|
||||
/**
|
||||
* 消息体
|
||||
*/
|
||||
private Object body;
|
||||
/*下发的指令,服务调用的时候就是服务标识符*/
|
||||
private String identifier;
|
||||
/*产品id*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
private String serialNumber;
|
||||
/**
|
||||
* 从机编号
|
||||
*/
|
||||
private Integer slaveId;
|
||||
private ModbusCode code;
|
||||
private String protocolCode;
|
||||
|
||||
private List<PropRead> values;
|
||||
private String topic;
|
||||
private String subCode;
|
||||
private ServerType serverType;
|
||||
|
||||
public DeviceDownMessage(List<PropRead> values, String topic, String subCode,String transport) {
|
||||
this.values = values;
|
||||
this.topic = topic;
|
||||
this.subCode = subCode;
|
||||
this.serverType = ServerType.explain(transport);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 平台下发指令数据model
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
public class DeviceFunctionMessage {
|
||||
|
||||
/*流水号,兼容modbus标准协议没有消息流水号*/
|
||||
private String seqNo;
|
||||
/*平台时间*/
|
||||
private Long pfTimestamp;
|
||||
/*下发的消息体*/
|
||||
private Object body;
|
||||
/*下发的指令物模型标识符*/
|
||||
private String identifier;
|
||||
/*下发的数据寄存器地址*/
|
||||
private String hexAddress;
|
||||
/*产品ID*/
|
||||
private Long productId;
|
||||
/*设备编号*/
|
||||
private String serialNumber;
|
||||
/*网关设备编号*/
|
||||
private String protocolCode;
|
||||
|
||||
/*是否有子设备 0-否,1-是*/
|
||||
private Integer hasSub;
|
||||
/*子设备从机编号 例如 02 编号从机。通过主机集控下发的指定从机编号*/
|
||||
private String subDeviceCode;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 设备消息
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class DeviceMessage {
|
||||
|
||||
/** 下发的数据*/
|
||||
private Object message;
|
||||
|
||||
/** 下发的topic*/
|
||||
private String topicName;
|
||||
|
||||
/** 设备编号*/
|
||||
private String serialNumber;
|
||||
|
||||
private String dataType;
|
||||
|
||||
/** 时间 */
|
||||
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss:SSS")
|
||||
private Date time;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 指令下发组将的model
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
public class FunctionCallBackBo {
|
||||
|
||||
/*下发的数据*/
|
||||
private byte[] message;
|
||||
|
||||
/*MQTt-下发的topic*/
|
||||
private String topicName;
|
||||
|
||||
/*设备编号*/
|
||||
private String serialNumber;
|
||||
/**
|
||||
* 原数据包
|
||||
*/
|
||||
private String sources;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 指令下发组将的model
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
public class InstructionsMessage {
|
||||
|
||||
/*下发的数据*/
|
||||
private byte[] message;
|
||||
|
||||
/*MQTt-下发的topic*/
|
||||
private String topicName;
|
||||
|
||||
/*设备编号*/
|
||||
private String serialNumber;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2024/6/20 10:53
|
||||
*/
|
||||
@Data
|
||||
public class ModbusPollMsg {
|
||||
|
||||
/**
|
||||
* 下发指令
|
||||
*/
|
||||
private List<String> commandList;
|
||||
/**
|
||||
* 服务端类型
|
||||
*/
|
||||
private Integer serverType;
|
||||
/**
|
||||
* 产品id
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
private String serialNumber;
|
||||
|
||||
private String transport;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
public class MqttBo {
|
||||
|
||||
/*主题*/
|
||||
private String topic;
|
||||
/*数据*/
|
||||
private String data;
|
||||
/*消息质量*/
|
||||
private int qos = 1;
|
||||
/*发送方向*/
|
||||
private String direction;
|
||||
/*时间*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date ts;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import com.maibu.core.protocol.modbus.ModbusCode;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2022/12/9 10:15
|
||||
*/
|
||||
@Data
|
||||
public class PropRead {
|
||||
|
||||
/**设备编号*/
|
||||
private String serialNumber;
|
||||
/**寄存器起始地址*/
|
||||
private int address;
|
||||
/**
|
||||
* 读取寄存器个数
|
||||
*/
|
||||
private int count;
|
||||
/**数据结果长度计算值*/
|
||||
private int length;
|
||||
/**
|
||||
* 从机地址
|
||||
*/
|
||||
private int slaveId;
|
||||
/**
|
||||
* 读取个数
|
||||
*/
|
||||
private int quantity;
|
||||
/**
|
||||
* 数据
|
||||
*/
|
||||
private String data;
|
||||
/**
|
||||
* 功能码
|
||||
*/
|
||||
private ModbusCode code;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 协议bean
|
||||
* @author gsb
|
||||
* @date 2022/10/25 14:54
|
||||
*/
|
||||
@Data
|
||||
public class ProtocolDto {
|
||||
|
||||
/**协议编号*/
|
||||
private String code;
|
||||
private String name;
|
||||
/*外部协议url*/
|
||||
private String protocolUrl;
|
||||
private String description;
|
||||
/**协议类型 协议类型 0:系统协议 1:jar,2.js,3.c*/
|
||||
private Integer protocolType;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.maibu.core.mq.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 网关子设备model
|
||||
* @author gsb
|
||||
* @date 2022/10/10 10:18
|
||||
*/
|
||||
@Data
|
||||
public class SubDeviceMessage {
|
||||
/*子设备编号或编码*/
|
||||
private String serialNumber;
|
||||
/*数据*/
|
||||
private byte[] data;
|
||||
/*消息id*/
|
||||
private String messageId;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.maibu.core.mq.ota;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* OTA升级回复model
|
||||
* @author gsb
|
||||
* @date 2022/10/24 17:20
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public class OtaReplyMessage {
|
||||
|
||||
private Long taskId;
|
||||
private BigDecimal version;
|
||||
private int status;
|
||||
private int progress;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.maibu.core.mq.ota;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* OTA远程升级
|
||||
* @author gsb
|
||||
* @date 2022/10/10 10:22
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public class OtaUpgradeBo {
|
||||
|
||||
// 设备编码
|
||||
private String serialNumber;
|
||||
// 升级任务ID
|
||||
private Long taskId;
|
||||
// 消息内容
|
||||
private byte[] msg;
|
||||
// 设备状态
|
||||
private int status;
|
||||
// topic
|
||||
private String topicName;
|
||||
// 固件包版本
|
||||
private BigDecimal version;
|
||||
// 固件包http地址
|
||||
private String url;
|
||||
// 固件包分包传输大小
|
||||
private int packageSize;
|
||||
// 固件包传输偏移量
|
||||
private int offset;
|
||||
// 升级进度
|
||||
private int progress;
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.maibu.core.mq.ota;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.maibu.utils.DateUtils;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* ota升级发送,实现Delayed延时接口
|
||||
*
|
||||
* @author bill
|
||||
*/
|
||||
@Data
|
||||
public class OtaUpgradeDelayTask implements Delayed {
|
||||
|
||||
/**
|
||||
* 固件id
|
||||
*/
|
||||
private Long firmwareId;
|
||||
/**
|
||||
* 1:指定产品 2:指定设备
|
||||
*/
|
||||
private Long upgradeType;
|
||||
|
||||
private List<String> devices;
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private Long taskId;
|
||||
/**
|
||||
* 开始升级时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date startTime;
|
||||
|
||||
|
||||
/**
|
||||
* 设置延迟执行时间 开始升级时间 -当前时间
|
||||
*
|
||||
* @param unit
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return startTime.getTime() - DateUtils.getTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed o) {
|
||||
OtaUpgradeDelayTask delayTask = (OtaUpgradeDelayTask) o;
|
||||
//比较
|
||||
long diff = this.startTime.getTime() - delayTask.startTime.getTime();
|
||||
if (diff <= 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.maibu.core.ota;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Data
|
||||
@TableName("iot_ota_firmware")
|
||||
public class DeviceOtaFirmware extends BaseDO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String version; //版本号
|
||||
|
||||
private String fileName; //文件名
|
||||
|
||||
private String minioObjectName; //服务器文件名
|
||||
|
||||
private String fileUrl; //存放地址
|
||||
|
||||
private String deviceType;
|
||||
|
||||
private String fileSize;
|
||||
|
||||
private String description;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.maibu.core.ota;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.maibu.core.domain.BaseDO;
|
||||
import com.maibu.core.enums.OtaOperate;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@Data
|
||||
@TableName(value = "iot_ota_operate_record", autoResultMap = true)
|
||||
public class DeviceOtaOperateRecord extends BaseDO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private OtaOperate operateType; // 操作类型
|
||||
|
||||
private String fileName; // 名称
|
||||
|
||||
private Long firmwareId; // id
|
||||
|
||||
private String deviceId; // 名称
|
||||
|
||||
private String deviceType;
|
||||
|
||||
private String preVersion;
|
||||
|
||||
private String nowVersion;
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.maibu.core.ota;
|
||||
|
||||
import com.maibu.exception.ServiceException;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OtaPackageCode {
|
||||
|
||||
OTA_01("查询产品工装号",(byte) 0x01),
|
||||
OTA_0A("OTA升级启动",(byte) 0x0A),
|
||||
OTA_0B("OTA升级包传输",(byte) 0x0B)
|
||||
;
|
||||
|
||||
private String desc;
|
||||
private byte code;
|
||||
|
||||
public static OtaPackageCode getInstance(int code) {
|
||||
switch ((byte)code) {
|
||||
case 0x01:
|
||||
return OTA_01;
|
||||
case 0x0A:
|
||||
return OTA_0A;
|
||||
case 0x0B:
|
||||
return OTA_0B;
|
||||
default:
|
||||
throw new ServiceException("功能码[" + code + "],未定义");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDes(int code){
|
||||
switch ((byte)code) {
|
||||
case 0x01:
|
||||
return OTA_01.desc;
|
||||
case 0x0A:
|
||||
return OTA_0A.desc;
|
||||
case 0x0B:
|
||||
return OTA_0B.desc;
|
||||
default:
|
||||
return "UNKOWN";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.maibu.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 设备回调状态
|
||||
*
|
||||
* @author bill
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DeviceStatusEnum {
|
||||
|
||||
working("1", "工作中"),
|
||||
idle("2", "空闲中"),
|
||||
offline("3", "离线"),
|
||||
charging("4", "充电中"),
|
||||
error("5", "故障");
|
||||
|
||||
String code;
|
||||
String message;
|
||||
|
||||
}
|
||||
@@ -6,8 +6,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.influxdb.query.FluxRecord;
|
||||
import com.influxdb.query.FluxTable;
|
||||
import com.maibu.influxdb.inter.InfluxField;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import com.maibu.core.ota.DeviceOtaFirmware;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public interface DeviceOtaFirmwareMapper extends BaseMapperX<DeviceOtaFirmware> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import com.maibu.core.ota.DeviceOtaOperateRecord;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public interface DeviceOtaOperateRecordMapper extends BaseMapperX<DeviceOtaOperateRecord> {
|
||||
|
||||
}
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.maibu.core.business.DevicePlanTask;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 设备历史状态
|
||||
@@ -10,4 +17,12 @@ import org.springframework.stereotype.Repository;
|
||||
@Repository
|
||||
public interface DevicePlanTaskMapper extends BaseMapperX<DevicePlanTask> {
|
||||
|
||||
@Select("SELECT t.*, iwr.work_name,d.device_alias " +
|
||||
"FROM iot_device_task t " +
|
||||
"LEFT JOIN iot_device d ON d.serial_number = t.device_id " +
|
||||
"left join iot_work_record iwr on t.route_id = iwr.id " +
|
||||
"${ew.customSqlSegment}")
|
||||
List<DevicePlanTask> selectTaskHistoryWithDeviceAlias(
|
||||
@Param(Constants.WRAPPER) Wrapper<DevicePlanTask> wrapper);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.maibu.core.host.LocationMessage;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
|
||||
/**
|
||||
* 设备历史状态
|
||||
*/
|
||||
@Repository
|
||||
public interface HostLocationMapper extends BaseMapperX<LocationMessage> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.maibu.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.maibu.core.business.RegionConsecutiveTaskRecord;
|
||||
import com.maibu.mybatis.mapper.BaseMapperX;
|
||||
|
||||
/**
|
||||
* 区域连续任务下发记录
|
||||
*/
|
||||
@Repository
|
||||
public interface RegionConsecutiveTaskRecordMapper extends BaseMapperX<RegionConsecutiveTaskRecord> {
|
||||
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.maibu.memory;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
import com.maibu.core.enums.ConnectorType;
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -24,19 +27,22 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Component
|
||||
@Data
|
||||
@Slf4j
|
||||
public class DeviceSessionManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeviceSessionManager.class);
|
||||
// 设备ID -> 设备对象(业务实体)
|
||||
private final ConcurrentHashMap<String, NettyDevice> deviceMap = new ConcurrentHashMap<>();
|
||||
|
||||
// 当前设备的控制权在哪 登录的账号 deviceId(下位机) -> token key 唯一保证一个deviceId 只有一个控制权
|
||||
private final ConcurrentHashMap<String, String> controllerMap = new ConcurrentHashMap<>();
|
||||
|
||||
// 设备ID -> Channel(通信通道)
|
||||
private final ConcurrentHashMap<String, Channel> channelMap = new ConcurrentHashMap<>();
|
||||
|
||||
// Channel -> 设备ID(反查)
|
||||
private final ConcurrentHashMap<Channel, String> channelToDeviceIdMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public void clearChannelToDeviceIdMap(String deviceId) {
|
||||
if (StringUtils.isEmpty(deviceId) || CollectionUtils.isEmpty(channelToDeviceIdMap)) {
|
||||
return;
|
||||
@@ -64,7 +70,6 @@ public class DeviceSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册设备连接(设备上线)
|
||||
*
|
||||
@@ -72,7 +77,8 @@ public class DeviceSessionManager {
|
||||
* @param channel 通信通道
|
||||
* @param deviceType 设备类型(MASTER/SLAVE)
|
||||
*/
|
||||
public void registerDevice(String deviceId, Channel channel, ConnectorType deviceType, ConnectorStatus status, String slaveId) {
|
||||
public void registerDevice(String deviceId, Channel channel, ConnectorType deviceType, ConnectorStatus status,
|
||||
String slaveId) {
|
||||
NettyDevice nettyDevice = deviceMap.computeIfAbsent(deviceId, id -> new NettyDevice(id, deviceType));
|
||||
nettyDevice.setChannel(channel);
|
||||
nettyDevice.setConnectorStatus(status); // 默认上线即ACTIVE
|
||||
@@ -84,6 +90,20 @@ public class DeviceSessionManager {
|
||||
System.out.println("Registered device: " + deviceId + " type: " + deviceType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册下位机设备
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
public void registerSlaveDevice(String deviceId, ConnectorStatus status, String slaveId) {
|
||||
NettyDevice nettyDevice = deviceMap.computeIfAbsent(deviceId, id -> new NettyDevice(id, ConnectorType.SLAVE));
|
||||
nettyDevice.setConnectorStatus(status); // 默认上线即ACTIVE
|
||||
nettyDevice.setCurrentSlaveId(slaveId);
|
||||
nettyDevice.setLatestLoginTime(System.currentTimeMillis());
|
||||
deviceMap.put(deviceId, nettyDevice);
|
||||
logger.debug("Registered slave device:{},type:{}", deviceId, ConnectorType.SLAVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上位机绑定下位机,建立双向绑定关系
|
||||
*
|
||||
@@ -92,7 +112,8 @@ public class DeviceSessionManager {
|
||||
*/
|
||||
public void bindConnector(String masterId, String slaveId) {
|
||||
NettyDevice master = deviceMap.get(masterId);
|
||||
if (master == null) return;
|
||||
if (master == null)
|
||||
return;
|
||||
NettyDevice slave = deviceMap.computeIfAbsent(slaveId, id -> new NettyDevice(id, ConnectorType.SLAVE));
|
||||
master.addConnectedDevice(slave);
|
||||
System.out.println("Bind connectors for master " + masterId + " and slave " + slaveId);
|
||||
@@ -105,6 +126,62 @@ public class DeviceSessionManager {
|
||||
return deviceMap.get(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有控制权的 客户端
|
||||
*/
|
||||
public String getMaster(String deviceId) {
|
||||
return controllerMap.get(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端当前 控制的设备
|
||||
*/
|
||||
public String getControl(String token) {
|
||||
for (String key : controllerMap.keySet()) {
|
||||
if (controllerMap.get(key).equals(token)) {
|
||||
return controllerMap.get(token);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void lock(String deviceId, String token) {
|
||||
if (!StringUtils.isEmpty(deviceId) && !StringUtils.isEmpty(token)) {
|
||||
controllerMap.put(deviceId, token);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean unLock(String token) {
|
||||
if (!StringUtils.isEmpty(token)) {
|
||||
Iterator<String> iterator = controllerMap.keySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String key = iterator.next();
|
||||
if (controllerMap.get(key).equals(token)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean unLock(String deviceId, String token, boolean force) {
|
||||
if (!StringUtils.isEmpty(deviceId)) {
|
||||
if (force) {
|
||||
controllerMap.remove(deviceId);
|
||||
return true;
|
||||
} else {
|
||||
String nowToken = controllerMap.get(deviceId);
|
||||
if (!StringUtils.isEmpty(token) && nowToken.equals(token)) {
|
||||
controllerMap.remove(deviceId);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// 模糊匹配
|
||||
public List<NettyDevice> getDevicesLike(String query) {
|
||||
return deviceMap.values().stream()
|
||||
@@ -112,32 +189,31 @@ public class DeviceSessionManager {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public List<NettyDevice> getSlaveControl(String slaveId) {
|
||||
// 获取所有连接的主机 且是active状态的
|
||||
return deviceMap.values().stream()
|
||||
.filter(device -> ObjectUtil.equals(device.getCurrentSlaveId(), slaveId)
|
||||
.filter(device -> Objects.equals(device.getCurrentSlaveId(), slaveId)
|
||||
&& ConnectorStatus.ACTIVE.equals(device.getConnectorStatus()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public List<NettyDevice> getAllSlaveControl(String slaveId) {
|
||||
// 获取所有连接的主机 不区分状态
|
||||
return deviceMap.values().stream()
|
||||
.filter(device -> ObjectUtil.equals(device.getCurrentSlaveId(), slaveId))
|
||||
.filter(device -> !StringUtils.isEmpty(device.getCurrentSlaveId())
|
||||
&& Objects.equals(device.getCurrentSlaveId(), slaveId)
|
||||
&& device.getDeviceType().equals(ConnectorType.MASTER))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public NettyDevice getCurrentControl(String slaveId) {
|
||||
// 获取所有连接的主机 不区分状态
|
||||
return deviceMap.values().stream()
|
||||
.filter(device -> ObjectUtil.equals(device.getCurrentSlaveId(), slaveId)
|
||||
.filter(device -> Objects.equals(device.getCurrentSlaveId(), slaveId)
|
||||
&& ConnectorStatus.ACTIVE.equals(device.getConnectorStatus()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/// 模糊匹配
|
||||
public NettyDevice getUserControl(String userName) {
|
||||
return deviceMap.values().stream()
|
||||
@@ -146,7 +222,6 @@ public class DeviceSessionManager {
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据设备ID获取Channel
|
||||
*/
|
||||
@@ -161,7 +236,6 @@ public class DeviceSessionManager {
|
||||
return channelToDeviceIdMap.get(channel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据从机查控制的主机
|
||||
*/
|
||||
@@ -174,7 +248,8 @@ public class DeviceSessionManager {
|
||||
* 根据从机查所有主机
|
||||
*/
|
||||
public List<NettyDevice> getMastersBySlaveId(String slaveId) {
|
||||
return deviceMap.values().stream().filter(x -> Objects.equals(x.getCurrentSlaveId(), slaveId)).collect(Collectors.toList());
|
||||
return deviceMap.values().stream().filter(x -> Objects.equals(x.getCurrentSlaveId(), slaveId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,18 +257,25 @@ public class DeviceSessionManager {
|
||||
*/
|
||||
public void removeDevice(String deviceId) {
|
||||
NettyDevice nettyDevice = deviceMap.remove(deviceId);
|
||||
// Channel channel = channelMap.remove(deviceId);
|
||||
// Channel channel = channelMap.remove(deviceId);
|
||||
clearChannelToDeviceIdMap(deviceId);
|
||||
// if (channel != null) {
|
||||
// channelToDeviceIdMap.remove(channel);
|
||||
// channel.close();
|
||||
// }
|
||||
// if (channel != null) {
|
||||
// channelToDeviceIdMap.remove(channel);
|
||||
// channel.close();
|
||||
// }
|
||||
if (nettyDevice != null) {
|
||||
// 仅当设备是上位机时,才解绑绑定关系
|
||||
if (nettyDevice.getDeviceType() == ConnectorType.MASTER) {
|
||||
for (Connector connected : new HashSet<>(nettyDevice.getConnectedConnectors())) {
|
||||
nettyDevice.removeConnectedDevice(connected);
|
||||
}
|
||||
// 清理channel和状态
|
||||
nettyDevice.setChannel(null);
|
||||
Channel channel = channelMap.remove(deviceId);
|
||||
if (channel != null) {
|
||||
channelToDeviceIdMap.remove(channel);
|
||||
channel.close();
|
||||
}
|
||||
} else {
|
||||
// 如果是下位机,则保留绑定关系,只清理channel和状态
|
||||
nettyDevice.setChannel(null);
|
||||
@@ -206,7 +288,6 @@ public class DeviceSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断设备是否在线
|
||||
*/
|
||||
@@ -231,5 +312,23 @@ public class DeviceSessionManager {
|
||||
return nettyDevice != null && nettyDevice.canReceive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端当前 控制的设备
|
||||
*/
|
||||
public String getDeviceByTaskId(Long taskId) {
|
||||
if (taskId == null) {
|
||||
return null;
|
||||
}
|
||||
log.debug("sendMessage deviceMap:{},taskId={}", JsonUtils.toJsonString(deviceMap), taskId);
|
||||
for (String key : deviceMap.keySet()) {
|
||||
NettyDevice nettyDevice = deviceMap.get(key);
|
||||
log.debug("sendMessage currentTaskId:{},equal {}", JsonUtils.toJsonString(nettyDevice.getCurrentTaskId()),
|
||||
Objects.equals(nettyDevice.getCurrentTaskId(), taskId));
|
||||
if (nettyDevice != null && Objects.equals(nettyDevice.getCurrentTaskId(), taskId)) {
|
||||
return nettyDevice.getConnectorId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user