|
|
|
package com.zhonglai.luhui.mqtt.service.db;
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
import com.ruoyi.system.domain.IotDevice;
|
|
|
|
import com.ruoyi.system.domain.IotTerminal;
|
|
|
|
import com.ruoyi.system.domain.IotThingsModel;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.config.RedisConfig;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.dao.BaseDao;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.dto.thingsmodels.ThingsModelBase;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.dto.thingsmodels.ThingsModelDataTypeEnum;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.factory.Topic;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.service.ClienNoticeService;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.service.redis.RedisService;
|
|
|
|
import com.zhonglai.luhui.mqtt.comm.util.DateUtils;
|
|
|
|
import com.zhonglai.luhui.mqtt.dto.Message;
|
|
|
|
import com.zhonglai.luhui.mqtt.dto.MessageCode;
|
|
|
|
import com.zhonglai.luhui.mqtt.service.CacheServiceImpl;
|
|
|
|
import com.zhonglai.luhui.mqtt.service.db.mode.TerminalDataThingsModeService;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.eclipse.paho.client.mqttv3.MqttException;
|
|
|
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
@Service
|
|
|
|
public class DeviceService {
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
private ClienNoticeService clienNoticeService;
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
private RedisService redisService ;
|
|
|
|
private TerminalDataThingsModeService terminalDataThingsModeService;
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
private CacheServiceImpl cacheServiceImpl;
|
|
|
|
|
|
|
|
private BaseDao baseDao = new BaseDao();
|
|
|
|
|
|
|
|
/**
|
|
...
|
...
|
@@ -51,146 +75,251 @@ public class DeviceService { |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取缓存网关信息
|
|
|
|
* @param id
|
|
|
|
* 增量更新数据
|
|
|
|
* @param oldstr
|
|
|
|
* @param saveJson
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public IotDevice getRedicDevice(String id)
|
|
|
|
public JSONObject getNewAdddate(String oldstr, JSONObject saveJson)
|
|
|
|
{
|
|
|
|
Object object = redisService.get(getRedicDeviceKey(id));
|
|
|
|
if(null != object)
|
|
|
|
JSONObject oldjs = new JSONObject();
|
|
|
|
if(StringUtils.isNoneBlank(oldstr))
|
|
|
|
{
|
|
|
|
oldjs = JSONObject.parseObject(oldstr);
|
|
|
|
}
|
|
|
|
for (String sk:saveJson.keySet())
|
|
|
|
{
|
|
|
|
return (IotDevice)object;
|
|
|
|
}else{
|
|
|
|
IotDevice iotDevice = getDeviceById(id);
|
|
|
|
setRedicDevice(iotDevice);
|
|
|
|
return iotDevice;
|
|
|
|
oldjs.put(sk,saveJson.get(sk));
|
|
|
|
}
|
|
|
|
return oldjs;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updataDevice(IotDevice iotDevice)
|
|
|
|
|
|
|
|
|
|
|
|
public void deviceOffLine(String clientId)
|
|
|
|
{
|
|
|
|
setRedicDevice(iotDevice);
|
|
|
|
cacheServiceImpl.deletRedisDevice(clientId);
|
|
|
|
IotDevice iotDevice = new IotDevice();
|
|
|
|
iotDevice.setClient_id(clientId);
|
|
|
|
iotDevice.setStatus(4);
|
|
|
|
baseDao.update(iotDevice,"client_id");
|
|
|
|
|
|
|
|
Set<String> keys = cacheServiceImpl.getRedicTerminalFromClientId(clientId);
|
|
|
|
if(null != keys && keys.size() != 0)
|
|
|
|
{
|
|
|
|
terminalOffLine(keys.toArray(new String[keys.size()]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void terminalOffLine(String... terminalIds)
|
|
|
|
{
|
|
|
|
baseDao.updateBySql("update iot_terminal set online=0 where id in(?)",Arrays.asList(terminalIds));
|
|
|
|
cacheServiceImpl.deletRedisTerminal(terminalIds);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 设置缓存网关信息
|
|
|
|
* @param device
|
|
|
|
* 控制发16进制指令
|
|
|
|
* @param clienid
|
|
|
|
* @param data
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
private boolean setRedicDevice(IotDevice device)
|
|
|
|
{
|
|
|
|
System.out.println("更新 "+device.getClient_id()+" 缓存,生命周期为 "+device.getDevice_life());
|
|
|
|
return redisService.setexDevice(getRedicDeviceKey(device.getClient_id()),device.getDevice_life(),device);
|
|
|
|
}
|
|
|
|
public Message controlHex(String clienid, String data) throws MqttException, InterruptedException {
|
|
|
|
|
|
|
|
public String getRedicDeviceKey(String client_id)
|
|
|
|
{
|
|
|
|
return getRedicDeviceKeyPath()+client_id;
|
|
|
|
}
|
|
|
|
Topic topic = getTopicFromDb(clienid);
|
|
|
|
if(null == topic)
|
|
|
|
{
|
|
|
|
return new Message(MessageCode.DEFAULT_FAIL_CODE,"mqtt_username查询失败");
|
|
|
|
}
|
|
|
|
topic.setTopicType("PUT");
|
|
|
|
topic.setMessageid(DateUtils.getNowTimeMilly()+"");
|
|
|
|
|
|
|
|
public String getRedicTerminalFromClientId(String client_id)
|
|
|
|
{
|
|
|
|
return RedisConfig.FIELD+"*:"+client_id+"*";
|
|
|
|
}
|
|
|
|
MqttMessage mqttMessage = new MqttMessage();
|
|
|
|
byte[] bs = hexStringToByte(data.trim().toUpperCase());
|
|
|
|
mqttMessage.setPayload(bs);
|
|
|
|
|
|
|
|
public String getRedicDeviceKeyPath()
|
|
|
|
{
|
|
|
|
return RedisConfig.FIELD+RedisConfig.DEVICE;
|
|
|
|
Message message = clienNoticeService.sendMessage(topic,mqttMessage);
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取缓存终端信息
|
|
|
|
* @param id
|
|
|
|
* 读
|
|
|
|
* @param clienid
|
|
|
|
* @param map
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
public IotTerminal getRedicTerminal(String id)
|
|
|
|
{
|
|
|
|
Object object = redisService.get(getRedicTerminalKey(id));
|
|
|
|
if(null == object)
|
|
|
|
public Message read(String clienid,Map<String,Object> map) throws MqttException, InterruptedException {
|
|
|
|
|
|
|
|
if(null == map || map.size() ==0)
|
|
|
|
{
|
|
|
|
IotTerminal terminal = getTerminalById(id);
|
|
|
|
return new Message(MessageCode.DEFAULT_FAIL_CODE,"参数验证失败");
|
|
|
|
}
|
|
|
|
|
|
|
|
if(null == terminal)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}else{
|
|
|
|
return terminal;
|
|
|
|
}
|
|
|
|
Topic topic = getTopicFromDb(clienid);
|
|
|
|
if(null == topic)
|
|
|
|
{
|
|
|
|
return new Message(MessageCode.DEFAULT_FAIL_CODE,"mqtt_username查询失败");
|
|
|
|
}
|
|
|
|
return (IotTerminal)object;
|
|
|
|
topic.setTopicType("READ");
|
|
|
|
topic.setMessageid(DateUtils.getNowTimeMilly()+"");
|
|
|
|
MqttMessage mqttMessage = new MqttMessage();
|
|
|
|
mqttMessage.setPayload(JSON.toJSONString(map).trim().getBytes());
|
|
|
|
Message message = clienNoticeService.sendMessage(topic,mqttMessage);
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 设置缓存终端信息
|
|
|
|
* @param terminal
|
|
|
|
* 强行断开链接
|
|
|
|
* @param clienid
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
private boolean setRedicTerminal(IotTerminal terminal,long device_life)
|
|
|
|
{
|
|
|
|
return redisService.setexDevice(getRedicTerminalKey(terminal.getId()),device_life,terminal);
|
|
|
|
}
|
|
|
|
public Message closeSession(String clienid) throws MqttException, InterruptedException {
|
|
|
|
|
|
|
|
public String getRedicTerminalKey(String terminal_id)
|
|
|
|
{
|
|
|
|
return getRedicTerminalKeyPath()+terminal_id;
|
|
|
|
MqttMessage mqttMessage = new MqttMessage();
|
|
|
|
byte[] bs = hexStringToByte(clienid.trim().toUpperCase());
|
|
|
|
mqttMessage.setPayload(bs);
|
|
|
|
|
|
|
|
clienNoticeService.sendMessage("CLOSE",mqttMessage);
|
|
|
|
return new Message(MessageCode.DEFAULT_SUCCESS_CODE,"端口请求已发送");
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getRedicTerminalKeyPath()
|
|
|
|
{
|
|
|
|
return RedisConfig.FIELD+RedisConfig.TERMINAL;
|
|
|
|
/**
|
|
|
|
* 删除主机
|
|
|
|
* @param client_id
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
public Message delIotDevice(String client_id) throws MqttException, InterruptedException {
|
|
|
|
closeSession(client_id); //强制下线
|
|
|
|
cacheServiceImpl.deletRedisDevice(client_id);
|
|
|
|
return new Message(MessageCode.DEFAULT_SUCCESS_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updataTerminal(IotTerminal terminal,long device_life)
|
|
|
|
{
|
|
|
|
setRedicTerminal(terminal,device_life);
|
|
|
|
baseDao.saveOrUpdateObject(terminal);
|
|
|
|
/**
|
|
|
|
* 删除终端
|
|
|
|
* @param client_id
|
|
|
|
* @param number
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
public Message delIotTerminal(String client_id,String number) throws MqttException, InterruptedException {
|
|
|
|
closeSession(client_id); //强制下线
|
|
|
|
cacheServiceImpl.deletRedisTerminal(client_id+"_"+number);
|
|
|
|
return new Message(MessageCode.DEFAULT_SUCCESS_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 增量更新数据
|
|
|
|
* @param oldstr
|
|
|
|
* @param saveJson
|
|
|
|
* 控制发json
|
|
|
|
* @param clienid
|
|
|
|
* @param map
|
|
|
|
* @return
|
|
|
|
* @throws MqttException
|
|
|
|
* @throws InterruptedException
|
|
|
|
*/
|
|
|
|
public JSONObject getNewAdddate(String oldstr, JSONObject saveJson)
|
|
|
|
{
|
|
|
|
JSONObject oldjs = new JSONObject();
|
|
|
|
if(StringUtils.isNoneBlank(oldstr))
|
|
|
|
public Message control(String clienid,Map<String,Object> map) throws MqttException, InterruptedException {
|
|
|
|
|
|
|
|
if(null == map || map.size() ==0)
|
|
|
|
{
|
|
|
|
oldjs = JSONObject.parseObject(oldstr);
|
|
|
|
return new Message(MessageCode.DEFAULT_FAIL_CODE,"参数验证失败");
|
|
|
|
}
|
|
|
|
for (String sk:saveJson.keySet())
|
|
|
|
|
|
|
|
Topic topic = getTopicFromDb(clienid);
|
|
|
|
if(null == topic)
|
|
|
|
{
|
|
|
|
oldjs.put(sk,saveJson.get(sk));
|
|
|
|
return new Message(MessageCode.DEFAULT_FAIL_CODE,"mqtt_username查询失败");
|
|
|
|
}
|
|
|
|
return oldjs;
|
|
|
|
topic.setTopicType("PUT");
|
|
|
|
topic.setMessageid(DateUtils.getNowTimeMilly()+"");
|
|
|
|
|
|
|
|
for(String key:map.keySet())
|
|
|
|
{
|
|
|
|
Object sendMap = map.get(key);
|
|
|
|
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(sendMap));
|
|
|
|
for(String skey:jsonObject.keySet())
|
|
|
|
{
|
|
|
|
IotThingsModel thingsModel = terminalDataThingsModeService.getIotThingsModel(topic.getUsername(),skey);
|
|
|
|
if(null == thingsModel) //没有配置的 都按字符串处理
|
|
|
|
{
|
|
|
|
thingsModel = new IotThingsModel();
|
|
|
|
thingsModel.setData_type(ThingsModelDataTypeEnum.STRING.name());
|
|
|
|
thingsModel.setIdentifier(key);
|
|
|
|
thingsModel.setModel_name(key);
|
|
|
|
thingsModel.setIs_top(0);
|
|
|
|
thingsModel.setIs_monitor(0);
|
|
|
|
thingsModel.setIs_save_log(0);
|
|
|
|
thingsModel.setIs_config(0);
|
|
|
|
JSONObject spes = new JSONObject();
|
|
|
|
spes.put("maxLength",255);
|
|
|
|
thingsModel.setSpecs(spes.toString());
|
|
|
|
}
|
|
|
|
String data_type = thingsModel.getData_type().toUpperCase();
|
|
|
|
Class<ThingsModelBase> aClass = Enum.valueOf(ThingsModelDataTypeEnum.class,data_type).getaClass();
|
|
|
|
ThingsModelBase thingsModelBase = JSON.parseObject(thingsModel.getSpecs(),aClass);
|
|
|
|
jsonObject.put(skey,thingsModelBase.getCmdView(jsonObject.get(skey)));
|
|
|
|
}
|
|
|
|
|
|
|
|
map.put(key,jsonObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
MqttMessage mqttMessage = new MqttMessage();
|
|
|
|
mqttMessage.setPayload(JSON.toJSONString(map).trim().getBytes());
|
|
|
|
Message message = clienNoticeService.sendMessage(topic,mqttMessage);
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 删除主机
|
|
|
|
* @param client_id
|
|
|
|
* 获取指定设备版本信息
|
|
|
|
* @param app_type
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public void deletRedisDevice(String client_id)
|
|
|
|
public Message getFirmwareVersion(String app_type)
|
|
|
|
{
|
|
|
|
Set<String> keys = redisService.keys(getRedicTerminalFromClientId(client_id));
|
|
|
|
if(null != keys && keys.size() != 0)
|
|
|
|
{
|
|
|
|
redisService.del(keys.toArray(new String[keys.size()]));
|
|
|
|
}
|
|
|
|
List list = baseDao.findListBysql("SELECT md5str,upload_file_path uploadFilePath,version_number versionNumber,code FROM liu_yu_le.`app_file_upgrade` WHERE app_type='"+app_type+"' ORDER BY id DESC limit 5");
|
|
|
|
return new Message(MessageCode.DEFAULT_SUCCESS_CODE,list);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 删除终端
|
|
|
|
* @param client_ids
|
|
|
|
* 通过数据获取发送消息的topic
|
|
|
|
* @param clienid
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public void deletRedisTerminal(String... client_ids)
|
|
|
|
private Topic getTopicFromDb(String clienid)
|
|
|
|
{
|
|
|
|
String[] keys = new String[client_ids.length];
|
|
|
|
for (int i=0;i<client_ids.length;i++)
|
|
|
|
JSONArray jsonArray = baseDao.findBysql("SELECT b.`role_id` roleid,b.`mqtt_username` username,a.`client_id` clientid,a.`payload_type` payloadtype FROM `iot_device` a LEFT JOIN `iot_product` b ON a.`product_id`=b.`id` WHERE client_id='"+clienid+"'");
|
|
|
|
if(null == jsonArray || jsonArray.size()==0 || null == jsonArray.getJSONObject(0).get("username"))
|
|
|
|
{
|
|
|
|
keys[i] = getRedicTerminalKey(client_ids[i]);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
redisService.del(keys);
|
|
|
|
Topic topic = JSON.parseObject( jsonArray.getJSONObject(0).toJSONString(),Topic.class);
|
|
|
|
topic.setTopicType("PUT");
|
|
|
|
topic.setMessageid(DateUtils.getNowTimeMilly()+"");
|
|
|
|
return topic;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* 把16进制字符串转换成字节数组
|
|
|
|
*
|
|
|
|
* @param hex
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
private byte[] hexStringToByte(String hex) {
|
|
|
|
int len = (hex.length() / 2);
|
|
|
|
byte[] result = new byte[len];
|
|
|
|
char[] achar = hex.toCharArray();
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
int pos = i * 2;
|
|
|
|
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
private byte toByte(char c) {
|
|
|
|
byte b = (byte) "0123456789ABCDEF".indexOf(c);
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|