From e0389a15daddb764bd740474bac46f0f6add87b1 Mon Sep 17 00:00:00 2001 From: listom Date: Mon, 12 Aug 2024 18:08:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E6=B5=B7=E4=B8=BA?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-local.yml | 161 +++++++ .../src/main/resources/application.yml | 13 + .../com/fastbee/common/utils/DateUtils.java | 2 + .../iot/cache/DeviceCacheConstants.java | 54 +++ .../fastbee/iot/cache/impl/TSLCacheImpl.java | 1 + .../com/fastbee/iot/domain/ThingsModel.java | 2 + .../fastbee/iot/enums/ProductTypeEnum.java | 43 ++ .../iot/enums/WaterFertilizerHttpEnum.java | 49 ++ .../haiwei/controller/HaiWeiController.java | 61 +++ .../iot/haiwei/service/HaiWeiService.java | 18 + .../service/impl/HaiWeiServiceImpl.java | 161 +++++++ .../iot/httpclient/HttpAPIController.java | 445 ++++++++++++++++++ .../iot/httpclient/HttpClientConfig.java | 103 ++++ .../fastbee/iot/httpclient/HttpResultDTO.java | 15 + .../iot/httpclient/IdleConnectionEvictor.java | 41 ++ .../fastbee/iot/mapper/DeviceLogMapper.java | 7 + .../com/fastbee/iot/mapper/TableMapper.java | 22 + .../iot/model/ThingsModels/PropertyDto.java | 5 + .../ThingsModels/ThingsModelValueItem.java | 3 + .../model/ThingsModels/ThingsModelsDto.java | 50 -- .../fastbee/iot/model/haiwei/CmdHaiWeiVo.java | 22 + .../fastbee/iot/model/haiwei/CmdTagVo.java | 19 + .../iot/model/haiwei/HaiWeiDeviceInfoVo.java | 35 ++ .../iot/model/haiwei/HaiWeiHttpVo.java | 23 + .../iot/model/haiwei/HaiWeiPropertyVo.java | 39 ++ .../fastbee/iot/model/haiwei/HaiWeiVo.java | 137 ++++++ .../iot/model/haiwei/bo/CmdHaiWeiBo.java | 15 + .../fastbee/iot/model/haiwei/bo/HaiWeiBo.java | 13 + .../iot/model/haiwei/dto/CmdHaiWeiDto.java | 24 + .../iot/tdengine/service/ILogService.java | 2 + .../service/impl/MySqlLogServiceImpl.java | 32 ++ .../service/impl/TdengineLogServiceImpl.java | 5 + .../java/com/fastbee/iot/timer/QxtrTask.java | 224 +++++++++ .../main/resources/mapper/iot/TableMapper.xml | 34 ++ .../mapper/iot/ThingsModelMapper.xml | 22 +- 35 files changed, 1847 insertions(+), 55 deletions(-) create mode 100644 fastbee-admin/src/main/resources/application-local.yml create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/DeviceCacheConstants.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/ProductTypeEnum.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/WaterFertilizerHttpEnum.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/controller/HaiWeiController.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/HaiWeiService.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/impl/HaiWeiServiceImpl.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpAPIController.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpClientConfig.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpResultDTO.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/IdleConnectionEvictor.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TableMapper.java delete mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelsDto.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdHaiWeiVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdTagVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiDeviceInfoVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiHttpVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiPropertyVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiVo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/CmdHaiWeiBo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/HaiWeiBo.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/dto/CmdHaiWeiDto.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/timer/QxtrTask.java create mode 100644 fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/TableMapper.xml diff --git a/fastbee-admin/src/main/resources/application-local.yml b/fastbee-admin/src/main/resources/application-local.yml new file mode 100644 index 0000000..29df449 --- /dev/null +++ b/fastbee-admin/src/main/resources/application-local.yml @@ -0,0 +1,161 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://w.hanzhenyun.com:3306/wumei2.4?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: wumei2.4 + password: rtB8EhbRRYSGyxHw + # 从库数据源 + slave: + enabled: false # 从数据源开关/默认关闭 + url: + username: + password: + # TDengine数据库 + tdengine-server: + enabled: false # 默认不启用TDengine,true=启用,false=不启用 + driverClassName: com.taosdata.jdbc.TSDBDriver + url: jdbc:TAOS://fastbee:6030/fastbee_log?timezone=UTC-8&charset=utf-8 + username: root + password: taosdata + dbName: fastbee_log + + initialSize: 5 # 初始连接数 + minIdle: 10 # 最小连接池数量 + maxActive: 20 # 最大连接池数量 + maxWait: 60000 # 配置获取连接等待超时的时间 + timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 # 配置一个连接在池中最大生存的时间,单位是毫秒 + validationQuery: SELECT 1 FROM DUAL # 配置检测连接是否有效 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: fastbee + login-password: fastbee + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + host: localhost # 地址 + port: 6379 # 端口,默认为6379 +# database: 1 # 数据库索引 +# password: fastbee # 密码 + timeout: 10s # 连接超时时间 + lettuce: + pool: + min-idle: 0 # 连接池中的最小空闲连接 + max-idle: 8 # 连接池中的最大空闲连接 + max-active: 8 # 连接池的最大数据库连接数 + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + # mqtt 配置 + mqtt: + username: fastbee # 账号 + password: fastbee # 密码 + host-url: tcp://localhost:1883 # mqtt连接tcp地址 + client-id: ${random.int} # 客户端Id,不能相同,采用随机数 ${random.value} + default-topic: test # 默认主题 + timeout: 30 # 超时时间 + keepalive: 30 # 保持连接 + clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息) + +# redisson 配置 +redisson: + # redis key前缀 + keyPrefix: + # 线程池数量 + threads: 4 + # Netty线程池数量 + nettyThreads: 8 + # 单节点配置 + singleServerConfig: + # 客户端名称 + clientName: ${fastbee.name} + # 最小空闲连接数 + connectionMinimumIdleSize: 8 + # 连接池大小 + connectionPoolSize: 32 + # 连接空闲超时,单位:毫秒 + idleConnectionTimeout: 10000 + # 命令等待超时,单位:毫秒 + timeout: 3000 + # 发布和订阅连接池大小 + subscriptionConnectionPoolSize: 50 + +# sip 配置 +sip: + enabled: false # 是否启用视频监控SIP,true为启用 + ## 本地调试时,绑定网卡局域网IP,设备在同一局域网,设备接入IP填写绑定IP + ## 部署服务端时,默认绑定容器IP,设备接入IP填写服务器公网IP + ip: 127.0.0.1 + port: 5061 # SIP端口(保持默认) + domain: 3402000000 # 由省级、市级、区级、基层编号组成 + id: 34020000002000000001 # 同上,另外增加编号,(可保持默认) + password: 12345678 # 监控设备接入的密码 + +# 日志配置 +logging: + level: + com.fastbee: debug + com.yomahub: debug + org.dromara: warn + org.springframework: warn + +# Swagger配置 +swagger: + enabled: true # 是否开启swagger + pathMapping: /dev-api # 请求前缀 + +liteflow: + #FlowExecutor的execute2Future的线程数,默认为64 + main-executor-works: 64 + #FlowExecutor的execute2Future的自定义线程池Builder + main-executor-class: com.fastbee.ruleEngine.config.MainExecutorBuilder + #并行节点的线程池Builder + thread-executor-class: com.fastbee.ruleEngine.config.WhenExecutorBuilder + rule-source-ext-data-map: + # 应用名称,规则链和脚本组件名称需要一致,不要修改 + applicationName: fastbee + #是否开启SQL日志 + sqlLogEnabled: true + # 规则多时,启用快速加载模式 + fast-load: false + #是否开启SQL数据轮询自动刷新机制 默认不开启 + pollingEnabled: false + pollingIntervalSeconds: 60 + pollingStartSeconds: 60 + #以下是chain表的配置 + chainTableName: iot_scene + chainApplicationNameField: application_name + chainNameField: chain_name + elDataField: el_data + chainEnableField: enable + #以下是script表的配置 + scriptTableName: iot_script + scriptApplicationNameField: application_name + scriptIdField: script_id + scriptNameField: script_name + scriptDataField: script_data + scriptTypeField: script_type + scriptLanguageField: script_language + scriptEnableField: enable diff --git a/fastbee-admin/src/main/resources/application.yml b/fastbee-admin/src/main/resources/application.yml index 29a996e..c9b063b 100644 --- a/fastbee-admin/src/main/resources/application.yml +++ b/fastbee-admin/src/main/resources/application.yml @@ -157,3 +157,16 @@ forest: # Forest配置 版本为1.5.36 log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false) async-mode: platform # [自v1.5.27版本起可用] 异步模式(默认为 platform) +#http请求参数 +http: # 最大连接数 + maxTotal: 100 + # 并发数 + defaultMaxPerRoute: 20 + # 创建连接的最长时间 + connectTimeout: 1000 + # 从连接池中获取到连接的最长时间 + connectionRequestTimeout: 500 + # 数据传输的最长时间 + socketTimeout: 10000 + # 提交请求前测试连接是否可用 + staleConnectionCheckEnabled: true diff --git a/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java b/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java index 6ec1ca3..4bdd20b 100644 --- a/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java +++ b/fastbee-common/src/main/java/com/fastbee/common/utils/DateUtils.java @@ -22,6 +22,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String YYYY = "yyyy"; + public static String YYYYMM = "yyyyMM"; + public static String YYYY_MM = "yyyy-MM"; public static String YYYY_MM_DD = "yyyy-MM-dd"; diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/DeviceCacheConstants.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/DeviceCacheConstants.java new file mode 100644 index 0000000..929934c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/DeviceCacheConstants.java @@ -0,0 +1,54 @@ +package com.fastbee.iot.cache; + +/** + * 缓存的iot的key 常量 + */ +public class DeviceCacheConstants { + + /** + * 设备告警推送 redis key;连续多次报警时,只触发一次 + */ + private static final String DEVICE_ALARM_PUSH_KEY = "device_alarm_push:"; + + /** + * 设备告警 redis key;只要触发告警就修改缓存 + */ + private static final String DEVICE_ALARM_KEY = "device_alarm:"; + + /** + * 设备信息 redis key + */ + private static final String DEVICE_LOG_KEY = "device_log:"; + + /** + * 设备信息 redis key + */ + private static final String DEVICE_INFO_KEY = "device_info:"; + + /** + * 插入数据库间隔 + */ + private static final String DEVICE_INSERT_DB = "device_insert:"; + + + public static String getDeviceAlarmPushKey(String deviceId, String triggerName, String operator, String value) { + return DEVICE_ALARM_PUSH_KEY + deviceId + ":" + triggerName + ":" + operator + ":" + value; + } + + public static String getDeviceAlarmKey(String deviceId) { + return DEVICE_ALARM_KEY + deviceId; + } + + public static String getDeviceLogKey(String deviceId) { + return DEVICE_LOG_KEY + deviceId; + } + + public static String getDeviceInfoKey(Long deviceId) { + return DEVICE_INFO_KEY + deviceId; + } + + public static String getDeviceInsertDb(Long deviceId) { + return DEVICE_INSERT_DB + deviceId; + } + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/impl/TSLCacheImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/impl/TSLCacheImpl.java index 9779d14..ede37bb 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/impl/TSLCacheImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/cache/impl/TSLCacheImpl.java @@ -252,6 +252,7 @@ public class TSLCacheImpl implements ITSLCache { .setName_en_US(thingsModel.getModelName_en_US()) .setOrder(thingsModel.getModelOrder()) .setModelId(thingsModel.getModelId()) + .setModelId(thingsModel.getModelId()) .setConfig(thingsModel.getModbusConfig()); return JSONObject.toJSONString(dto); })); diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java index b76d6c5..34bf65f 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/domain/ThingsModel.java @@ -44,6 +44,8 @@ public class ThingsModel extends BaseEntity @ApiModelProperty("英文物模型名称") private String modelName_en_US; + private String group; + /** 产品ID */ @ApiModelProperty("产品ID") private Long productId; diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/ProductTypeEnum.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/ProductTypeEnum.java new file mode 100644 index 0000000..aba7322 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/ProductTypeEnum.java @@ -0,0 +1,43 @@ +package com.fastbee.iot.enums; + +public enum ProductTypeEnum { + + SOLAR_DEVICE(138, "太阳能供电设备"), + FLOW_METER_DEVICE(139, "流量计设备"), + DOOR_LOCK_DEVICE(140, "门锁控制设备"), + WENSHIDU_SHEBEI(4, "温湿度"); + + private String name; + private Integer type; + + + ProductTypeEnum(Integer type, String name) { + this.type = type; + this.name = name; + } + + public static ProductTypeEnum getName(Integer type) { + for (ProductTypeEnum scoreEnum : ProductTypeEnum.values()) { + if (scoreEnum.type.equals(type)) { + return scoreEnum; + } + } + return null; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/WaterFertilizerHttpEnum.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/WaterFertilizerHttpEnum.java new file mode 100644 index 0000000..03601d6 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/enums/WaterFertilizerHttpEnum.java @@ -0,0 +1,49 @@ +package com.fastbee.iot.enums; + +import com.fastbee.common.core.domain.CommonResult; + +public enum WaterFertilizerHttpEnum { + _08012101("08012101", "参数不足"), + _08010001("08010001", "设备不存在或云服务器不存在"), + _08010002("08010002", "设备不存在或云服务器不存在"), + _08012102("08012102", "私钥不正确"), + _08012103("08012103", "解密失败"), + _08012104("08012104", "超时过期"), + _08010003("08010003", "操作失败"), + _08012105("08012105", "操作失败"), + _08012106("08012106", "与设备通信失败"); + + private String name; + private String type; + + + WaterFertilizerHttpEnum(String type, String name) { + this.type = type; + this.name = name; + } + + public static WaterFertilizerHttpEnum getWaterFertilizerHttpEnum(String type) { + for (WaterFertilizerHttpEnum scoreEnum : WaterFertilizerHttpEnum.values()) { + if (scoreEnum.type.equals(type)) { + return scoreEnum; + } + } + return null; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/controller/HaiWeiController.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/controller/HaiWeiController.java new file mode 100644 index 0000000..630e86c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/controller/HaiWeiController.java @@ -0,0 +1,61 @@ +package com.fastbee.iot.haiwei.controller; + +import com.fastbee.common.core.domain.CommonResult; +import com.fastbee.common.utils.json.JsonUtils; +import com.fastbee.iot.haiwei.service.HaiWeiService; +import com.fastbee.iot.model.haiwei.CmdHaiWeiVo; +import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo; +import com.fastbee.iot.model.haiwei.HaiWeiVo; +import com.fastbee.iot.model.haiwei.dto.CmdHaiWeiDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@Validated +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@RestController +@RequestMapping("/haiwei/device") +@Api(tags = "海为设备") +@Slf4j +public class HaiWeiController { + @Resource + HaiWeiService haiWeiService; + + + /** + * 获取所有水肥设备 + */ + @GetMapping("/devices") + @ApiOperation("获取所有海为设备") + public CommonResult> getHaiWeiDevices() { + return haiWeiService.getHaiWeiDevices(); + } + + /** + * 获取农作物产量统计 + */ + @GetMapping("/cache/{deviceId}") + @ApiOperation("获取海为设备缓存信息") + public CommonResult getCache(@PathVariable("deviceId") Long deviceId) { + return haiWeiService.getCache(deviceId); + } + + /** + * 向grm设备下发指令 + */ + @ApiOperation("向海为设备下发指令") + @PostMapping("/cmd") + public CommonResult cmdDevices(@RequestBody CmdHaiWeiDto cmdHaiWeiDto) { + log.info("向海为设备下发指令:{}", JsonUtils.toJsonString(cmdHaiWeiDto)); + return haiWeiService.cmdDevices(cmdHaiWeiDto); + } + + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/HaiWeiService.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/HaiWeiService.java new file mode 100644 index 0000000..34abd82 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/HaiWeiService.java @@ -0,0 +1,18 @@ +package com.fastbee.iot.haiwei.service; + +import com.fastbee.common.core.domain.CommonResult; +import com.fastbee.iot.model.haiwei.CmdHaiWeiVo; +import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo; +import com.fastbee.iot.model.haiwei.HaiWeiVo; +import com.fastbee.iot.model.haiwei.dto.CmdHaiWeiDto; + +import java.util.List; + +public interface HaiWeiService { + + CommonResult> getHaiWeiDevices(); + + CommonResult getCache(Long deviceId); + + CommonResult cmdDevices(CmdHaiWeiDto cmdGrmDeviceDto); +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/impl/HaiWeiServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/impl/HaiWeiServiceImpl.java new file mode 100644 index 0000000..1b30d0e --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/haiwei/service/impl/HaiWeiServiceImpl.java @@ -0,0 +1,161 @@ +package com.fastbee.iot.haiwei.service.impl; + +import cn.hutool.core.bean.BeanUtil; + +import com.alibaba.fastjson.JSON; +import com.fastbee.common.core.domain.CommonResult; +import com.fastbee.common.core.redis.RedisCache; +import com.fastbee.common.utils.json.JsonUtils; +import com.fastbee.iot.cache.DeviceCacheConstants; +import com.fastbee.iot.cache.ITSLCache; +import com.fastbee.iot.domain.Device; +import com.fastbee.iot.enums.WaterFertilizerHttpEnum; +import com.fastbee.iot.haiwei.service.HaiWeiService; +import com.fastbee.iot.httpclient.HttpAPIController; +import com.fastbee.iot.httpclient.HttpResultDTO; +import com.fastbee.iot.mapper.DeviceMapper; +import com.fastbee.iot.model.ThingsModels.PropertyDto; +import com.fastbee.iot.model.haiwei.CmdHaiWeiVo; +import com.fastbee.iot.model.haiwei.CmdTagVo; +import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo; +import com.fastbee.iot.model.haiwei.HaiWeiVo; +import com.fastbee.iot.model.haiwei.bo.CmdHaiWeiBo; +import com.fastbee.iot.model.haiwei.dto.CmdHaiWeiDto; +import com.fastbee.iot.service.IDeviceService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.fastbee.iot.enums.ProductTypeEnum.*; + +@Service +@Slf4j +public class HaiWeiServiceImpl implements HaiWeiService { + @Resource + private IDeviceService iDeviceService; + @Resource + private RedisCache redisCache; + @Resource + DeviceMapper deviceMapper; + @Resource + private ITSLCache itslCache; + + @Override + public CommonResult> getHaiWeiDevices() { + Device device = new Device(); + device.setProductId(Long.valueOf(SOLAR_DEVICE.getType())); + List devices = iDeviceService.selectDeviceList(device); + device.setProductId(Long.valueOf(FLOW_METER_DEVICE.getType())); + List devices1 = iDeviceService.selectDeviceList(device); + device.setProductId(Long.valueOf(DOOR_LOCK_DEVICE.getType())); + List devices2 = iDeviceService.selectDeviceList(device); + devices.addAll(devices1); + devices.addAll(devices2); + List deviceVos = new ArrayList<>(); + for (Device device1 : devices) { + HaiWeiVo haiWeiVo = new HaiWeiVo(); + BeanUtil.copyProperties(device1, haiWeiVo); + deviceVos.add(haiWeiVo); + } + return CommonResult.success(deviceVos); + } + + @Override + public CommonResult getCache(Long deviceId) { + HaiWeiDeviceInfoVo haiWeiDeviceInfoVo = + redisCache.getCacheObject(DeviceCacheConstants.getDeviceLogKey(deviceId.toString())); + if (haiWeiDeviceInfoVo != null) { + if (null != haiWeiDeviceInfoVo.getReceiveTime()) { + //5分钟未更新设备信息,任务设备离线 + if (System.currentTimeMillis() - haiWeiDeviceInfoVo.getReceiveTime().getTime() >= 1000 * 60 * 5) { + haiWeiDeviceInfoVo.setOnline(false); + } + } else { + haiWeiDeviceInfoVo.setOnline(false); + } + } + return CommonResult.success(haiWeiDeviceInfoVo); + } + + @Override + public CommonResult cmdDevices(CmdHaiWeiDto cmdHaiWeiDto) { + String url = "https://cloud.haiwell.com/api/project/machine/datagroup/setTagsValue"; + Device deviceEntity = deviceMapper.selectDeviceByDeviceId(cmdHaiWeiDto.getDeviceId()); + CmdHaiWeiVo cmdWaterFertilizerVo = new CmdHaiWeiVo(); + cmdWaterFertilizerVo.setDeviceId(cmdHaiWeiDto.getDeviceId()); + List cmdTagVos = new ArrayList<>(); + Map devParams = getDevParams(deviceEntity); + CmdHaiWeiBo cmdWaterFertilizerBo = new CmdHaiWeiBo(); + cmdWaterFertilizerBo.setAccount(devParams.get("account")); + cmdWaterFertilizerBo.setMachineCode(devParams.get("machineCode")); + cmdWaterFertilizerBo.setPrivateKey(devParams.get("privateKey")); + cmdWaterFertilizerBo.setWebapiKey(devParams.get("webapiKey")); + //获取该产品下功能模型 + com.alibaba.fastjson2.JSONObject thingsModelObject = + com.alibaba.fastjson2.JSONObject.parseObject(itslCache.getCacheThingsModelByProductId(deviceEntity.getProductId())); + com.alibaba.fastjson2.JSONArray thingsList = thingsModelObject.getJSONArray("properties"); + List properties = thingsList.toList(PropertyDto.class); + Map> stringListMap = properties.stream().collect(Collectors.groupingBy(PropertyDto::getId)); + Map tags = new HashMap<>(); + String group = null; + List propertyDtos = stringListMap.get(cmdHaiWeiDto.getNameEn()); + if (StringUtils.isEmpty(group)) { + group = propertyDtos.get(0).getGroup(); + String[] split = cmdHaiWeiDto.getValue().split("\\."); + tags.put(cmdHaiWeiDto.getNameEn(), split[0]); + cmdWaterFertilizerBo.setGroupTag(group); + cmdWaterFertilizerBo.setTags(tags); + + HttpResultDTO duhttpResultDTO = HttpAPIController.doPostWithJsonParamAndHeaders(url, + JsonUtils.toJsonString(cmdWaterFertilizerBo), new HashMap<>()); + group = null; + tags.clear(); + if (null != duhttpResultDTO && duhttpResultDTO.getCode() == 200) { + Object object = JSON.parse(duhttpResultDTO.getBody()); + //请求报错 + if (JsonUtils.toJsonString((Map) object).contains("error")) { + Object map = ((Map) object).get("error"); + Object map1 = ((Map) map).get("code"); + WaterFertilizerHttpEnum waterFertilizerHttpEnum = WaterFertilizerHttpEnum.getWaterFertilizerHttpEnum((String) map1); + return CommonResult.error(500,waterFertilizerHttpEnum.getName()); + } else { + Object map = ((Map) object).get("result"); + Object map1 = ((Map) map).get("data"); + Map a = (Map) map1; + for (String s : a.keySet()) { + CmdTagVo cmdTagVo = new CmdTagVo(); + cmdTagVo.setNameEn(s); + Integer s1 = (Integer) a.get(s); + cmdTagVo.setResult(s1.toString()); + cmdTagVos.add(cmdTagVo); + } + } + } else { + return CommonResult.error(500,"Http请求异常"); + } + + } + cmdWaterFertilizerVo.setCmdTagVos(cmdTagVos); + return CommonResult.success(cmdWaterFertilizerVo); + } + + public Map getDevParams(Device device) { + Map devData = new HashMap<>(); + devData.put("machineCode", device.getSerialNumber()); + String remark = device.getRemark(); + String[] split = remark.split(","); + for (String s : split) { + String[] split1 = s.split("_"); + devData.put(split1[0], split1[1]); + } + return devData; + } + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpAPIController.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpAPIController.java new file mode 100644 index 0000000..b024dc6 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpAPIController.java @@ -0,0 +1,445 @@ +package com.fastbee.iot.httpclient; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.fastbee.common.utils.StringUtils; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.*; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Component +public class HttpAPIController { + + private static CloseableHttpClient httpClient; + + /** + * 信任SSL证书 + */ + static { + try { + SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL) + .loadTrustMaterial((x, y) -> true).build(); + /** + * 一、连接超时:connectionTimeout-->指的是连接一个url的连接等待时间 + * 二、读取数据超时:SocketTimeout-->指的是连接上一个url,获取response的返回等待时间 + */ + RequestConfig config = RequestConfig.custom().setConnectTimeout(500000).setSocketTimeout(500000).build(); + httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext) + .setSSLHostnameVerifier((x, y) -> true).build(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Autowired + private RequestConfig config; + + /** + * @description GET---不含参 + * @param url + * @return com.mark.dc2.DTO.HttpResultDTO + * @author Mario + * @date 2019/7/23 9:02 + */ + /*public HttpResultDTO doGet(String url) throws Exception { + // 声明 http get 请求 + HttpGet httpGet = new HttpGet(url); + // 装载配置信息 + httpGet.setConfig(config); + // 允许重定向 + httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true); + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpGet); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + }*/ + + /** + * @description GET---含请求头 + * @param url + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @author Mario + * @date 2019/7/23 9:04 + */ + /* public HttpResultDTO doGetWithHeaders(String url, Map headers) throws Exception { + // 声明 http get 请求 + HttpGet httpGet = new HttpGet(url); + // 装载配置信息 + httpGet.setConfig(config); + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpGet.addHeader(key,value); + } + } + // 允许重定向 + httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true); + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpGet); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + }*/ + + /** + * @description GET---含Map请求参数 + * @param url + * @param mapParams + * @return com.mark.dc2.DTO.HttpResultDTO + * @author Mario + * @date 2019/7/23 9:06 + */ + /*public HttpResultDTO doGetWithParams(String url, Map mapParams) throws Exception { + // 包装URL + URIBuilder uriBuilder = new URIBuilder(url); + if (mapParams != null) { + // 遍历map,拼接请求参数 + for (Map.Entry entry : mapParams.entrySet()) { + uriBuilder.setParameter(entry.getKey(), entry.getValue().toString()); + } + } + // 调用不带参数的get请求 + return this.doGet(uriBuilder.build().toString()); + }*/ + + /** + * @param url + * @param jsonParam + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description POST---含参(请求路径、JSON参数串、请求头) + * @author Mario + * @date 2019/7/23 9:20 + */ + public static HttpResultDTO doPostWithJsonParamAndHeaders(String url, String jsonParam, Map headers) { + // 声明httpPost请求 + HttpPost httpPost = new HttpPost(url); + + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpPost.addHeader(key, value); + } + } + + // 设置以Json数据方式发送 + StringEntity stringEntity = new StringEntity(jsonParam, "utf-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + + // 发起请求 + CloseableHttpResponse response = null; + try { + response = httpClient.execute(httpPost); + } catch (IOException e) { + throw new RuntimeException(e); + } + + try { + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + /** + * @description POST--不含参 + * @param url + * @return com.mark.dc2.DTO.HttpResultDTO + * @author Mario + * @date 2019/7/23 9:14 + */ + /*public HttpResultDTO doPost(String url) throws Exception { + // 声明httpPost请求 + HttpPost httpPost = new HttpPost(url); + + // 加入配置信息 + httpPost.setConfig(config); + + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpPost); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + }*/ + + /** + * @description POST---含参 + * @param url + * @param params + * @return com.mark.dc2.DTO.HttpResultDTO + * @author Mario + * @date 2019/7/23 9:16 + */ + /*public HttpResultDTO doPostWithParams(String url, Map params) throws Exception { + // 声明httpPost请求 + HttpPost httpPost = new HttpPost(url); + // 加入配置信息 + httpPost.setConfig(config); + // 判断map是否为空,不为空则进行遍历,封装from表单对象 + if (params != null) { + List list = new ArrayList(); + for (Map.Entry entry : params.entrySet()) { + list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); + } + // 构造from表单对象 + UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8"); + // 把表单放到post里 + httpPost.setEntity(urlEncodedFormEntity); + } + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpPost); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + }*/ + + /** + * @param url + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description POST---含请求头 + * @author Mario + * @date 2019/7/23 9:17 + */ + /*public HttpResultDTO doPostWithHeaders(String url, Map headers) throws Exception { + // 声明httpPost请求 + HttpPost httpPost = new HttpPost(url); + // 加入配置信息 + httpPost.setConfig(config); + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpPost.addHeader(key,value); + } + } + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpPost); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + }*/ + public static HttpResultDTO doGetWithJsonParamAndHeaders(String url, String jsonParam, Map headers) throws Exception { + // 声明httpPost请求 + HttpClient httpClient = HttpClientBuilder.create().build(); + // Get请求 + URIBuilder uriBuilder = new URIBuilder(url); + if (StringUtils.isNotEmpty(jsonParam)) { + List nameValuePairList = json2NameValuePairList(JSON.parseObject(jsonParam)); + uriBuilder.setParameters(nameValuePairList); + } + HttpGet httpGet = new HttpGet(uriBuilder.build()); + // 设置Header + httpGet.setHeader("Content-Type", "application/json"); + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpGet.addHeader(key, value); + } + HttpResponse response1 = httpClient.execute(httpGet); + return new HttpResultDTO(response1.getStatusLine().getStatusCode(), EntityUtils.toString( + response1.getEntity(), "UTF-8")); + } + + private static List json2NameValuePairList(JSONObject params) { + if (params != null && !params.isEmpty()) { + List list = new ArrayList(); + for (Map.Entry entry : params.entrySet()) { + if (entry.getValue() != null) { + String value = String.valueOf(entry.getValue()); + list.add(new BasicNameValuePair(entry.getKey(), value)); + } + } + return list; + } + return null; + } + + /** + * @param url + * @param jsonParam + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description PUT---含参(请求路径、JSON参数串、请求头) + * @author Mario + * @date 2019/7/23 9:32 + */ + public static HttpResultDTO doPutWithJsonAndHeaders(String url, String jsonParam, Map headers) throws Exception { + // 声明httpPut请求 + HttpPut httpPut = new HttpPut(url); + + //设置header + httpPut.setHeader("Content-type", "application/json"); + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpPut.setHeader(entry.getKey(), entry.getValue()); + } + } + + //组织请求参数 + if (StringUtils.isNotEmpty(jsonParam)) { + StringEntity stringEntity = new StringEntity(jsonParam, "utf-8"); + httpPut.setEntity(stringEntity); + } + + // 发起请求 + CloseableHttpResponse response = httpClient.execute(httpPut); + + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + } + + /** + * @param url + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description DELETE---含参(请求路径、请求头) + * @author Mario + * @date 2019/7/23 9:37 + */ + public static HttpResultDTO doDeleteWithHeaders(String url, Map headers) throws Exception { + // 声明httpDelete请求 + HttpDelete httpDelete = new HttpDelete(url); + + //设置header + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpDelete.setHeader(entry.getKey(), entry.getValue()); + } + } + // 发起请求 + CloseableHttpResponse response = httpClient.execute(httpDelete); + + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + + } + + /** + * @param url + * @param mapParams + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description GET---含Map请求参数且含请求头 + * @author Mario + * @date 2019/7/23 9:08 + */ + public HttpResultDTO doGetWithParamsAndHeaders(String url, Map mapParams, + Map headers) throws Exception { + // 包装请求行 + if (mapParams != null) { + // 包装URL + URIBuilder uriBuilder = new URIBuilder(url); + // 遍历map,拼接请求参数 + for (Map.Entry entry : mapParams.entrySet()) { + uriBuilder.setParameter(entry.getKey(), entry.getValue().toString()); + } + // 新的请求行 + url = uriBuilder.build().toString(); + } + // 声明 http get 请求 + HttpGet httpGet = new HttpGet(url); + + // 装载配置信息 + httpGet.setConfig(config); + + // 允许重定向 + httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); + + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpGet.addHeader(key, value); + } + } + // 发起请求 + CloseableHttpResponse response = this.httpClient.execute(httpGet); + // 返回响应代码与内容 + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + } + + /** + * @param url + * @param mapParams + * @param headers + * @return com.mark.dc2.DTO.HttpResultDTO + * @description POST---含参(请求路径、Map参数、请求头) + * @author Mario + * @date 2019/7/23 9:22 + */ + public HttpResultDTO doPostWithParamsAndHeaders(String url, Map mapParams, Map headers) { + // 声明httpPost请求 + HttpPost httpPost = new HttpPost(url); + // 加入配置信息 + httpPost.setConfig(config); + + // 判断map是否为空,不为空则进行遍历,封装from表单对象 + if (mapParams != null) { + List list = new ArrayList(); + for (Map.Entry entry : mapParams.entrySet()) { + list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); + } + // 构造from表单对象 + UrlEncodedFormEntity urlEncodedFormEntity = null; + try { + urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + + // 把表单放到post里 + httpPost.setEntity(urlEncodedFormEntity); + } + + // 设置请求头 + if (headers != null) { + for (String key : headers.keySet()) { + String value = headers.get(key).toString(); + httpPost.addHeader(key, value); + } + } + + // 发起请求 + CloseableHttpResponse response = null; + try { + response = this.httpClient.execute(httpPost); + } catch (IOException e) { + throw new RuntimeException(e); + } + try { + return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString( + response.getEntity(), "UTF-8")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpClientConfig.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpClientConfig.java new file mode 100644 index 0000000..691f7a5 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpClientConfig.java @@ -0,0 +1,103 @@ +package com.fastbee.iot.httpclient; + +import org.apache.http.client.config.RequestConfig; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HttpClientConfig { + @Value("${http.maxTotal}") + private Integer maxTotal; + + @Value("${http.defaultMaxPerRoute}") + private Integer defaultMaxPerRoute; + + @Value("${http.connectTimeout}") + private Integer connectTimeout; + + @Value("${http.connectionRequestTimeout}") + private Integer connectionRequestTimeout; + + @Value("${http.socketTimeout}") + private Integer socketTimeout; + + @Value("${http.staleConnectionCheckEnabled}") + private boolean staleConnectionCheckEnabled; + + /** + * 首先实例化一个连接池管理器,设置最大连接数、并发连接数 + * + * @return + */ + @Bean(name = "httpClientConnectionManager") + public PoolingHttpClientConnectionManager getHttpClientConnectionManager() { + PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager(); + //最大连接数 + httpClientConnectionManager.setMaxTotal(maxTotal); + //并发数 + httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); + return httpClientConnectionManager; + } + + /** + * 实例化连接池,设置连接池管理器。 + * 这里需要以参数形式注入上面实例化的连接池管理器 + * + * @param httpClientConnectionManager + * @return + */ + @Bean(name = "httpClientBuilder") + public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) { + + //HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象 + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + + httpClientBuilder.setConnectionManager(httpClientConnectionManager); + + return httpClientBuilder; + } + + /** + * 注入连接池,用于获取httpClient + * + * @param httpClientBuilder + * @return + */ + @Bean + public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) { + return httpClientBuilder.build(); + } + + /** + * Builder是RequestConfig的一个内部类 + * 通过RequestConfig的custom方法来获取到一个Builder对象 + * 设置builder的连接信息 + * 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置 + * + * @return + */ + @Bean(name = "builder") + public RequestConfig.Builder getBuilder() { + RequestConfig.Builder builder = RequestConfig.custom(); + return builder.setConnectTimeout(connectTimeout) + .setConnectionRequestTimeout(connectionRequestTimeout) + .setSocketTimeout(socketTimeout) + .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled); + } + + /** + * 使用builder构建一个RequestConfig对象 + * + * @param builder + * @return + */ + @Bean + public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) { + return builder.build(); + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpResultDTO.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpResultDTO.java new file mode 100644 index 0000000..2d5f253 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/HttpResultDTO.java @@ -0,0 +1,15 @@ +package com.fastbee.iot.httpclient; + +import lombok.Data; +import lombok.NonNull; + +@Data +public class HttpResultDTO { + // 响应码 + @NonNull + private Integer code; + + // 响应体 + @NonNull + private String body; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/IdleConnectionEvictor.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/IdleConnectionEvictor.java new file mode 100644 index 0000000..3a19e94 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/httpclient/IdleConnectionEvictor.java @@ -0,0 +1,41 @@ +package com.fastbee.iot.httpclient; + +import org.apache.http.conn.HttpClientConnectionManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class IdleConnectionEvictor extends Thread { + @Autowired + private HttpClientConnectionManager connMgr; + + private volatile boolean shutdown; + + public IdleConnectionEvictor() { + super(); + super.start(); + } + + @Override + public void run() { + try { + while (!shutdown) { + synchronized (this) { + wait(5000); + // 关闭失效的连接 + connMgr.closeExpiredConnections(); + } + } + } catch (InterruptedException ex) { + // 结束 + } + } + + //关闭清理无效连接的线程 + public void shutdown() { + shutdown = true; + synchronized (this) { + notifyAll(); + } + } +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java index 60efcaf..539973a 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/DeviceLogMapper.java @@ -67,6 +67,13 @@ public interface DeviceLogMapper */ public int saveBatch(@Param("list") List list); + /** + * 创建数据库表 + * + * @param tableName 表名称 + */ + int createTable(@Param("tableName") String tableName, @Param("id") Long id); + /** * 修改设备日志 * diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TableMapper.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TableMapper.java new file mode 100644 index 0000000..a837b13 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/mapper/TableMapper.java @@ -0,0 +1,22 @@ +package com.fastbee.iot.mapper; + +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public interface TableMapper { + + /** + * 查询collectstatusPmon + * + * @param tableName 表名 + * @return collectstatusPmon + */ + public void createTable(String tableName); + + + public String getTableByName(String tableName); + + List getTableNameList(String[] tableNames); +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/PropertyDto.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/PropertyDto.java index 9be0720..ffdc483 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/PropertyDto.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/PropertyDto.java @@ -17,6 +17,7 @@ import java.util.List; @Accessors(chain = true) public class PropertyDto { + /** 物模型唯一标识符 */ private String id; /** 物模型名称 */ @@ -67,4 +68,8 @@ public class PropertyDto private String parseType; private ModbusConfig config; + + private String group; + + private Long modelId; } diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelValueItem.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelValueItem.java index 39c6882..f775b64 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelValueItem.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelValueItem.java @@ -99,6 +99,9 @@ public class ThingsModelValueItem { private Long modelId; + private String group; + + /** * 上报时间 diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelsDto.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelsDto.java deleted file mode 100644 index 12cd168..0000000 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/ThingsModels/ThingsModelsDto.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.fastbee.iot.model.ThingsModels; - -import java.util.ArrayList; -import java.util.List; - -/** - * 产品分类的Id和名称输出 - * - * @author kerwincui - * @date 2021-12-16 - */ -public class ThingsModelsDto -{ - public ThingsModelsDto(){ - properties=new ArrayList<>(); - functions=new ArrayList<>(); - events=new ArrayList<>(); - } - - /** 属性 */ - private List properties; - /** 功能 */ - private List functions; - /** 事件 */ - private List events; - - public List getProperties() { - return properties; - } - - public void setProperties(List properties) { - this.properties = properties; - } - - public List getFunctions() { - return functions; - } - - public void setFunctions(List functions) { - this.functions = functions; - } - - public List getEvents() { - return events; - } - - public void setEvents(List events) { - this.events = events; - } -} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdHaiWeiVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdHaiWeiVo.java new file mode 100644 index 0000000..e15b55c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdHaiWeiVo.java @@ -0,0 +1,22 @@ +package com.fastbee.iot.model.haiwei; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 向grm设备下发指令 + */ +@Data +@ApiModel(description = "向水肥设备下发指令") +public class CmdHaiWeiVo { + + @ApiModelProperty(value = "设备id") + private Long deviceId; + + @ApiModelProperty("属性") + private List cmdTagVos; + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdTagVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdTagVo.java new file mode 100644 index 0000000..d78f1c9 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/CmdTagVo.java @@ -0,0 +1,19 @@ +package com.fastbee.iot.model.haiwei; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 向grm设备下发指令 + */ +@Data +@ApiModel(description = "属性") +public class CmdTagVo { + + @ApiModelProperty("属性英文名") + private String nameEn; + + @ApiModelProperty(value = "写值结果;1为成功,其他为失败") + private String result; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiDeviceInfoVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiDeviceInfoVo.java new file mode 100644 index 0000000..0d0ffce --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiDeviceInfoVo.java @@ -0,0 +1,35 @@ +package com.fastbee.iot.model.haiwei; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Data +@ApiModel(description = "海为设备") +public class HaiWeiDeviceInfoVo { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("设备ID") + private Long deviceId; + + @ApiModelProperty("设备是否在线") + private Boolean online = false; + + @ApiModelProperty("设备编号") + private String serialNumber; + + @ApiModelProperty("设备名称") + private String deviceName; + + @ApiModelProperty("属性值,key为显示分组") + private List propertyList; + + @ApiModelProperty("设备接收时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date receiveTime; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiHttpVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiHttpVo.java new file mode 100644 index 0000000..3cce1a1 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiHttpVo.java @@ -0,0 +1,23 @@ +package com.fastbee.iot.model.haiwei; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 设备属性值 + */ +@Data +public class HaiWeiHttpVo { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("物模型ID") + private Long modelId; + + @ApiModelProperty("组名称") + private String group; + + @ApiModelProperty("属性中文名") + private String nameCn; + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiPropertyVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiPropertyVo.java new file mode 100644 index 0000000..39411ee --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiPropertyVo.java @@ -0,0 +1,39 @@ +package com.fastbee.iot.model.haiwei; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.HashMap; + + +/** + * 设备属性值 + */ +@Data +@ApiModel(description = "海为属性值") +public class HaiWeiPropertyVo { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("物模型ID") + private Long modelId; + + @ApiModelProperty("属性中文名") + private String nameCn; + + @ApiModelProperty("属性英文名") + private String nameEn; + + @ApiModelProperty("值对应的枚举值") + private HashMap enumMap; + + @ApiModelProperty("值") + private Object value; + + @ApiModelProperty("单位") + private String unit; + + @ApiModelProperty("加单位的值") + private String valueAndUnit; + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiVo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiVo.java new file mode 100644 index 0000000..c7f525d --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/HaiWeiVo.java @@ -0,0 +1,137 @@ +package com.fastbee.iot.model.haiwei; + +import com.fastbee.common.annotation.Excel; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +@ApiModel(description = "设备") +public class HaiWeiVo { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("设备ID") + private Long deviceId; + + private String qvyvma; + + @ApiModelProperty("设备名称") + private String deviceName; + + @ApiModelProperty("产品分类ID") + private Long categoryId; + + @Excel(name = "设备参数") + private String devParams; + + private Date tenantTime; + + private Date userTime; + + /** 产品ID */ + @ApiModelProperty("产品ID") + private Long productId; + + /** 产品名称 */ + @ApiModelProperty("产品名称") + private String productName; + + /** 用户ID */ + @ApiModelProperty("用户ID") + private Long userId; + + /** 用户昵称 */ + @ApiModelProperty("用户昵称") + private String userName; + + /** 租户ID */ + @ApiModelProperty("租户ID") + private Long tenantId; + + /** 租户名称 */ + @ApiModelProperty("租户名称") + private String tenantName; + + /** 设备编号 */ + @ApiModelProperty("设备编号") + private String serialNumber; + + /** 设备类型(1-直连设备、2-网关设备、3-监控设备) */ + @ApiModelProperty("设备类型(1-直连设备、2-网关设备、3-监控设备)") + private Integer deviceType; + + /** 设备状态(1-未激活,2-禁用,3-在线,4-离线) */ + @ApiModelProperty("设备状态(1-未激活,2-禁用,3-在线,4-离线)") + private Integer status; + + /** 设备影子 */ + @ApiModelProperty("是否启用设备影子(0=禁用,1=启用)") + private Integer isShadow; + + /** 设备所在地址 */ + @ApiModelProperty("设备所在地址") + private String networkAddress; + + /** 设备入网IP */ + @ApiModelProperty("设备入网IP") + private String networkIp; + + /** 设备经度 */ + @ApiModelProperty("设备经度") + private BigDecimal longitude; + + /** 设备纬度 */ + @ApiModelProperty("设备纬度") + private BigDecimal latitude; + + /** 激活时间 */ + @ApiModelProperty("激活时间") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date activeTime; + + /** 子设备网关编号 */ + @ApiModelProperty("子设备网关编号") + private String gwDevCode; + + /** 物模型值 */ + @ApiModelProperty("物模型值") + private String thingsModelValue; + + /** 图片地址 */ + @ApiModelProperty("图片地址") + private String imgUrl; + + /** 是否自定义位置 **/ + @ApiModelProperty("定位方式(1=ip自动定位,2=设备定位,3=自定义)") + private Integer locationWay; + + /** 设备摘要 **/ + @ApiModelProperty("设备摘要") + private String summary; + + private String isView; + + private String viewId; + + @ApiModelProperty("厂家id") + private Long factoryId; + + + @ApiModelProperty("是否是模拟设备") + private Integer isSimulate; + + @ApiModelProperty("子设备地址") + private Integer slaveId; + + @ApiModelProperty("删除标志") + private String delFlag; + + private Integer devType; + + private Long projectDikuaiId; + +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/CmdHaiWeiBo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/CmdHaiWeiBo.java new file mode 100644 index 0000000..8b3abc6 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/CmdHaiWeiBo.java @@ -0,0 +1,15 @@ +package com.fastbee.iot.model.haiwei.bo; + +import lombok.Data; + +import java.util.Map; + +@Data +public class CmdHaiWeiBo { + String account; + String machineCode; + String privateKey; + String webapiKey; + String groupTag; + Map tags; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/HaiWeiBo.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/HaiWeiBo.java new file mode 100644 index 0000000..a8d0263 --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/bo/HaiWeiBo.java @@ -0,0 +1,13 @@ +package com.fastbee.iot.model.haiwei.bo; + +import lombok.Data; + +@Data +public class HaiWeiBo { + String account; + String machineCode; + String privateKey; + String webapiKey; + String groupTag; + String[] tags; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/dto/CmdHaiWeiDto.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/dto/CmdHaiWeiDto.java new file mode 100644 index 0000000..d47e2da --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/model/haiwei/dto/CmdHaiWeiDto.java @@ -0,0 +1,24 @@ +package com.fastbee.iot.model.haiwei.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 向grm设备下发指令 + */ +@Data +@ApiModel(description = "向海为设备下发指令") +public class CmdHaiWeiDto { + + @ApiModelProperty(value = "设备id", required = true) + private Long deviceId; + + @ApiModelProperty(value = "属性英文名", required = true) + private String nameEn; + + @ApiModelProperty(value = "属性对应值", required = true) + private String value; +} diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java index 66c3224..1f1c7ff 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/ILogService.java @@ -27,6 +27,8 @@ public interface ILogService { /** 保存设备日志 **/ int saveDeviceLog(DeviceLog deviceLog); + int saveDeviceLogList(List deviceLogEntityList); + /** * 批量保存日志 */ diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java index 5e4959d..cb562e8 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/MySqlLogServiceImpl.java @@ -3,6 +3,7 @@ package com.fastbee.iot.tdengine.service.impl; import com.fastbee.common.utils.DateUtils; import com.fastbee.iot.domain.Device; import com.fastbee.iot.domain.DeviceLog; +import com.fastbee.iot.mapper.TableMapper; import com.fastbee.iot.model.DeviceStatistic; import com.fastbee.iot.model.HistoryModel; import com.fastbee.iot.model.ThingsModelLogCountVO; @@ -11,7 +12,10 @@ import com.fastbee.iot.tdengine.service.ILogService; import com.fastbee.iot.mapper.DeviceLogMapper; import com.fastbee.iot.model.MonitorModel; import com.fastbee.iot.tdengine.service.model.TdLogDto; +import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Resource; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -24,12 +28,40 @@ import java.util.stream.Collectors; */ public class MySqlLogServiceImpl implements ILogService { + private String tableName = "iot_device_log_"; + private DeviceLogMapper deviceLogMapper; + @Resource + private TableMapper tableMapper; + public MySqlLogServiceImpl(DeviceLogMapper _deviceLogMapper){ this.deviceLogMapper=_deviceLogMapper; } + /** + * 分库存入 + * @param deviceLogEntityList + */ + @Override + public int saveDeviceLogList(List deviceLogEntityList){ + if(deviceLogEntityList.size() > 0){ + //DeviceLog deviceLogEntity = deviceLogEntityList.get(0); + //Date createTime = deviceLogEntity.getCreateTime(); + //String ym = DateUtils.parseDateToStr(DateUtils.YYYYMM,createTime); + //String ymTableName = tableName + ym; + //if(null == tableMapper.getTableByName(ymTableName)){ + // deviceLogMapper.createTable(ymTableName,1L); + //} + //List stringList = deviceLogEntityList.stream() + // .map(a->a.getSerialNumber()) + // .collect(Collectors.toList()); + //deviceMapper.batchChangeOnline(stringList); + //return deviceLogMapper.saveBatch(deviceLogEntityList,ymTableName); + } + return 0; + } + /*** * 新增设备日志 * @return diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java index 30a6af5..5453f88 100644 --- a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/tdengine/service/impl/TdengineLogServiceImpl.java @@ -44,6 +44,11 @@ public class TdengineLogServiceImpl implements ILogService { this.dbName=_tDengineConfig.getDbName(); } + @Override + public int saveDeviceLogList(List deviceLogEntityList) { + return 0; + } + /*** * 新增设备日志 * @return diff --git a/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/timer/QxtrTask.java b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/timer/QxtrTask.java new file mode 100644 index 0000000..ce6051c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/timer/QxtrTask.java @@ -0,0 +1,224 @@ +package com.fastbee.iot.timer;//package com.fastbee.farming; + +import com.fastbee.common.core.redis.RedisCache; +import com.fastbee.common.core.redis.RedisKeyBuilder; +import com.fastbee.common.utils.DateUtils; +import com.fastbee.common.utils.json.JsonUtils; +import com.fastbee.iot.cache.DeviceCacheConstants; +import com.fastbee.iot.cache.ITSLCache; +import com.fastbee.iot.domain.Device; +import com.fastbee.iot.domain.DeviceLog; +import com.fastbee.iot.httpclient.HttpAPIController; +import com.fastbee.iot.httpclient.HttpResultDTO; +import com.fastbee.iot.model.ThingsModels.PropertyDto; +import com.fastbee.iot.model.haiwei.bo.HaiWeiBo; +import com.fastbee.iot.model.haiwei.HaiWeiDeviceInfoVo; +import com.fastbee.iot.model.haiwei.HaiWeiPropertyVo; +import com.fastbee.iot.service.IDeviceService; +import com.fastbee.iot.tdengine.service.ILogService; +import com.fastbee.iot.tdengine.service.model.TdLogDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static com.fastbee.iot.enums.ProductTypeEnum.*; + +@Component("qxtrTask") +@Slf4j +public class QxtrTask { + + @Autowired + private IDeviceService iDeviceService; + @Resource + private ITSLCache itslCache; + @Autowired + private ILogService iLogService; + @Resource + RedisCache redisCache; + + private static Pattern pattern = Pattern.compile("[-+]?[0-9]+(\\.[0-9]+)?$"); + + /** + * 定时任务 新增太阳能设备 + */ + public void getSolarDeviceFromHttp() throws Exception { + log.info("定时任务,新增 太阳能设备 数据"); + Device device = new Device(); + device.setProductId(Long.valueOf(SOLAR_DEVICE.getType())); + List devices = iDeviceService.selectDeviceList(device); + getDeviceInfo(Long.valueOf(SOLAR_DEVICE.getType()), devices); + } + + /** + * 定时任务 流量计设备 + */ + public void getFlowMeterDeviceFromHttp() throws Exception { + log.info("定时任务,新增 流量计设备 数据"); + Device device = new Device(); + device.setProductId(Long.valueOf(FLOW_METER_DEVICE.getType())); + List devices = iDeviceService.selectDeviceList(device); + getDeviceInfo(Long.valueOf(FLOW_METER_DEVICE.getType()), devices); + } + + /** + * 定时任务 门锁控制设备 + */ + public void getDoorLockDeviceFromHttp() throws Exception { + log.info("定时任务,新增 门锁控制设备 数据"); + Device device = new Device(); + device.setProductId(Long.valueOf(DOOR_LOCK_DEVICE.getType())); + List devices = iDeviceService.selectDeviceList(device); + getDeviceInfo(Long.valueOf(DOOR_LOCK_DEVICE.getType()), devices); + } + + /*//////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + public void getDeviceInfo(Long productId, List devices) { + Date createTime = new Date(); + getDeviceInfoFromHttp(productId, devices, createTime); + } + + public void getDeviceInfoFromHttp(Long productId, List devices, Date createTime) { + String url = "https://cloud.haiwell.com/api/project/machine/datagroup/getTagsValue"; + com.alibaba.fastjson2.JSONObject thingsModelObject = + com.alibaba.fastjson2.JSONObject.parseObject(itslCache.getCacheThingsModelByProductId(productId)); + com.alibaba.fastjson2.JSONArray thingsList = thingsModelObject.getJSONArray("properties"); + List properties = thingsList.toList(PropertyDto.class); + Map> stringListMap = properties.stream().collect(Collectors.groupingBy(PropertyDto::getGroup)); + for (Device device : devices) { + try { + Map devParams = getDevParams(device); + HaiWeiBo haiWeiBo = new HaiWeiBo(); + haiWeiBo.setAccount(devParams.get("account")); + haiWeiBo.setMachineCode(devParams.get("machineCode")); + haiWeiBo.setPrivateKey(devParams.get("privateKey")); + haiWeiBo.setWebapiKey(devParams.get("webapiKey")); + Map mapAll = new HashMap<>(); + for (String group : stringListMap.keySet()) { + List propertyDtos = stringListMap.get(group); + haiWeiBo.setGroupTag(group); + String[] tags = new String[propertyDtos.size()]; + for (int i = 0; i < propertyDtos.size(); i++) { + tags[i] = propertyDtos.get(i).getId(); + } + haiWeiBo.setTags(tags); + HttpResultDTO duhttpResultDTO = HttpAPIController.doPostWithJsonParamAndHeaders(url, JsonUtils.toJsonString(haiWeiBo), + new HashMap<>()); + if (null != duhttpResultDTO && duhttpResultDTO.getCode() == 200) { + Object object = com.alibaba.fastjson.JSON.parse(duhttpResultDTO.getBody()); //先转换成Object + Object map = ((Map) object).get("result"); + if(!ObjectUtils.isEmpty(map)) { + Object map1 = ((Map) map).get("data"); + mapAll.putAll((Map) map1); + } + } + } + setCacheOrDb(device, mapAll, properties); + } catch (Exception e) { + log.error("getDeviceInfoFromHttp error", e); + } + } + } + + private void setCacheOrDb(Device deviceEntity, Map map, List propertyDtos) { + HaiWeiDeviceInfoVo haiWeiDeviceInfoVo = new HaiWeiDeviceInfoVo(); + List propertyList = new ArrayList<>(); + haiWeiDeviceInfoVo.setDeviceId(deviceEntity.getDeviceId()); + haiWeiDeviceInfoVo.setSerialNumber(deviceEntity.getSerialNumber()); + haiWeiDeviceInfoVo.setDeviceName(deviceEntity.getDeviceName()); + haiWeiDeviceInfoVo.setReceiveTime(new Date()); + haiWeiDeviceInfoVo.setOnline(true); + + for (PropertyDto propertyDto : propertyDtos) { + HaiWeiPropertyVo haiWeiPropertyVo = new HaiWeiPropertyVo(); + haiWeiPropertyVo.setModelId(Long.valueOf(propertyDto.getModelId())); + haiWeiPropertyVo.setNameCn(propertyDto.getName()); + haiWeiPropertyVo.setNameEn(propertyDto.getId()); + com.alibaba.fastjson2.JSONObject datatype = propertyDto.getDatatype(); + Object type = datatype.get("type"); + //值类型如果是枚举 + if ("enum".equals(type)) { + ArrayList enumList = (ArrayList) datatype.get("enumList"); + HashMap a = new HashMap<>(); + for (Map map1 : enumList) { + a.put((String) map1.get("value"), (String) map1.get("text")); + } + haiWeiPropertyVo.setEnumMap(a); + } else { + haiWeiPropertyVo.setUnit((String) datatype.get("unit")); + } + String s = map.get(propertyDto.getId()); + //拿到属性值 + if (!ObjectUtils.isEmpty(s)) { + //值为数字,取小数点后两位 + boolean matches = pattern.matcher(s).matches(); + if (matches) { + BigDecimal roundedNumber = new BigDecimal(Double.valueOf(s)).setScale(2, BigDecimal.ROUND_HALF_UP); + s = String.valueOf(roundedNumber); + } + haiWeiPropertyVo.setValue(s); + } else { + haiWeiPropertyVo.setValue(""); + } + haiWeiPropertyVo.setValueAndUnit(haiWeiPropertyVo.getValue() + haiWeiPropertyVo.getUnit()); + propertyList.add(haiWeiPropertyVo); + } + haiWeiDeviceInfoVo.setPropertyList(propertyList); + //插入缓存 + redisCache.setCacheObject(DeviceCacheConstants.getDeviceLogKey(deviceEntity.getDeviceId().toString()), haiWeiDeviceInfoVo); + //插入数据库 + List deviceLogEntityList = new ArrayList<>(); + for (HaiWeiPropertyVo waterFertilizePropertyVo : propertyList) { + DeviceLog deviceLogEntity = new DeviceLog(); + deviceLogEntity.setLogValue(waterFertilizePropertyVo.getValue().toString()); + deviceLogEntity.setIdentity(waterFertilizePropertyVo.getNameEn()); + deviceLogEntity.setModelName(waterFertilizePropertyVo.getNameCn()); + deviceLogEntity.setDeviceId(deviceEntity.getDeviceId()); + deviceLogEntity.setSerialNumber(deviceEntity.getSerialNumber()); + deviceLogEntity.setDeviceName(deviceEntity.getDeviceName()); + deviceLogEntity.setLogType(1); + deviceLogEntity.setCreateTime(new Date()); + deviceLogEntity.setIsMonitor(0); + deviceLogEntity.setMode(2); + deviceLogEntityList.add(deviceLogEntity); + redisCache.zSetAdd(RedisKeyBuilder.buildDeviceOnlineListKey(), deviceLogEntity.getSerialNumber(), DateUtils.getTimestampSeconds()); + } + if (deviceLogEntityList.size() > 0) { + String key = DeviceCacheConstants.getDeviceInsertDb(deviceEntity.getDeviceId()); + Object cacheObject = redisCache.getCacheObject(key); + //10分钟插入数据库一次 + if (null == cacheObject) { + redisCache.setCacheObject(key, 0, 10, TimeUnit.MINUTES); + TdLogDto dto = new TdLogDto(); + dto.setSerialNumber(deviceEntity.getSerialNumber()); + dto.setList(deviceLogEntityList); + iLogService.saveBatch(dto); + } + } + + } + + public Map getDevParams(Device device) { + Map devData = new HashMap<>(); + devData.put("machineCode", device.getSerialNumber()); + String remark = device.getRemark(); + String[] split = remark.split(","); + for (String s : split) { + String[] split1 = s.split("_"); + devData.put(split1[0],split1[1]); + } + return devData; + } + +} + + + diff --git a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/TableMapper.xml b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/TableMapper.xml new file mode 100644 index 0000000..64b561c --- /dev/null +++ b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/TableMapper.xml @@ -0,0 +1,34 @@ + + + + + + + CREATE TABLE IF NOT EXISTS `${tableName}` + ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `group_id` int(0) NULL DEFAULT NULL COMMENT '组号', + `username` varchar(20) NULL DEFAULT NULL COMMENT '用户名', + `password` varchar(20) NULL DEFAULT NULL COMMENT '密码', + PRIMARY KEY (`id`) + ) ENGINE = InnoDB + AUTO_INCREMENT = 9 + CHARACTER SET = utf8mb4 COMMENT ='用于测试的用户表'; + + + + + + + diff --git a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ThingsModelMapper.xml b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ThingsModelMapper.xml index a4ec850..ce852cb 100644 --- a/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ThingsModelMapper.xml +++ b/fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/ThingsModelMapper.xml @@ -17,6 +17,7 @@ + @@ -58,6 +59,7 @@ datatype, formula, specs, + group, is_chart, is_share_perm, is_history, @@ -83,7 +85,7 @@ end as model_name, m.model_name as model_name_zh_cn, t.en_us as model_name_en_us, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, - m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, + m.specs,m.group, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order from iot_things_model m left join iot_things_model_translate t on m.model_id = t.id @@ -138,7 +140,7 @@ else m.model_name end as model_name, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, - m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, + m.specs,m.group, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order from iot_things_model m left join iot_things_model_translate t on m.model_id = t.id @@ -156,7 +158,7 @@ else m.model_name end as model_name, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, - m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, + m.specs, m.group,m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order from iot_things_model m left join iot_things_model_translate t on m.model_id = t.id @@ -171,7 +173,7 @@ else m.model_name end as model_name, m.product_id, m.product_name, m.tenant_id, m.tenant_name, m.identifier, m.type, m.datatype, m.formula, - m.specs, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, + m.specs,m.group, m.is_chart, m.is_share_perm, m.is_history, m.is_monitor, m.is_app, m.del_flag, m.create_by, m.create_time, m.update_by, m.update_time, m.remark, m.is_readonly, m.model_order from iot_things_model m left join iot_things_model_translate t on m.model_id = t.id @@ -219,6 +221,9 @@ specs, + + group, + is_chart, @@ -290,6 +295,9 @@ #{specs}, + + #{group}, + #{isChart}, @@ -344,6 +352,7 @@ type, datatype, specs, + group, is_chart, is_share_perm, is_history, @@ -359,7 +368,7 @@ #{model.modelName},#{model.productId},#{model.productName},#{model.tenantId}, #{model.tenantName},#{model.identifier},#{model.type},#{model.datatype}, - #{model.specs},#{model.isChart},#{model.isSharePerm},#{model.isHistory}, + #{model.specs},#{model.group},#{model.isChart},#{model.isSharePerm},#{model.isHistory}, #{model.isMonitor},#{model.isApp},#{model.isReadonly},#{model.createBy},#{model.createTime}, #{model.formula} @@ -399,6 +408,9 @@ specs = #{specs}, + + group = #{group}, + is_chart = #{isChart},