|
|
@@ -0,0 +1,383 @@
|
|
|
+package com.yunfeiyun.agmp.iots.device.serviceImp;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.alibaba.fastjson2.JSONArray;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.yunfeiyun.agmp.common.service.LocationService;
|
|
|
+import com.yunfeiyun.agmp.common.utils.DateUtils;
|
|
|
+import com.yunfeiyun.agmp.common.utils.JSONUtils;
|
|
|
+import com.yunfeiyun.agmp.common.utils.StringUtils;
|
|
|
+import com.yunfeiyun.agmp.common.utils.reflect.ReflectUtils;
|
|
|
+import com.yunfeiyun.agmp.iot.common.constant.cmd.CmdDef;
|
|
|
+import com.yunfeiyun.agmp.iot.common.constant.devicetype.IotDeviceDictConst;
|
|
|
+import com.yunfeiyun.agmp.iot.common.constant.devicetype.ServiceNameConst;
|
|
|
+import com.yunfeiyun.agmp.iot.common.constant.mqtt.IotMqttConstant;
|
|
|
+import com.yunfeiyun.agmp.iot.common.domain.IotBaseEntity;
|
|
|
+import com.yunfeiyun.agmp.iot.common.domain.IotCbddata;
|
|
|
+import com.yunfeiyun.agmp.iot.common.domain.IotDevice;
|
|
|
+import com.yunfeiyun.agmp.iot.common.domain.IotPest;
|
|
|
+import com.yunfeiyun.agmp.iot.common.model.cmd.CmdModel;
|
|
|
+import com.yunfeiyun.agmp.iot.common.service.MongoService;
|
|
|
+import com.yunfeiyun.agmp.iots.core.manager.MqttManager;
|
|
|
+import com.yunfeiyun.agmp.iots.device.common.DeviceAbstractImpl;
|
|
|
+import com.yunfeiyun.agmp.iots.device.domain.cbd.YfCbdConfigMsg;
|
|
|
+import com.yunfeiyun.agmp.iots.device.domain.cbd.YfCbdMsgUtil;
|
|
|
+import com.yunfeiyun.agmp.iots.device.domain.cbd.YfCbdReqMsg;
|
|
|
+import com.yunfeiyun.agmp.iots.device.domain.cbd.YfCbdTakephotoMsg;
|
|
|
+import com.yunfeiyun.agmp.iots.device.mapper.IotPestMapper;
|
|
|
+import com.yunfeiyun.agmp.iots.device.service.IYfXctDevice;
|
|
|
+import com.yunfeiyun.agmp.iots.service.*;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.http.util.TextUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+@Component(ServiceNameConst.SERVICE_YF_XCT)
|
|
|
+@Slf4j
|
|
|
+public class IYfXctDeviceImpl extends DeviceAbstractImpl implements IYfXctDevice {
|
|
|
+ @Autowired
|
|
|
+ private MqttManager mqttManager;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IIotDeviceconfigService iIotDeviceconfigService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IIotDevicelasteddataService iIotDevicelasteddataService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MongoService<IotBaseEntity> mongoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private LocationService locationService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IotCbdImgService iotCbdImgService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IIotDeviceService iIotDeviceService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IIotCmdlogService iIotCmdlogService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IotDeviceAddressService iotDeviceAddressService;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object sendCmd(CmdModel cmdModel) throws Exception {
|
|
|
+ log.info("【吸虫塔】发送指令 任务 cmdModel={}", cmdModel);
|
|
|
+ // 获取执行的指令
|
|
|
+ CmdModel.Cmd cmdDistribution = cmdModel.getCmdDistribution();
|
|
|
+ // 获取执行的方法 ,方法可以通过反射获取执行,也可以临时case 匹配
|
|
|
+ String methodName = cmdModel.getCmdDistribution().getFunc();
|
|
|
+ String mqttMsgContent = "";
|
|
|
+ String clogSendresult = "发送指令成功";
|
|
|
+ switch (methodName) {
|
|
|
+ case CmdDef.YfCbdCmdDef.CMD_REQ_DATA:
|
|
|
+ mqttMsgContent = JSON.toJSON(new YfCbdReqMsg()).toString();
|
|
|
+ log.info("【吸虫塔】发送指令【reqData】 mqttMsgContent={}", mqttMsgContent);
|
|
|
+ break;
|
|
|
+ case CmdDef.YfCbdCmdDef.CMD_CONFIG:
|
|
|
+ JSONObject jobjParam = cmdDistribution.getJsons();
|
|
|
+
|
|
|
+ YfCbdConfigMsg yfCbdConfigMsg = new YfCbdConfigMsg();
|
|
|
+ YfCbdConfigMsg.Config config = new YfCbdConfigMsg.Config();
|
|
|
+
|
|
|
+ Set<String> keys = jobjParam.keySet();
|
|
|
+ Iterator<String> itor = keys.iterator();
|
|
|
+ while (itor.hasNext()) {
|
|
|
+ String key = itor.next();
|
|
|
+ try {
|
|
|
+ YfCbdMsgUtil.setField(config, key, jobjParam.getString(key));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ yfCbdConfigMsg.setExt(config);
|
|
|
+ mqttMsgContent = JSON.toJSON(yfCbdConfigMsg).toString();
|
|
|
+ log.info("【吸虫塔】发送指令【config】 mqttMsgContent={}", mqttMsgContent);
|
|
|
+ break;
|
|
|
+ case CmdDef.YfCbdCmdDef.CMD_TAKEPHOTO:
|
|
|
+ mqttMsgContent = JSON.toJSON(new YfCbdTakephotoMsg()).toString();
|
|
|
+ log.info("【吸虫塔】发送指令【takephoto】 mqttMsgContent={}", mqttMsgContent);
|
|
|
+ break;
|
|
|
+ case CmdDef.YfCbdCmdDef.CMD_REFRESH: {
|
|
|
+ mqttMsgContent = JSONUtils.toJSONString(cmdDistribution.getJsons());
|
|
|
+ log.info("【吸虫塔】发送指令【refresh】 mqttMsgContent={}", mqttMsgContent);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String topic = IotMqttConstant.YFCbdTopic.TOPIC_CBD_CMD_PREFIX + cmdModel.getIotDevice().getDevCode();
|
|
|
+ IotDevice iotDevice = iIotDeviceService.selectIotDeviceByDevBid(cmdModel.getIotDevice().getDevBid());
|
|
|
+ mqttManager.publishMsg(iotDevice.getDevconnBid(), topic, mqttMsgContent);
|
|
|
+
|
|
|
+ log.info("【吸虫塔】发送指令完毕!connectionId:{},topic :{} mqttMsgContent: {}", iotDevice.getDevconnBid(), topic, mqttMsgContent);
|
|
|
+
|
|
|
+ cmdModel.setClogSendresult(clogSendresult);
|
|
|
+ cmdModel.setClogDesc(mqttMsgContent);
|
|
|
+
|
|
|
+ iIotCmdlogService.insertSuccessCmdlog(cmdModel);
|
|
|
+
|
|
|
+ //返回值待定
|
|
|
+ return true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public String xctData(JSONObject ext, String cId, IotDevice iotDevice) {
|
|
|
+
|
|
|
+ String[] keyArrays = {
|
|
|
+ "dat_f",
|
|
|
+ "shake_sec",
|
|
|
+ "shake",
|
|
|
+ "ds",
|
|
|
+ "dver",
|
|
|
+ "st",
|
|
|
+ "et"
|
|
|
+ };
|
|
|
+
|
|
|
+ JSONObject extConf = new JSONObject();
|
|
|
+ for (String k : keyArrays) {
|
|
|
+ String v = "0";
|
|
|
+ if (ext.containsKey(k)) {
|
|
|
+ v = ext.getString(k);
|
|
|
+ }
|
|
|
+ extConf.put(k, v);
|
|
|
+ }
|
|
|
+ return JSONUtils.toJSONString(extConf);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param ext
|
|
|
+ * @param devUpdateddate
|
|
|
+ * @param topic
|
|
|
+ * @param connectionId
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public void cmdData(JSONObject ext, String devUpdateddate, String topic, String connectionId) throws Exception {
|
|
|
+ log.info("【吸虫塔】数据解析 {}", ext.toString());
|
|
|
+ String devId = mqttManager.getDevIdByTopic(connectionId, topic);
|
|
|
+ IotDevice iotDeviceFromDb = iIotDeviceService.selectIotDeviceByDevBid(devId);
|
|
|
+ if (iotDeviceFromDb == null) {
|
|
|
+ log.info("【吸虫塔】iotDeviceFromDb 空 {} ", devId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String vtype = ext.getString("vtype");
|
|
|
+ if (ext.containsKey("dat_f")) {
|
|
|
+ ext.put("datt", ext.getString("dat_f"));
|
|
|
+ }
|
|
|
+
|
|
|
+ iotDeviceFromDb.setDevUpdateddate(devUpdateddate);
|
|
|
+ iotDeviceFromDb.setDevStatus("1");
|
|
|
+
|
|
|
+ HashMap<String, String> keyMaps = new HashMap<>();
|
|
|
+ keyMaps.put("dver", "devVersion");
|
|
|
+ keyMaps.put("imei", "devCode");
|
|
|
+ keyMaps.put("gps", "devPositiontype");
|
|
|
+
|
|
|
+ for (Map.Entry<String, String> entry : keyMaps.entrySet()) {
|
|
|
+ String k = entry.getValue();
|
|
|
+ String v = ext.getString(entry.getKey());
|
|
|
+ if (StringUtils.isNotEmpty(v)) {
|
|
|
+ ReflectUtils.invokeSetter(iotDeviceFromDb, k, v);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String lat = ext.getString("lat");
|
|
|
+ String lng = ext.getString("lng");
|
|
|
+
|
|
|
+ if (!Objects.equals(iotDeviceFromDb.getDevPositionstatus(), "0")) {
|
|
|
+ iotDeviceAddressService.setDeviceAddress(iotDeviceFromDb, lng, lat);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 单独处理是否识别是否开启识别:0禁用(不带识别)1识别 2 计数
|
|
|
+ String disable = ext.getString("disable");
|
|
|
+ log.info("【吸虫塔-解析识别状态】disable:{}", disable);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("【吸虫塔-解析识别状态 异常】disable:{}", e.getMessage());
|
|
|
+ }
|
|
|
+ // 更新设备基础信息数据库 mysql
|
|
|
+ iIotDeviceService.updateIotDevice(iotDeviceFromDb);
|
|
|
+
|
|
|
+ // 更新设备数据信息到数据库 mongodb
|
|
|
+ String cId = iotDeviceFromDb.getTid();
|
|
|
+ String devConfig = this.xctData(ext, cId, iotDeviceFromDb);
|
|
|
+ // 创建或更新设备配置信息
|
|
|
+ if (StringUtils.isNotEmpty(devConfig)) {
|
|
|
+ iIotDeviceconfigService.createOrUpdateDevConfig(iotDeviceFromDb, devConfig, iotDeviceFromDb.getDevUpdateddate());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存 设备最新数据 到redis
|
|
|
+ iIotDevicelasteddataService.createOrUpdateDeviceLastedData(
|
|
|
+ ext, iotDeviceFromDb, iotDeviceFromDb.getDevUpdateddate(), 60 * 60 * 24L);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param ext
|
|
|
+ * @param topic
|
|
|
+ * @param connectionId
|
|
|
+ */
|
|
|
+ public void cmdOffline(JSONObject ext, String topic, String connectionId) {
|
|
|
+ log.debug("测报灯离线数据 {}", ext.toString());
|
|
|
+ String devId = mqttManager.getDevIdByTopic(connectionId, topic);
|
|
|
+ IotDevice iotDevice = iIotDeviceService.selectIotDeviceByDevBid(devId);
|
|
|
+ if (iotDevice == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ IotDevice newIotDevice = new IotDevice();
|
|
|
+ newIotDevice.setDevBid(devId);
|
|
|
+ newIotDevice.setDevStatus("0");
|
|
|
+ newIotDevice.setDevOfflinedate(DateUtils.dateTimeNow());
|
|
|
+ iIotDeviceService.updateIotDevice(newIotDevice);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param topic
|
|
|
+ * @param dataJson
|
|
|
+ * @param connectionId
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Object receiveData(String topic, JSONObject dataJson, String connectionId) throws Exception {
|
|
|
+ log.info("【吸虫塔】收到的 设备上报数据 {}", dataJson.toString());
|
|
|
+ // 接收设备上报数据后的处理逻辑
|
|
|
+ String devUpdateddate = DateUtils.dateTimeNow();
|
|
|
+ if(topic.startsWith(IotMqttConstant.YFXctTopic.TOPIC_XCT_PEST_IMG)){
|
|
|
+ Object result = this.receivePicData(dataJson, devUpdateddate, topic, connectionId);
|
|
|
+ log.info("【吸虫塔】图片数据处理完成");
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ if(topic.startsWith(IotMqttConstant.YFCbdTopic.TOPIC_CBD_REPORT_PREFIX)){
|
|
|
+ String cmd = dataJson.getString("cmd");
|
|
|
+ if (TextUtils.isEmpty(cmd)) {
|
|
|
+ log.error("未取到cmd");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if("data".equals("cmd")){
|
|
|
+ JSONObject ext = dataJson.getJSONObject("ext");
|
|
|
+ if (ext == null) {
|
|
|
+ log.error("未取到ext");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (cmd.equals("data")) {
|
|
|
+ this.cmdData(ext, devUpdateddate, topic, connectionId);
|
|
|
+ } else if (cmd.equals("offline")) {
|
|
|
+ this.cmdOffline(ext, topic, connectionId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param jsonObject
|
|
|
+ * @param devUpdateddate
|
|
|
+ * @param topic
|
|
|
+ * @param connectionId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+
|
|
|
+ public Object receivePicData(JSONObject jsonObject, String devUpdateddate, String topic, String connectionId) {
|
|
|
+ String devId = mqttManager.getDevIdByTopic(connectionId, topic);
|
|
|
+ IotDevice iotDevice = iIotDeviceService.selectIotDeviceByDevBid(devId);
|
|
|
+ if (iotDevice == null) {
|
|
|
+ return "设备不存在 就不在处理";
|
|
|
+ }
|
|
|
+ String devtypeBid = iotDevice.getDevtypeBid();
|
|
|
+ String deviceTypeId = iotDevice.getDevtypeBid();
|
|
|
+ String devCode = jsonObject.getString("device_id");
|
|
|
+ log.info("【解析测报灯图片数据】:devtypeBid:{},deviceTypeId,{},devCode:{}", devtypeBid, deviceTypeId, devCode);
|
|
|
+ String cbdimgAddr = jsonObject.getString("img");
|
|
|
+ if (StringUtils.isEmpty(cbdimgAddr)) {
|
|
|
+ return "图片地址不存在,则不处理";
|
|
|
+ }
|
|
|
+ // 由于吸虫塔和测报灯的害虫编号重复将吸虫塔中的虫子编号进行转化
|
|
|
+ transXctPestPoint(jsonObject);
|
|
|
+ // 将吸虫塔的数据格式转化成测报灯的数据格式
|
|
|
+ jsonObject = transXctDataToCbdData(jsonObject);
|
|
|
+
|
|
|
+ // 保存测报灯图片数据到mongodb
|
|
|
+ iotCbdImgService.insertIotCbdimg(iotDevice, jsonObject, devUpdateddate);
|
|
|
+
|
|
|
+ return "测报灯指令上报的图片结果";
|
|
|
+ }
|
|
|
+
|
|
|
+ private JSONObject transXctDataToCbdData(JSONObject jsonObject) {
|
|
|
+ JSONObject result = new JSONObject();
|
|
|
+ result.put("imei",jsonObject.get("device_id"));
|
|
|
+ result.put("Image",jsonObject.get("img"));
|
|
|
+ result.put("Result",jsonObject.get("label"));
|
|
|
+ result.put("Result_image",jsonObject.get("img"));
|
|
|
+ result.put("Result_code",jsonObject.get("return_string"));
|
|
|
+ result.put("Image_b","0");
|
|
|
+ result.put("Result_b","0");
|
|
|
+ result.put("Result_image_b","0");
|
|
|
+ result.put("Result_code_b","0");
|
|
|
+ result.put("Result_c",jsonObject.get("Result_c"));
|
|
|
+ result.put("disable","0");
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ private void transXctPestPoint(JSONObject dataJson){
|
|
|
+ String cbdrecogMachinemark = dataJson.getString("return_string");
|
|
|
+ String cbdrecogResult = dataJson.getString("label");
|
|
|
+
|
|
|
+ JSONArray jsonArray = JSONArray.parseArray(cbdrecogMachinemark);
|
|
|
+ JSONArray transAfterData = new JSONArray();
|
|
|
+
|
|
|
+ int totalPestNum = 0;
|
|
|
+ for(int i = jsonArray.size()-1;i>=0;i--){
|
|
|
+ JSONObject returnStrItem = jsonArray.getJSONObject(i);
|
|
|
+ for(Map.Entry<String,Object> entry : returnStrItem.entrySet()){
|
|
|
+ String key = entry.getKey();
|
|
|
+ Object value = entry.getValue();
|
|
|
+ totalPestNum++;
|
|
|
+ if(!"4".equals(key)) {
|
|
|
+ returnStrItem.remove(key);
|
|
|
+ returnStrItem.put("xct"+key,value);
|
|
|
+ transAfterData.add(returnStrItem);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ dataJson.put("return_string",transAfterData.toJSONString());
|
|
|
+ for(int i = 1;i<=3;i++){
|
|
|
+ cbdrecogResult = cbdrecogResult.replaceFirst(i+",","xct"+i+",");
|
|
|
+ }
|
|
|
+ cbdrecogResult = cbdrecogResult.replaceAll("4,\\d+#|#4,\\d+","");
|
|
|
+ dataJson.put("label",cbdrecogResult);
|
|
|
+ dataJson.put("Result_c",totalPestNum);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param jobjMsg
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public boolean isDeviceProps(JSONObject jobjMsg) {
|
|
|
+ if ("data".equals(jobjMsg.getString("cmd"))) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param topic
|
|
|
+ * @param jobjMsg
|
|
|
+ * @param connectionId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public IotDevice findIotDevice(String topic, JSONObject jobjMsg, String connectionId) {
|
|
|
+ String devId = mqttManager.getDevIdByTopic(connectionId, topic);
|
|
|
+ IotDevice ret = iIotDeviceService.selectIotDeviceByDevBid(devId);
|
|
|
+ log.debug("查到了一个iotdevice {}", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+}
|