package scene import ( "context" "github.com/gogf/gf/database/gredis" ) const ( timerScenePrefix = "scene:timer:*" deviceScenePrefix = "scene:device_status:*" weatherScenePrefix = "scene:weather:*" scenePrefix = "scene:*" dataExpires = 7200 ) type GetSceneParams struct { Type string `json:"type"` Name string `json:"name"` DeviceCode string `json:"device_code"` } type InfoScene struct { SceneId string `json:"scene_id"` Conditions []*Conditions `json:"conditions"` Actions []*Action `json:"actions"` } type Conditions struct { TaskId string `json:"task_id"` Times int `json:"times"` // 执行次数 -1 表示无限次 Cron string `json:"cron"` Key string `json:"key"` // redis key DeviceType string `json:"device_type"` // 设备类型 DeviceId string `json:"device_id"` // 设备id SubDeviceId string `json:"sub_device_id"` // 子设备id FieldType int `json:"field_type"` // 字段类型 1字符串 2数值 Field string `json:"field"` // 字段名 TargetValue string `json:"target_value"` // 值 Operator int `json:"operator"` // 比较类型 数值比较 1 > 2 >= 3 = 4 <= 5 < 6 != Location string `json:"location"` // 地点 } type Action struct { DeviceID string `json:"device_id"` // 设备ID SubDeviceId string `json:"sub_device_id"` // 实体子设备Id,如果需要 ActionExecutor string `json:"action_executor"` // 动作对象类型 ExecutorProperty *TaskExecutorProperty `json:"executor_property"` // 动作执行明细 PlcPubMessage *PlcPubMessage `json:"plc_pub_message"` // PLC消息 } // TaskExecutorProperty 定时任务执行动作执行参数 type TaskExecutorProperty struct { FunctionCode string `json:"function_code"` FunctionValue map[string]interface{} `json:"function_value"` DelaySeconds int64 `json:"delay_seconds"` } type PlcPubMessage struct { Topic string `json:"topic"` Payload []byte `json:"payload"` } type AllSceneResult struct { Total int `json:"total"` Data []*InfoScene `json:"data"` } type Info struct { Key string `json:"key"` SceneId string `json:"scene_id"` TaskId string `json:"task_id"` Config string `json:"config"` } type Manager struct { redisClient *gredis.Redis ctx context.Context } func NewSceneManager(host string, port int) *Manager { red := gredis.New(&gredis.Config{ Host: host, Port: port, Db: 2, MaxActive: 100, }) ctx := context.Background() helper := &Manager{ redisClient: red, ctx: ctx, } return helper } func (a *Manager) SaveScene(info *Info) error { _, err := a.redisClient.DoVar("SET", info.Key, info.Config) if err != nil { return err } //_, err = a.redisClient.Do("EXPIRE", info.Key, -1) //if err != nil { // return err //} return nil } func (a *Manager) GetScene(key string) (string, error) { // get status from redis result, err := a.redisClient.DoVar("GET", key) if err != nil { return "", err } return result.String(), nil } func (a *Manager) DeleteScene(key string) error { // get status from redis _, err := a.redisClient.Do("DEL", key) if err != nil { return err } return nil } // GetAllScenesPage 查询定时场景 func (a *Manager) GetAllScenesPage(code string, pi, ps int) (AllSceneResult, error) { var key string switch code { case "time": key = timerScenePrefix case "device": key = deviceScenePrefix case "weather": key = weatherScenePrefix default: key = scenePrefix } var result AllSceneResult // 使用KEYS命令获取所有匹配前缀的键s keys, err := a.redisClient.DoVar("KEYS", key) if err != nil { return result, err } // 检查是否有数据 if keys.IsEmpty() { return result, nil } var start, end int // 转换为字符串切片 keyList := keys.Strings() result.Total = len(keyList) if len(keyList) > 0 { start = (pi - 1) * ps end = pi*ps - 1 if end > len(keyList)-1 { end = len(keyList) - 1 } } // 存储所有结果 scenes := make([]*InfoScene, 0) var scene InfoScene for i := start; i <= end; i++ { r, err := a.redisClient.DoVar("GET", keyList[i]) if err != nil { return result, err } err = r.Struct(&scene) if err != nil { return result, err } scenes = append(scenes, &scene) } return result, nil } // GetAllScenes 查询定时场景 func (a *Manager) GetAllScenes(code string) ([]*InfoScene, error) { var key string switch code { case "time": key = timerScenePrefix case "device": key = deviceScenePrefix case "weather": key = weatherScenePrefix default: key = scenePrefix } // 使用KEYS命令获取所有匹配前缀的键s keys, err := a.redisClient.DoVar("KEYS", key) if err != nil { return nil, err } // 检查是否有数据 if keys.IsEmpty() { return nil, nil } // 转换为字符串切片 keyList := keys.Strings() // 存储所有结果 scenes := make([]*InfoScene, 0) var scene InfoScene for _, v := range keyList { r, err := a.redisClient.DoVar("GET", v) if err != nil { return nil, err } err = r.Struct(&scene) if err != nil { return nil, err } scenes = append(scenes, &scene) } return scenes, nil }