Bläddra i källkod

更新设备状态判断条件

liuxiulin 2 månader sedan
förälder
incheckning
dcc6f0aaee

+ 23 - 0
pkg/deviceStatus/deviceStatus.go

@@ -88,3 +88,26 @@ func (mgr *DevStatusManager) GetDeviceStatusByKey(key string) (string, error) {
 	}
 	return result.String(), nil
 }
+
+func (mgr *DevStatusManager) GetWeatherInfo(location string) (string, error) {
+	key := "weather:city:" + location
+	result, err := mgr.redisClient.DoVar("GET", key)
+	if err != nil {
+		return "", err
+	}
+	return result.String(), nil
+}
+
+func (mgr *DevStatusManager) SetWeatherInfo(location string, info string) error {
+	key := "weather:city:" + location
+	_, err := mgr.redisClient.DoVar("SET", key, info)
+	if err != nil {
+		return err
+	}
+
+	_, err = mgr.redisClient.Do("EXPIRE", key, 3600)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 13 - 0
pkg/rpcs/access.go

@@ -74,3 +74,16 @@ type ReplyStatus struct {
 type ReplayInfo struct {
 	Info string
 }
+
+type ArgsGetWeather struct {
+	Location string
+}
+
+type ReplayWeatherInfo struct {
+	Info string
+}
+
+type ArgsSetWeather struct {
+	Location string
+	Info     string
+}

+ 2 - 1
pkg/rpcs/devicemanager.go

@@ -3,6 +3,7 @@ package rpcs
 import (
 	"sparrow/pkg/deviceAlarm"
 	"sparrow/pkg/online"
+	"sparrow/pkg/scene"
 )
 
 type ArgsGenerateDeviceAccessToken ArgsDeviceId
@@ -88,5 +89,5 @@ type ReplyScene struct {
 }
 
 type ReplyScenes struct {
-	Result string
+	Result []*scene.InfoScene
 }

+ 35 - 20
pkg/scene/scene.go

@@ -6,7 +6,7 @@ import (
 )
 
 const (
-	scenePrefix = "scene-manager:alarm:"
+	scenePrefix = "scene:"
 	dataExpires = 7200
 )
 
@@ -85,22 +85,37 @@ func (a *Manager) DeleteScene(key string) error {
 	return nil
 }
 
-// ScanKeys 扫描所有匹配的key
-//func (a *Manager) ScanKeys(pattern string) ([]string, error) {
-//	var cursor uint64
-//	var allKeys []string
-//	for {
-//		// 扫描一批匹配的key
-//		_, err := a.redisClient.Do("Scan", cursor, pattern, 100)
-//		if err != nil {
-//			return nil, err
-//		}
-//		allKeys = append(allKeys, keys...)
-//		cursor = nextCursor
-//		// 游标归0时结束迭代
-//		if cursor == 0 {
-//			break
-//		}
-//	}
-//	return allKeys, nil
-//}
+// GetAllScenes 查询所有场景信息s
+func (a *Manager) GetAllScenes() ([]*InfoScene, error) {
+	// 使用KEYS命令获取所有匹配前缀的键
+	keys, err := a.redisClient.DoVar("KEYS", scenePrefix+"*")
+	if err != nil {
+		return nil, err
+	}
+
+	// 检查是否有数据
+	if keys.IsEmpty() {
+		return nil, nil
+	}
+
+	// 转换为字符串切片
+	keyList := keys.Strings()
+
+	// 存储所有结果
+	scenes := make([]*InfoScene, 0)
+	var scene InfoScene
+	for _, key := range keyList {
+
+		result, err := a.redisClient.DoVar("GET", key)
+		if err != nil {
+			return nil, err
+		}
+		err = result.Struct(&scene)
+		if err != nil {
+			return nil, err
+		}
+		scenes = append(scenes, &scene)
+	}
+
+	return scenes, nil
+}

+ 18 - 3
services/devicemanager/manager.go

@@ -160,6 +160,21 @@ func (dm *DeviceManager) GetDeviceStatusByKey(args rpcs.ArgsGetStatus, reply *rp
 	return nil
 }
 
+func (dm *DeviceManager) GetWeatherInfo(args rpcs.ArgsGetWeather, reply *rpcs.ReplayWeatherInfo) error {
+	info, err := dm.statusManager.GetWeatherInfo(args.Location)
+	if err != nil {
+		return err
+	}
+	if info != "" {
+		reply.Info = info
+	}
+	return nil
+}
+
+func (dm *DeviceManager) SetWeatherInfo(args rpcs.ArgsSetWeather, reply *rpcs.ReplyEmptyResult) error {
+	return dm.statusManager.SetWeatherInfo(args.Location, args.Info)
+}
+
 func (dm *DeviceManager) SetAlarm(args rpcs.ArgsAlarmInfo, reply *rpcs.ArgsAlarmInfo) error {
 	return dm.alarmManager.SetAlarm(&deviceAlarm.AlarmParams{
 		DeviceCode:      args.DeviceCode,
@@ -183,12 +198,12 @@ func (dm *DeviceManager) DelAlarm(args rpcs.ArgsGetAlarm, reply *rpcs.ReplayAlar
 	return dm.alarmManager.DeleteAlarm(args.DeviceCode)
 }
 
-func (dm *DeviceManager) GetAllScene(args rpcs.ArgsScene, reply *rpcs.ReplyScenes) error {
-	result, err := dm.sceneManager.GetScene(args.Key)
+func (dm *DeviceManager) GetAllScenes(args rpcs.ArgsScene, reply *rpcs.ReplyScenes) error {
+	result, err := dm.sceneManager.GetAllScenes()
 	if err != nil {
 		return err
 	}
-	if result != "" {
+	if len(result) > 0 {
 		reply.Result = result
 	}
 	return nil

+ 19 - 0
services/knowoapi/controllers/device.go

@@ -6,6 +6,7 @@ import (
 	"io"
 	"sparrow/pkg/models"
 	"sparrow/pkg/rpcs"
+	"sparrow/pkg/scene"
 	"sparrow/pkg/server"
 	"sparrow/services/knowoapi/services"
 	"strconv"
@@ -516,3 +517,21 @@ func (a *DeviceController) PostSendcommand() {
 	}
 	done(a.Ctx, params.DeviceId)
 }
+
+// GetAllScenes 获取所有的场景
+// POST /device/allscenes
+func (a *DeviceController) GetAllScenes() {
+	// proid, err := a.Ctx.URLParamInt("proid")
+	// if err != nil {
+	// 	proid = 0
+	// }
+	params := new(scene.GetSceneParams)
+	datas, err := a.Service.GetScenes(*params)
+	if err != nil {
+		responseError(a.Ctx, ErrDatabase, err.Error())
+		return
+	}
+	done(a.Ctx, map[string]interface{}{
+		"chart": datas,
+	})
+}

+ 3 - 2
services/scene-service/internal/service/manager/device_status.go

@@ -24,6 +24,7 @@ type DeviceSceneConfig struct {
 
 // DeviceCondition 设备场景配置
 type DeviceCondition struct {
+	Key         string `json:"key"`           // redis key
 	DeviceType  string `json:"device_type"`   // 设备类型
 	DeviceId    string `json:"device_id"`     // 设备id
 	SubDeviceId string `json:"sub_device_id"` // 子设备id
@@ -142,7 +143,7 @@ func (d *DeviceSceneService) checkDeviceCondition(config DeviceSceneConfig) (boo
 	for _, v := range config.Conditions {
 		fmt.Printf("检查设备状态:%s\n", v.DeviceId)
 		var args rpcs.ArgsGetStatus
-		args.Key = fmt.Sprintf("device:%s:status:%s%s", v.DeviceType, v.DeviceId, v.SubDeviceId)
+		args.Key = v.Key
 		var reply rpcs.ReplyStatus
 		err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetDeviceStatusByKey", args, &reply)
 		if err != nil {
@@ -151,7 +152,7 @@ func (d *DeviceSceneService) checkDeviceCondition(config DeviceSceneConfig) (boo
 		}
 		j := gjson.New(reply.Status)
 		// 判断是否满足条件并填入到result
-		fmt.Printf("判断条件:target_value:%s,value:%s,type:%d,operator:%d", v.TargetValue, j.Get(v.Field), v.FieldType, v.Operator)
+		fmt.Printf("判断条件:target_value:%s,value:%s,type:%d,operator:%d\n", v.TargetValue, j.Get(v.Field), v.FieldType, v.Operator)
 		results = append(results, utils.CheckValue(v.TargetValue, j.Get(v.Field), v.FieldType, v.Operator))
 	}
 	switch config.DecisionExpr {

+ 38 - 1
services/scene-service/internal/service/manager/weather.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"github.com/gogf/gf/container/gmap"
 	"github.com/gogf/gf/encoding/gjson"
+	"sparrow/pkg/rpcs"
 	"sparrow/pkg/server"
 	"sparrow/pkg/utils"
 	"time"
@@ -163,9 +164,45 @@ func (w *WeatherSceneService) checkWeatherCondition(config WeatherSceneConfig) (
 }
 
 func getWeatherInfo(location string) (map[string]interface{}, error) {
+
+	// redis获取天气数据
+	args := rpcs.ArgsGetWeather{Location: location}
+	reply := rpcs.ReplayWeatherInfo{}
+	err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetWeatherInfo", args, &reply)
+	if err != nil {
+		server.Log.Errorf("天气状态获取失败:%v", err)
+		return nil, err
+	}
+
+	if reply.Info != "" {
+		info := gjson.New(reply.Info)
+		// 判断数据是否过期
+		if !info.GetTime("last_update").Before(time.Now().Add(-time.Minute * 15)) {
+			return info.Map(), nil
+		}
+		return nil, errors.New("获取天气数据失败")
+	}
+
 	weatherInfo, err := weather.GetWeatherInfo(location, "SgqF9ZGBUj7R0dLAb")
 	if err != nil {
 		return nil, err
 	}
-	return gjson.New(weatherInfo).Map(), nil
+	j := gjson.New(weatherInfo)
+	err = redisSaveWeatherInfo(location, j.MustToJsonString())
+	return j.Map(), nil
+
+}
+
+func redisSaveWeatherInfo(location string, info string) error {
+	args := rpcs.ArgsSetWeather{
+		Location: location,
+		Info:     info,
+	}
+	reply := rpcs.ReplySetStatus{}
+	err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.SetWeatherInfo", args, &reply)
+	if err != nil {
+		server.Log.Errorf("天气状态获取失败:%v", err)
+		return err
+	}
+	return nil
 }