Commit 95f777a6 authored by 何金镒's avatar 何金镒

场景相关

parent 01fec03f
# mcp sse
## 高德地图
```js
349b29559f74c1805651a98cb3ba8aca
{
"server_name":{
"url":"https://mcp.amap.com/sse?key=349b29559f74c1805651a98cb3ba8aca",
"headers":{},
"timeout":60,
"sse_read_timeout":300
}
}
```
## 智家中控屏AI集成 功能需求:
- 智能设备AI控制
通过AI语音交互,业主可以用自然语音交互的方式更加便捷快速的控制户内的智能家居设备,及楼栋单元门。
- AI生成场景
通过AI语音交互,业主可以用自然语音交互的方式更加便捷快速的控制户内的智能家居场景,并快速生成场景。
```js
{
"场景名称" : "智能推荐",
"场景动作" : ""
}
```
- 访客邀请
通过智慧屏/APP/小程序的AI语音交互,可实现访客邀请。访客到达社区后,无感通过社区出入口,联动道闸开启。
- 智能会所管理
......
......@@ -85,3 +85,33 @@
- 支持的命令有:
1、OptCentralAcIndoorUnit(参数设置,可设置开关 on、风速 speed、模式 runModel、温度 temp),开关参数有true、false;风速参数有AUTO、LOW、MID、HIGH;模式参数有 AIR_SUPPLY、HOT、COLD、AUTO、DEHUMIDIFICATION;温度参数有16-30,步长为0.5,
如:{"on":false,"speed":"AUTO","runModel":"AIR_SUPPLY","temp":16.5}
## 空调
- 包含的设备类型operateId有:12001,12002,12003,12004,12005,12006,12007,12008,12009
- 支持的命令有:
- 支持的属性有:
```js
{
"power": {
"type": "bool",
"description": "电源开关"
},
"mode": {
"type": "enum",
"values": ["WIND", "HOT", "COLD", "DEHUMIDIFICATION"],
"description": "运行模式"
},
"setTemperature": {
"type": "int",
"unit": "°C",
"range": [5, 35],
"step": 1,
"description": "设定温度"
},
"fanSpeed": {
"type": "enum",
"values": ["LOW", "MID", "HIGH", "AUTO"],
"description": "风速"
}
}
```
......@@ -22,7 +22,7 @@ public class DeviceConstant {
* 设备类型 -- OID
*/
public final static Map<String, List<Integer>> device_model = Map.of(
"LIGHT", List.of(1,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,20,201,
"LIGHT", List.of(1,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,20,
201,492,493,501,502,503,504,505,506,507,508,509,510,511,513,514,515,516,517,518,519),
// "DIMMING_LIGHT",List.of(),
// "SWITCH",List.of(),//
......
package com.ikonke.konkeaialibabamcp.controller;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.ikonke.konkeaialibabamcp.controller.param.AddSceneParam;
import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
import com.ikonke.konkeaialibabamcp.utils.KonkeIotUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
......@@ -18,11 +20,15 @@ public class DeviceController {
@Autowired
private SycDeviceService sycDeviceService;
@Autowired
private KonkeIotUtils konkeIotServer;
@GetMapping("/findSycDeviceByCcu")
public JSONArray findSycDeviceByCcu(@RequestParam(name = "ccuName") String ccuName){
log.info("findSycDeviceByCcu..根据主机号查询设备..ccuName:{}",ccuName);
return sycDeviceService.findByCcu(ccuName,null);
public JSONArray findSycDeviceByCcu(@RequestParam(name = "ccuName") String ccuName,
@RequestParam(name = "type", required = false) Integer type,
@RequestParam(name = "capabilities", required = false) Integer capabilities){
log.info("findSycDeviceByCcu..根据主机号查询设备..ccuName:{},type:{},capabilities:{}",ccuName,type,capabilities);
return sycDeviceService.findByCcu(ccuName,type,capabilities);
}
@GetMapping("/synchronousDevice")
......@@ -32,4 +38,23 @@ public class DeviceController {
}
@PostMapping("/addScene")
public String addScene(@RequestParam(value = "ccuName") String ccuName,
@RequestParam(value = "ccuName")Integer roomId,
@RequestBody JSONObject actions) {
log.info("addScene..新增场景..ccuName:{}",ccuName);
return konkeIotServer.addScene(ccuName,actions);
}
@PostMapping("/addScene2")
public String addScene2(@RequestParam(name = "ccuName") String ccuName,
@RequestBody JSONObject addSceneParam) {
log.info("addScene..新增场景..ccuName:{}",addSceneParam);
return konkeIotServer.addScene(ccuName,addSceneParam);
}
}
package com.ikonke.konkeaialibabamcp.controller.param;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class AddSceneParam {
private String name;
private Integer roomId;
private List<SceneAction> actions;
}
@Data
class SceneAction {
private Integer devId;
private String typeId;
private Map<String, Object> operation;
}
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;
@Data
@TableName("`device_model`")
public class DeviceModel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("operateId")
private String operateId;
@TableField("model")
private String model;
@TableField("actions")
private String actions;
@TableField("capabilities")
private String capabilities;
@TableField("description")
private String description;
@TableField("additionalApplianceDetails")
private String additionalApplianceDetails;
@TableField("realType")
private String realType;
}
package com.ikonke.konkeaialibabamcp.mapper.mysql;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeviceModelMapper extends BaseMapper<DeviceModel> {
}
package com.ikonke.konkeaialibabamcp.service;
import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.exceptions.StatefulException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
......@@ -10,7 +13,9 @@ import com.ikonke.konkeaialibabamcp.entity.mongodb.Device;
import com.ikonke.konkeaialibabamcp.entity.mongodb.Region;
import com.ikonke.konkeaialibabamcp.entity.mongodb.Room;
import com.ikonke.konkeaialibabamcp.entity.mongodb.Scene;
import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel;
import com.ikonke.konkeaialibabamcp.entity.mysql.SynDevice;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.IDeviceModelService;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ISynDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -27,12 +32,16 @@ import java.util.List;
@Component
public class SycDeviceService {
public static Cache<String, String> device_model_cache = CacheUtil.newLRUCache(1024);
@Autowired
private ISynDeviceService synDeviceService;
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private IDeviceModelService deviceModelService;
public JSONArray findByCcu(String ccuName,Integer type){
public JSONArray findByCcu(String ccuName,Integer type,Integer capabilities){
log.info("findByCcu..根据主机号查询设备..ccuName:{}",ccuName);
QueryWrapper<SynDevice> wrapper = new QueryWrapper<>();
wrapper.eq("ccuId", ccuName);
......@@ -46,13 +55,30 @@ public class SycDeviceService {
jsonArray = new JSONArray();
for (SynDevice synDevice : list) {
JSONObject jsonObject = new JSONObject();
String operateId = synDevice.getOperateId();
jsonObject.set("deviceId", synDevice.getDeviceId());
jsonObject.set("deviceName", synDevice.getDeviceName());
jsonObject.set("roomId", synDevice.getRoomId());
jsonObject.set("roomName", synDevice.getRoomName());
jsonObject.set("typeId", synDevice.getOperateId());
jsonObject.set("typeId", operateId);
jsonObject.set("model", synDevice.getModel());
if(capabilities != null && capabilities == 2){
String deviceModel_json_str = device_model_cache.get(operateId);
if(StrUtil.isBlank(deviceModel_json_str)){
QueryWrapper<DeviceModel> deviceModel_wrapper = new QueryWrapper<>();
deviceModel_wrapper.eq("operateId", operateId);
List<DeviceModel> model_list = deviceModelService.list(deviceModel_wrapper);
if(!model_list.isEmpty()){
DeviceModel deviceModel = model_list.get(0);
device_model_cache.put(operateId, JSONUtil.toJsonStr(deviceModel));
jsonObject.set("capabilities", deviceModel.getCapabilities());
}
}else{
DeviceModel bean = JSONUtil.toBean(deviceModel_json_str, DeviceModel.class);
jsonObject.set("capabilities", bean.getCapabilities());
}
}
jsonArray.set(jsonObject);
}
}
......@@ -90,13 +116,14 @@ public class SycDeviceService {
}
@NotNull
private static List<SynDevice> getSynDevices(String ccuName, List<Device> device, List<Room> rooms,List<Scene> scenes) {
private List<SynDevice> getSynDevices(String ccuName, List<Device> device, List<Room> rooms,List<Scene> scenes) {
List<SynDevice> synDeviceList = new ArrayList<>();
for(Device d : device){
if(d.getRoomId() == -1){
continue;
}
String model = DeviceConstant.getDeviceType(d.getRealType());
String model = this.getDeviceType(d.getRealType());
if(!"UNKNOWN".equals(model)){
SynDevice synDevice = new SynDevice();
synDevice.setDeviceId(d.getDevId());
......@@ -141,4 +168,22 @@ public class SycDeviceService {
return synDeviceList;
}
public String getDeviceType(Integer oid){
String deviceModel_json_str = device_model_cache.get(String.valueOf(oid));
if(StrUtil.isBlank(deviceModel_json_str)){
QueryWrapper<DeviceModel> deviceModel_wrapper = new QueryWrapper<>();
deviceModel_wrapper.eq("operateId", oid);
List<DeviceModel> model_list = deviceModelService.list(deviceModel_wrapper);
if(!model_list.isEmpty()){
DeviceModel deviceModel = model_list.get(0);
device_model_cache.put(String.valueOf(oid), JSONUtil.toJsonStr(deviceModel));
return deviceModel.getModel();
}
}else{
DeviceModel bean = JSONUtil.toBean(deviceModel_json_str, DeviceModel.class);
return bean.getModel();
}
return "UNKNOWN";
}
}
package com.ikonke.konkeaialibabamcp.service.mysqlservice;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel;
public interface IDeviceModelService extends IService<DeviceModel> {
}
package com.ikonke.konkeaialibabamcp.service.mysqlservice.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ikonke.konkeaialibabamcp.entity.mysql.DeviceModel;
import com.ikonke.konkeaialibabamcp.mapper.mysql.DeviceModelMapper;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.IDeviceModelService;
import org.springframework.stereotype.Service;
@Service
public class DeviceModelServiceImpl extends ServiceImpl<DeviceModelMapper, DeviceModel> implements IDeviceModelService {
}
......@@ -2,9 +2,11 @@ package com.ikonke.konkeaialibabamcp.utils;
import cn.hutool.core.exceptions.StatefulException;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ikonke.konkeaialibabamcp.constant.DeviceConstant;
import com.ikonke.konkeaialibabamcp.controller.param.AddSceneParam;
import com.ikonke.konkeaialibabamcp.entity.mongodb.DeviceStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
......@@ -487,6 +489,27 @@ public class KonkeIotUtils {
return result2;
}
/**
* 获取场景
*/
public String getScene(String ccuName, String sceneId){
String url = baseUrl + "/2.0/ccu/" + ccuName + "/scenes?actions=true&id="+sceneId;
log.info("KonkeIotServer getScene url {}, ccuName {},sceneId:{}", url, ccuName,sceneId);
String body = HttpRequest.get(url)
.header("appId", appId)
.header("appKey", appKey)
.timeout(20000)
.execute().body();
JSONObject json_response = JSONUtil.parseObj(body);
if(json_response.getBool("success")){
JSONArray data = json_response.getJSONArray("data");
JSONObject data_json = data.getJSONObject(0);
return data_json.toString();
}else{
throw new StatefulException(-20, "获取场景失败");
}
}
/**
* 删除场景
*/
......@@ -500,6 +523,7 @@ public class KonkeIotUtils {
}
/**
* POST 'https://iot.ikonke.com:4432/2.0/ccu/CCU_00001/scenes'
* {
* "name": "场景名称",
* "roomId": 2,
......@@ -514,9 +538,36 @@ public class KonkeIotUtils {
* }
* ]
* }
*
* 1、验证参数
* 2、保存场景
* 3、返回场景ID
* 4、返回场景getScene
*
* 5、这个场景应该是一个临时场景,若用户没有说保存,应该删除掉
*/
public String addScene(String ccuName,Integer roomId,String sceneName){
return "";
public String addScene(String ccuName,JSONObject scene){
AddSceneParam bean = JSONUtil.toBean(scene, AddSceneParam.class);
// String url = baseUrl + "/2.0/ccu/" + ccuName + "/scenes";
// log.info("addScene..新增场景..ccuName:{},scene:{}",ccuName,scene.toString());
// String result = HttpRequest.post(url)
// .header("appId", appId)
// .header("appKey", appKey)
// .body(scene.toString())
// .execute().body();
//
// log.info("addScene..新增场景..result:{}",result);
// JSONObject response = JSONUtil.parseObj(result);
// if(!response.getBool("success")){
// throw new StatefulException(-1, response.getStr("message"));
// }else{
// return response.getStr("data");
// }
return "";
}
/**
......
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