123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package service
- import (
- "encoding/json"
- "errors"
- "fmt"
- "github.com/gogf/gf/container/gmap"
- "github.com/gogf/gf/encoding/gjson"
- "sparrow/pkg/rpcs"
- "sparrow/pkg/server"
- service2 "sparrow/services/scene-service/internal/service/manager"
- )
- type SceneInfo struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Status int `json:"status"`
- SceneType string `json:"scene_type"`
- Config string `json:"config"`
- Action string `json:"action"`
- Time string `json:"time"`
- }
- type SceneService struct {
- scenes *gmap.HashMap // 场景ID到场景实例的映射
- timer TaskManager
- weather TaskManager
- deviceStatus TaskManager
- }
- func NewSceneService() *SceneService {
- return &SceneService{
- scenes: gmap.New(true),
- timer: service2.NewTimerSceneService(),
- weather: service2.NewWeatherSceneService(),
- deviceStatus: service2.NewDeviceSceneService(),
- }
- }
- type TaskManager interface {
- Add(config string) error
- Update(config string) error
- Remove(config string) error
- Start(config string) error
- Stop(config string) error
- }
- // getServiceByType 根据场景类型获取对应的服务实例
- func (m *SceneService) getServiceByType(sceneType string) (TaskManager, error) {
- switch sceneType {
- case "oneKey":
- return nil, nil
- case "timer":
- return m.timer, nil
- case "weather":
- return m.weather, nil
- case "deviceStatus":
- return m.deviceStatus, nil
- default:
- return nil, errors.New("不支持的场景类型: " + sceneType)
- }
- }
- func (m *SceneService) SubmitAction(args rpcs.ArgsSubmitSceneAction, reply *rpcs.ReplySubmitSceneAction) error {
- scene := SceneInfo{
- Id: args.Id,
- Name: args.Name,
- Status: args.Status,
- SceneType: args.SceneType,
- Config: args.Config,
- Action: args.Action,
- }
- srv, err := m.getServiceByType(scene.SceneType)
- if err != nil {
- server.Log.Errorf("不支持的场景类型: %s, 场景ID: %s", scene.SceneType, scene.Id)
- return err
- }
- switch scene.Action {
- case "add":
- err = srv.Add(scene.Config)
- if err != nil {
- return err
- }
- m.scenes.Set(scene.Id, scene)
- return m.saveSceneRedis(scene)
- case "remove":
- err = srv.Remove(scene.Config)
- if err != nil {
- server.Log.Errorf("delete scene-manager error: Id: %s, error: %v", scene.Id, err)
- }
- m.scenes.Remove(scene.Id)
- return m.delSceneRedis(scene)
- case "update":
- err = srv.Update(scene.Config)
- if err != nil {
- server.Log.Errorf("update scene-manager error: Id: %s, error: %v", scene.Id, err)
- return err
- }
- m.scenes.Set(scene.Id, scene)
- return m.saveSceneRedis(scene)
- case "start":
- err = srv.Start(scene.Config)
- if err != nil {
- server.Log.Errorf("start scene-manager error: Id: %s, error: %v", scene.Id, err)
- return err
- }
- scene.Status = 1
- m.scenes.Set(scene.Id, scene)
- return m.saveSceneRedis(scene)
- case "stop":
- err = srv.Stop(scene.Config)
- if err != nil {
- server.Log.Errorf("stop scene-manager error: Id: %s, error: %v", scene.Id, err)
- return err
- }
- scene.Status = 0
- m.scenes.Set(scene.Id, scene)
- return m.saveSceneRedis(scene)
- case "do":
- err = m.doAction(gjson.New(scene.Action).MustToJsonString())
- }
- return nil
- }
- func (m *SceneService) doAction(action string) error {
- var actions []*service2.Action
- err := json.Unmarshal([]byte(action), &actions)
- if err != nil {
- server.Log.Errorf("unmarshal actions error :%v", err)
- return err
- }
- return service2.NewTaskExecutor(actions).Do()
- }
- func (m *SceneService) saveSceneRedis(scene SceneInfo) error {
- sceneArgs := rpcs.ArgsScene{
- Key: fmt.Sprintf("scene-manager:%s:%s", scene.SceneType, scene.Id),
- SceneId: scene.Id,
- Config: scene.Config,
- }
- sceneReply := rpcs.ReplyGetDeviceOnlineStatus{}
- err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.SaveScene", sceneArgs, &sceneReply)
- if err != nil {
- server.Log.Errorf("save scene-manager error: Id: %s, error: %v", scene.Id, err)
- }
- return err
- }
- func (m *SceneService) delSceneRedis(scene SceneInfo) error {
- sceneArgs := rpcs.ArgsScene{
- Key: fmt.Sprintf("scene-manager:%s:%s", scene.SceneType, scene.Id),
- Config: scene.Config,
- }
- sceneReply := rpcs.ReplyGetDeviceOnlineStatus{}
- err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.DeleteScene", sceneArgs, &sceneReply)
- if err != nil {
- server.Log.Errorf("save scene-manager error: Id: %s, error: %v", scene.Id, err)
- }
- return err
- }
|