Commit 08cd8d80 authored by 何金镒's avatar 何金镒

场景推荐 1

parent b12b1cae
package com.ikonke.konkeaialibabamcp.aitools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class SceneRecommendTools {
private final RedisTemplate<String, Object> redisTemplate;
public SceneRecommendTools(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//删除场景,会定时删除Redis中的临时场景
//保存场景,将Redis中的临时场景删除即可
}
package com.ikonke.konkeaialibabamcp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
return template;
}
}
package com.ikonke.konkeaialibabamcp.constant;
public class RedisKeys {
public static final String KONKE_CDC = "konke:cdc:";
// key--> konke:cdc:mac:add_temporary_scene:scene_id value-->
public static final String ADD_TEMPORARY_SCENE = "add_temporary_scene";
}
package com.ikonke.konkeaialibabamcp.controller; package com.ikonke.konkeaialibabamcp.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray; 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.service.SycDeviceService; import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
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.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -15,7 +18,6 @@ import org.springframework.web.bind.annotation.*; ...@@ -15,7 +18,6 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/deviceController") @RequestMapping("/deviceController")
public class DeviceController { public class DeviceController {
@Autowired @Autowired
private SycDeviceService sycDeviceService; private SycDeviceService sycDeviceService;
@Autowired @Autowired
...@@ -40,10 +42,21 @@ public class DeviceController { ...@@ -40,10 +42,21 @@ public class DeviceController {
@PostMapping("/addScene") @PostMapping("/addScene")
public String addScene(@RequestParam(value = "ccuName") String ccuName, public String addScene(@RequestHeader("temporarySceneId") String temporarySceneId,
@RequestHeader("sn") String sn,
@RequestParam(value = "ccuName") String ccuName,
@RequestBody JSONObject actions) { @RequestBody JSONObject actions) {
log.info("addScene..新增场景..ccuName:{},actions:{}",ccuName,actions); log.info("addScene..新增场景..ccuName:{},temporarySceneId:{},sn:{},actions:{}",ccuName,temporarySceneId,sn,actions);
return konkeIotServer.addScene(ccuName,actions); konkeIotServer.delScene(sn,ccuName,temporarySceneId);
return konkeIotServer.addScene(sn,ccuName,actions);
}
@DeleteMapping("/delScene")
public Boolean delScene(@RequestHeader("temporarySceneId") String temporarySceneId,
@RequestHeader("sn") String sn,
@RequestParam(value = "ccuName") String ccuName) {
log.info("addScene..删除场景..ccuName:{},temporarySceneId:{},sn:{}",ccuName,temporarySceneId,sn);
return konkeIotServer.delScene(sn,ccuName,temporarySceneId);
} }
......
package com.ikonke.konkeaialibabamcp.utils; package com.ikonke.konkeaialibabamcp.utils;
import cn.hutool.core.exceptions.StatefulException; import cn.hutool.core.exceptions.StatefulException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest; 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.ikonke.konkeaialibabamcp.constant.DeviceConstant; import com.ikonke.konkeaialibabamcp.constant.DeviceConstant;
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.service.SycDeviceService; import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
...@@ -14,6 +16,7 @@ import org.springframework.beans.factory.annotation.Value; ...@@ -14,6 +16,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -22,6 +25,7 @@ import java.util.ArrayList; ...@@ -22,6 +25,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Component @Component
...@@ -39,10 +43,12 @@ public class KonkeIotUtils { ...@@ -39,10 +43,12 @@ 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;
public KonkeIotUtils(MongoTemplate mongoTemplate, SycDeviceService sycDeviceService) { public KonkeIotUtils(MongoTemplate mongoTemplate, SycDeviceService sycDeviceService, RedisTemplate<String, Object> redisTemplate) {
this.mongoTemplate = mongoTemplate; this.mongoTemplate = mongoTemplate;
this.sycDeviceService = sycDeviceService; this.sycDeviceService = sycDeviceService;
this.redisTemplate = redisTemplate;
} }
public final static Map<String, String> actionMap = Map.of( public final static Map<String, String> actionMap = Map.of(
...@@ -518,7 +524,15 @@ public class KonkeIotUtils { ...@@ -518,7 +524,15 @@ public class KonkeIotUtils {
/** /**
* 删除场景 * 删除场景
*/ */
public Boolean delScene(String ccuName, String sceneId){ public Boolean delScene(String sn,String ccuName, String sceneId){
if(StrUtil.isBlank(sn) || StrUtil.isBlank(ccuName) || StrUtil.isBlank(sceneId)){
return false;
}
log.info("delScene....sn:{},ccuName:{},sceneId:{}",sn,ccuName,sceneId);
String redisKey = RedisKeys.KONKE_CDC + sn + ":" + RedisKeys.ADD_TEMPORARY_SCENE+ ":" +sceneId;
redisTemplate.delete(redisKey);
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)
.header("appId", appId) .header("appId", appId)
...@@ -551,7 +565,8 @@ public class KonkeIotUtils { ...@@ -551,7 +565,8 @@ public class KonkeIotUtils {
* *
* 5、这个场景应该是一个临时场景,若用户没有说保存,应该删除掉 * 5、这个场景应该是一个临时场景,若用户没有说保存,应该删除掉
*/ */
public String addScene(String ccuName,JSONObject scene){ public String addScene(String sn,String ccuName,JSONObject scene){
try {
AddSceneParam bean = JSONUtil.toBean(scene, AddSceneParam.class); AddSceneParam bean = JSONUtil.toBean(scene, AddSceneParam.class);
JSONObject body = new JSONObject(); JSONObject body = new JSONObject();
...@@ -565,12 +580,14 @@ public class KonkeIotUtils { ...@@ -565,12 +580,14 @@ public class KonkeIotUtils {
body_action.set("realType",sycDeviceService.getDeviceRealType(Integer.valueOf(action.getTypeId()))); body_action.set("realType",sycDeviceService.getDeviceRealType(Integer.valueOf(action.getTypeId())));
body_action.set("delay", 0); body_action.set("delay", 0);
body_action.set("operation", this.getSceneAction(action.getOperation())); body_action.set("operation", this.getSceneAction(action.getOperation()));
actions.set(body_action);
} }
body.set("actions", actions); body.set("actions", actions);
String url = baseUrl + "/2.0/ccu/" + ccuName + "/scenes"; String url = baseUrl + "/2.0/ccu/" + ccuName + "/scenes";
log.info("addScene..新增场景..ccuName:{},scene:{}",ccuName,scene.toString()); log.info("addScene..新增场景..ccuName:{},scene:{}",ccuName,body.toString());
String result = HttpRequest.post(url) String result = HttpRequest.post(url)
.header("appId", appId) .header("appId", appId)
.header("appKey", appKey) .header("appKey", appKey)
...@@ -582,8 +599,17 @@ public class KonkeIotUtils { ...@@ -582,8 +599,17 @@ public class KonkeIotUtils {
if(!response.getBool("success")){ if(!response.getBool("success")){
throw new StatefulException(-1, response.getStr("message")); throw new StatefulException(-1, response.getStr("message"));
}else{ }else{
log.info("addScene..新增场景..result:{}",response.getStr("data")); Integer scene_id = response.getInt("data");
return response.getStr("data");
String redisKey = RedisKeys.KONKE_CDC + sn + ":" + RedisKeys.ADD_TEMPORARY_SCENE+ ":" +scene_id;
redisTemplate.opsForValue().set(redisKey, JSONUtil.toJsonStr(body),5*60, TimeUnit.SECONDS);
log.info("addScene..新增场景..result:{}",scene_id);
return scene_id+"";
}
}catch (Exception e){
e.printStackTrace();
throw new StatefulException(-20, "新增临时场景失败");
} }
} }
...@@ -598,7 +624,13 @@ public class KonkeIotUtils { ...@@ -598,7 +624,13 @@ public class KonkeIotUtils {
Object firstValue = firstEntry.getValue(); Object firstValue = firstEntry.getValue();
if("on".equalsIgnoreCase(firstKey)){ if("on".equalsIgnoreCase(firstKey)){
if("false".equalsIgnoreCase(firstValue.toString())){
return "OFF";
}else if("true".equalsIgnoreCase(firstValue.toString())){
return "ON";
}else{
return firstValue; return firstValue;
}
}else{ }else{
log.error("不支持的操作1:{}",JSONUtil.toJsonStr(operation)); log.error("不支持的操作1:{}",JSONUtil.toJsonStr(operation));
} }
......
...@@ -5,6 +5,9 @@ import org.springframework.stereotype.Component; ...@@ -5,6 +5,9 @@ import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/**
*
*/
@Component @Component
public class RedisCacheUtil { public class RedisCacheUtil {
......
...@@ -19,7 +19,7 @@ spring: ...@@ -19,7 +19,7 @@ spring:
min-idle: 0 # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最小空闲连接
cluster: cluster:
max-redirects: 3 max-redirects: 3
nodes: 172.17.14.1:7001,172.17.14.1:7002,172.17.14.1:7003,172.17.14.2:7001,172.17.14.2:7002,172.17.14.2:7003 nodes: 172.24.70.175:7101,172.24.70.175:7102,172.24.70.175:7103,172.24.70.176:7101,172.24.70.176:7102,172.24.70.176:7103
ai: ai:
mcp: mcp:
......
...@@ -9,6 +9,18 @@ spring: ...@@ -9,6 +9,18 @@ spring:
data: data:
mongodb: mongodb:
uri: mongodb://user002:konke2025@172.17.13.1:27017,172.17.13.2:27017,172.17.13.3:27017/konke_iot?authSource=konke_iot&authMechanism=SCRAM-SHA-1 uri: mongodb://user002:konke2025@172.17.13.1:27017,172.17.13.2:27017,172.17.13.3:27017/konke_iot?authSource=konke_iot&authMechanism=SCRAM-SHA-1
redis:
password: kknjredis
lettuce:
pool:
max-active: 8 # 连接池中的最大空闲连接
max-wait: 500 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池最大连接数(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
cluster:
max-redirects: 3
nodes: 172.17.14.1:7001,172.17.14.1:7002,172.17.14.1:7003,172.17.14.2:7001,172.17.14.2:7002,172.17.14.2:7003
ai: ai:
mcp: mcp:
server: server:
......
...@@ -44,3 +44,9 @@ ...@@ -44,3 +44,9 @@
## 示例引导: ## 示例引导:
用户输入:"帮我预约下午2点到4点的茶室" 用户输入:"帮我预约下午2点到4点的茶室"
期望输出:"预约成功" 或 "预约失败" 或 "你要预约的场所没有抵扣券,暂不支持AI购买,请手动购买" 期望输出:"预约成功" 或 "预约失败" 或 "你要预约的场所没有抵扣券,暂不支持AI购买,请手动购买"
##
2、当用户提出试用推荐的场景时,你需要根据获取到的临时场景ID{{#conversation.temporarySceneId#}}与家庭下的主机号,再调用mcp函数triggerScene来触发场景。
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