Commit 30ae30a1 authored by 何金镒's avatar 何金镒

新增场景 3

parent b22ce43c
CREATE TABLE `temporary_scene` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ccuId` varchar(10) DEFAULT NULL COMMENT '主机号,CCU_127445',
`temporarySceneId` varchar(10) DEFAULT NULL COMMENT '临时场景ID',
`createTime` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
...@@ -5,8 +5,10 @@ import cn.hutool.json.JSONArray; ...@@ -5,8 +5,10 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.ikonke.konkeaialibabamcp.constant.RedisKeys; import com.ikonke.konkeaialibabamcp.constant.RedisKeys;
import com.ikonke.konkeaialibabamcp.service.SycDeviceService; import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
import com.ikonke.konkeaialibabamcp.utils.CcuUtils;
import com.ikonke.konkeaialibabamcp.utils.KonkeIotUtils; import com.ikonke.konkeaialibabamcp.utils.KonkeIotUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -41,6 +43,7 @@ public class DeviceController { ...@@ -41,6 +43,7 @@ public class DeviceController {
@PostMapping("/addScene") @PostMapping("/addScene")
public String addScene(@RequestHeader("temporarySceneId") String temporarySceneId, public String addScene(@RequestHeader("temporarySceneId") String temporarySceneId,
@RequestHeader("sn") String sn, @RequestHeader("sn") String sn,
...@@ -55,9 +58,28 @@ public class DeviceController { ...@@ -55,9 +58,28 @@ public class DeviceController {
public Boolean delScene(@RequestHeader("temporarySceneId") String temporarySceneId, public Boolean delScene(@RequestHeader("temporarySceneId") String temporarySceneId,
@RequestHeader("sn") String sn, @RequestHeader("sn") String sn,
@RequestParam(value = "ccuName") String ccuName) { @RequestParam(value = "ccuName") String ccuName) {
log.info("addScene..删除场景..ccuName:{},temporarySceneId:{},sn:{}",ccuName,temporarySceneId,sn); log.info("delScene..删除场景..ccuName:{},temporarySceneId:{},sn:{}",ccuName,temporarySceneId,sn);
return konkeIotServer.delScene(sn,ccuName,temporarySceneId); return konkeIotServer.delScene(sn,ccuName,temporarySceneId);
} }
@GetMapping("/triggerScene")
public String triggerScene(@ToolParam(description = "主机号")String ccuName,
@ToolParam(description = "场景ID")String devId,
@ToolParam(description = "场景类型ID,type等于scene")String typeId){
log.info("mcp调用--->根据主机号和场景ID触发场景....ccuName:{},devId:{},type:{}",ccuName,devId,typeId);
return konkeIotServer.optScene(CcuUtils.getCcuName(ccuName), devId);
}
@PostMapping("/saveTemporaryScene")
public String saveTemporaryScene(@RequestParam(value = "ccuName") String ccuName,
@RequestParam(value = "temporarySceneId") String temporarySceneId) {
log.info("saveTemporaryScene..临时场景存储..ccuName:{},temporarySceneId:{}",ccuName,temporarySceneId);
if(konkeIotServer.saveTemporaryScene(ccuName, temporarySceneId)){
return "保存成功";
}else{
return "保存失败";
}
}
} }
package com.ikonke.konkeaialibabamcp.entity.mysql;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("`temporary_scene`")
public class TemporaryScene implements Serializable {
@Serial
private static final long serialVersionUID = -1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("ccuId")
private String ccuId;
@TableField("temporarySceneId")
private String temporarySceneId;
@TableField("createTime")
private LocalDateTime createTime;
}
package com.ikonke.konkeaialibabamcp.mapper.mysql;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ikonke.konkeaialibabamcp.entity.mysql.TemporaryScene;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TemporarySceneMapper extends BaseMapper<TemporaryScene> {
@Delete("DELETE t1 FROM temporary_scene t1 INNER JOIN temporary_scene t2 WHERE t1.ccuId = t2.ccuId AND ( t1.createTime < t2.createTime OR ( t1.createTime = t2.createTime AND t1.id < t2.id ) )")
int delByCreateTime();
}
package com.ikonke.konkeaialibabamcp.service.mysqlservice;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ikonke.konkeaialibabamcp.entity.mysql.TemporaryScene;
public interface ITemporarySceneService extends IService<TemporaryScene> {
int delByCreateTime();
}
package com.ikonke.konkeaialibabamcp.service.mysqlservice.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ikonke.konkeaialibabamcp.entity.mysql.SynDevice;
import com.ikonke.konkeaialibabamcp.entity.mysql.TemporaryScene;
import com.ikonke.konkeaialibabamcp.mapper.mysql.TemporarySceneMapper;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ITemporarySceneService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ITemporarySceneServiceImpl extends ServiceImpl<TemporarySceneMapper, TemporaryScene> implements ITemporarySceneService {
@Override
public int delByCreateTime() {
return baseMapper.delByCreateTime();
}
}
package com.ikonke.konkeaialibabamcp.timedtasks;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ITemporarySceneService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@EnableScheduling
public class TemporarySceneTask {
@Autowired
private ITemporarySceneService temporarySceneService;
/**
* 每5分钟再执行一次该定时器。
*/
@Scheduled(fixedRate = 300000)
public void task() {
log.info("开始定时任务:删除数据库中的旧的临时任务");
int i = temporarySceneService.delByCreateTime();
log.info("结束定时任务:删除数据库中的旧的临时任务数量"+i);
}
}
...@@ -6,12 +6,17 @@ import cn.hutool.http.HttpRequest; ...@@ -6,12 +6,17 @@ import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ikonke.konkeaialibabamcp.constant.DeviceConstant; import com.ikonke.konkeaialibabamcp.constant.DeviceConstant;
import com.ikonke.konkeaialibabamcp.constant.RedisKeys; import com.ikonke.konkeaialibabamcp.constant.RedisKeys;
import com.ikonke.konkeaialibabamcp.controller.param.AddSceneParam; import com.ikonke.konkeaialibabamcp.controller.param.AddSceneParam;
import com.ikonke.konkeaialibabamcp.entity.mongodb.DeviceStatus; import com.ikonke.konkeaialibabamcp.entity.mongodb.DeviceStatus;
import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel; import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel;
import com.ikonke.konkeaialibabamcp.entity.mysql.SynDevice;
import com.ikonke.konkeaialibabamcp.entity.mysql.TemporaryScene;
import com.ikonke.konkeaialibabamcp.service.SycDeviceService; import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ISynDeviceService;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ITemporarySceneService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
...@@ -22,6 +27,7 @@ import org.springframework.stereotype.Component; ...@@ -22,6 +27,7 @@ import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.awt.*; import java.awt.*;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -43,11 +49,13 @@ public class KonkeIotUtils { ...@@ -43,11 +49,13 @@ public class KonkeIotUtils {
private final MongoTemplate mongoTemplate; private final MongoTemplate mongoTemplate;
private final SycDeviceService sycDeviceService; private final SycDeviceService sycDeviceService;
private final RedisTemplate<String, Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
private final ITemporarySceneService temporarySceneService;
public KonkeIotUtils(MongoTemplate mongoTemplate, SycDeviceService sycDeviceService, RedisTemplate<String, Object> redisTemplate) { public KonkeIotUtils(MongoTemplate mongoTemplate, SycDeviceService sycDeviceService, RedisTemplate<String, Object> redisTemplate, ITemporarySceneService temporarySceneService) {
this.mongoTemplate = mongoTemplate; this.mongoTemplate = mongoTemplate;
this.sycDeviceService = sycDeviceService; this.sycDeviceService = sycDeviceService;
this.redisTemplate = redisTemplate; this.redisTemplate = redisTemplate;
this.temporarySceneService = temporarySceneService;
} }
public final static Map<String, String> actionMap = Map.of( public final static Map<String, String> actionMap = Map.of(
...@@ -530,8 +538,11 @@ public class KonkeIotUtils { ...@@ -530,8 +538,11 @@ public class KonkeIotUtils {
* 触发场景 * 触发场景
*/ */
public String optScene(String ccuName, String sceneId){ public String optScene(String ccuName, String sceneId){
if(StrUtil.isBlank(sceneId)){
throw new StatefulException(-21, "场景不存在");
}
if(StrUtil.isBlank(ccuName) || StrUtil.isBlank(sceneId)){ if(StrUtil.isBlank(ccuName) || StrUtil.isBlank(sceneId)){
throw new StatefulException(-20, "参数不能为空"); throw new StatefulException(-20, "参数错误");
} }
String url = baseUrl + "/1.0/app/ccu/" + ccuName + "/dev/" + sceneId + "/opt"; String url = baseUrl + "/1.0/app/ccu/" + ccuName + "/dev/" + sceneId + "/opt";
log.info("KonkeIotServer optScene url {}, param {}, appId {}, appKey {}", url, "", appId, appKey); log.info("KonkeIotServer optScene url {}, param {}, appId {}, appKey {}", url, "", appId, appKey);
...@@ -543,7 +554,13 @@ public class KonkeIotUtils { ...@@ -543,7 +554,13 @@ public class KonkeIotUtils {
.body(opt.toString()) .body(opt.toString())
.execute().body(); .execute().body();
log.info("KonkeIotServer optScene result {}", result2); log.info("KonkeIotServer optScene result {}", result2);
return result2; JSONObject jsonObject = JSONUtil.parseObj(result2);
if(jsonObject.getBool("success")){
return "触发场景成功";
}else{
return "触发场景失败";
}
} }
/** /**
...@@ -576,8 +593,18 @@ public class KonkeIotUtils { ...@@ -576,8 +593,18 @@ public class KonkeIotUtils {
} }
log.info("delScene..删除场景..sn:{},ccuName:{},sceneId:{}",sn,ccuName,sceneId); log.info("delScene..删除场景..sn:{},ccuName:{},sceneId:{}",sn,ccuName,sceneId);
String redisKey = RedisKeys.KONKE_CDC + ccuName + ":" + RedisKeys.ADD_TEMPORARY_SCENE+ ":" +sceneId; QueryWrapper<TemporaryScene> wrapper = new QueryWrapper<>();
redisTemplate.delete(redisKey); wrapper.eq("ccuId", ccuName);
wrapper.eq("temporarySceneId", sceneId);
List<TemporaryScene> list = temporarySceneService.list(wrapper);
if(list.isEmpty()){
return true;
}else{
for(TemporaryScene scene : list){
temporarySceneService.removeById(scene.getId());
}
}
String url = baseUrl + "/2.0/ccu/" + ccuName + "/scene/" + sceneId; String url = baseUrl + "/2.0/ccu/" + ccuName + "/scene/" + sceneId;
String body = HttpRequest.delete(url) String body = HttpRequest.delete(url)
...@@ -647,8 +674,13 @@ public class KonkeIotUtils { ...@@ -647,8 +674,13 @@ public class KonkeIotUtils {
}else{ }else{
Integer scene_id = response.getInt("data"); Integer scene_id = response.getInt("data");
String redisKey = RedisKeys.KONKE_CDC + ccuName + ":" + RedisKeys.ADD_TEMPORARY_SCENE+ ":" +scene_id;
redisTemplate.opsForValue().set(redisKey, JSONUtil.toJsonStr(body),5*60, TimeUnit.SECONDS); TemporaryScene temporaryScene = new TemporaryScene();
temporaryScene.setCcuId(ccuName);
temporaryScene.setTemporarySceneId(scene_id+"");
temporaryScene.setCreateTime(LocalDateTime.now());
temporarySceneService.save(temporaryScene);
log.info("addScene..新增场景..result:{}",scene_id); log.info("addScene..新增场景..result:{}",scene_id);
return scene_id+""; return scene_id+"";
...@@ -659,6 +691,27 @@ public class KonkeIotUtils { ...@@ -659,6 +691,27 @@ public class KonkeIotUtils {
} }
} }
/**
* 保存临时场景
*/
public Boolean saveTemporaryScene(String ccuName,String temporarySceneId){
try {
QueryWrapper<TemporaryScene> wrapper = new QueryWrapper<>();
wrapper.eq("ccuId", ccuName);
wrapper.eq("temporarySceneId", temporarySceneId);
List<TemporaryScene> list = temporarySceneService.list(wrapper);
if(!list.isEmpty()){
for(TemporaryScene scene : list){
temporarySceneService.removeById(scene.getId());
}
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/** /**
* 将大模型推荐的action转换成新增场景的action * 将大模型推荐的action转换成新增场景的action
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment