浏览代码

add scene his

liuxiulin 2 周之前
父节点
当前提交
b647833ee9

+ 29 - 0
pkg/models/scene_his.go

@@ -0,0 +1,29 @@
+package models
+
+import (
+	"github.com/jinzhu/gorm"
+)
+
+// SceneHis device model
+// device is a product instance, which is managed by our platform
+type SceneHis struct {
+	gorm.Model
+	RecordId    string `gorm:"column:record_id;size:32;index"`
+	SceneID     string `gorm:"column:scene_id;size:32;index"`
+	DeviceId    string `gorm:"column:device_id;size:20;index"`
+	SubDeviceId string `gorm:"column:sub_device_id;size:20;index"`
+	Cmd         string `gorm:"column:cmd;size:20;"`
+	Params      string `sql:"type:varchar(200);"`
+	Topic       string `sql:"type:varchar(200);"`
+	Payload     string `sql:"type:varchar(200);"`
+}
+
+type SceneHisQuery struct {
+	Device
+	ProductName string
+}
+
+// Validate 验证
+func (a *SceneHis) Validate() error {
+	return nil
+}

+ 2 - 0
pkg/rpcs/devicemanager.go

@@ -73,12 +73,14 @@ type ReplayAlarm struct {
 }
 
 type ArgsScene struct {
+	SceneType     string
 	Key           string
 	SceneId       string
 	Name          string
 	ConditionDesc string
 	ActionDesc    string
 	Config        string
+	Status        int
 	Time          time.Time
 }
 

+ 4 - 10
pkg/scene/scene.go

@@ -21,12 +21,15 @@ type GetSceneParams struct {
 }
 
 type InfoScene struct {
+	Id            string    `json:"id"`
 	Key           string    `json:"key"`
 	Name          string    `json:"name"`
+	SceneType     string    `json:"scene_type"`
 	ActionDesc    string    `json:"action_desc"`
 	ConditionDesc string    `json:"condition_desc"`
 	SceneId       string    `json:"scene_id"`
 	Config        string    `json:"config"`
+	Status        int       `json:"status"`
 	Time          time.Time `json:"time"`
 }
 
@@ -34,15 +37,6 @@ type AllSceneResult struct {
 	Total int          `json:"total"`
 	Data  []*InfoScene `json:"data"`
 }
-type Info struct {
-	Key           string    `json:"key"`
-	Name          string    `json:"name"`
-	ActionDesc    string    `json:"action_desc"`
-	ConditionDesc string    `json:"condition_desc"`
-	SceneId       string    `json:"scene_id"`
-	Config        string    `json:"config"`
-	Time          time.Time `json:"time"`
-}
 
 type Manager struct {
 	redisClient *gredis.Redis
@@ -64,7 +58,7 @@ func NewSceneManager(host string, port int) *Manager {
 	return helper
 }
 
-func (a *Manager) SaveScene(info *Info) error {
+func (a *Manager) SaveScene(info *InfoScene) error {
 	_, err := a.redisClient.DoVar("SET", info.Key, info)
 	if err != nil {
 		return err

+ 2 - 1
services/devicemanager/manager.go

@@ -233,13 +233,14 @@ func (dm *DeviceManager) GetAllScenes(args rpcs.ArgsGetAllScene, reply *rpcs.Rep
 }
 
 func (dm *DeviceManager) SaveScene(args rpcs.ArgsScene, reply *rpcs.ReplyScene) error {
-	return dm.sceneManager.SaveScene(&scene.Info{
+	return dm.sceneManager.SaveScene(&scene.InfoScene{
 		Key:           args.Key,
 		SceneId:       args.SceneId,
 		ConditionDesc: args.ConditionDesc,
 		ActionDesc:    args.ActionDesc,
 		Name:          args.Name,
 		Config:        args.Config,
+		Status:        args.Status,
 		Time:          args.Time,
 	})
 }

+ 87 - 0
services/knowoapi/controllers/scene_his.go

@@ -0,0 +1,87 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12"
+	"sparrow/pkg/models"
+	"sparrow/services/knowoapi/services"
+)
+
+// SceneHisController api
+type SceneHisController struct {
+	Ctx     iris.Context
+	Service services.SceneHisService
+	Token   Token
+}
+
+// Post post
+// POST /SceneHis
+func (a *SceneHisController) Post() {
+	ptl := new(models.SceneHis)
+	if err := parseBody(a.Ctx, ptl); err != nil {
+		badRequest(a.Ctx, err)
+		return
+	}
+	err := a.Service.Create(ptl)
+	if err != nil {
+		responseError(a.Ctx, ErrDatabase, err.Error())
+		return
+	}
+	done(a.Ctx, ptl)
+}
+
+// Delete delete
+// DELETE /user/SceneHis
+func (a *SceneHisController) Delete() {
+	SceneHis := new(models.SceneHis)
+	if err := parseBody(a.Ctx, SceneHis); err != nil {
+		badRequest(a.Ctx, err)
+		return
+	}
+	if err := a.Service.Delete(SceneHis); err != nil {
+		responseError(a.Ctx, ErrDatabase, err.Error())
+		return
+	}
+	done(a.Ctx, "删除成功")
+}
+
+// Put 更新
+// PUT /user/SceneHis
+func (a *SceneHisController) Put() {
+	params := new(models.SceneHis)
+	if err := parseBody(a.Ctx, params); err != nil {
+		badRequest(a.Ctx, err)
+		return
+	}
+	if err := a.Service.Update(params); err != nil {
+		responseError(a.Ctx, ErrDatabase, err.Error())
+		return
+	}
+	done(a.Ctx, "已保存")
+}
+
+// Get  SceneHis
+// GET /user/SceneHis?pi=&ps=&name=&version
+func (a *SceneHisController) Get() {
+	pi, err := a.Ctx.URLParamInt("pi")
+	if err != nil {
+		badRequest(a.Ctx, err)
+		return
+	}
+	ps, err := a.Ctx.URLParamInt("ps")
+	if err != nil {
+		badRequest(a.Ctx, err)
+		return
+	}
+	deviceId := a.Ctx.URLParam("device_id")
+
+	datas, tSceneHisl, err := a.Service.Query(pi, ps, deviceId)
+	if err != nil {
+		responseError(a.Ctx, ErrDatabase, err.Error())
+		return
+	}
+
+	done(a.Ctx, map[string]interface{}{
+		"list":       datas,
+		"tSceneHisl": tSceneHisl,
+	})
+}

+ 2 - 0
services/knowoapi/model/all.go

@@ -18,6 +18,7 @@ type All struct {
 	RuleChain   *RuleChain
 	RuleNode    *RuleNode
 	Ota         *Ota
+	SceneHis    *SceneHis
 }
 
 // Init 初始化所有model
@@ -36,5 +37,6 @@ func (a *All) Init(db *gorm.DB) *All {
 	a.RuleChain = new(RuleChain).Init(db)
 	a.RuleNode = new(RuleNode).Init(db)
 	a.Ota = new(Ota).Init(db)
+	a.SceneHis = new(SceneHis).Init(db)
 	return a
 }

+ 74 - 0
services/knowoapi/model/scene_his.go

@@ -0,0 +1,74 @@
+package model
+
+import (
+	"fmt"
+	"sparrow/pkg/models"
+
+	"github.com/jinzhu/gorm"
+)
+
+// SceneHis model
+type SceneHis struct {
+	db *gorm.DB
+}
+
+// Init init SceneHis
+func (a *SceneHis) Init(db *gorm.DB) *SceneHis {
+	a.db = db
+	return a
+}
+
+// Query query all roles
+func (a *SceneHis) Query(pi, ps int, deviceId string) (datas []models.SceneHis, tSceneHisl int, err error) {
+	tx := a.db.Where("1=1")
+	if deviceId != "" {
+		tx = tx.Where("version like ?", "%"+deviceId+"%")
+	}
+
+	err = tx.Limit(ps).Offset((pi - 1) * ps).Find(&datas).Error
+	err = tx.Model(&models.SceneHis{}).Count(&tSceneHisl).Error
+	return
+}
+
+// Get 获取数据内容
+func (a *SceneHis) Get(vendorId string, recordId string) (data models.SceneHis, err error) {
+	cache := getCache()
+	key := fmt.Sprintf("SceneHisId:%s", recordId)
+	if v, ok := cache.Get(key); ok {
+		_d := v.(*models.SceneHis)
+		data = *_d
+	} else {
+		err = a.db.Where("vendor_id = ? and record_id = ?", vendorId, recordId).First(&data).Error
+		if err == nil {
+			cache.Set(key, &data)
+		}
+	}
+	return
+}
+
+// Create 创建
+func (a *SceneHis) Create(SceneHis *models.SceneHis) error {
+	return a.db.Save(SceneHis).Error
+
+}
+
+// Delete delete
+func (a *SceneHis) Delete(SceneHis *models.SceneHis) error {
+	cache := getCache()
+	key := fmt.Sprintf("SceneHis:%d", SceneHis.ID)
+	if _, ok := cache.Get(key); ok {
+		cache.Delete(key)
+	}
+	return a.db.Delete(SceneHis).Error
+}
+
+// Update update
+func (a *SceneHis) Update(SceneHis *models.SceneHis) (data models.SceneHis, err error) {
+	cache := getCache()
+	key := fmt.Sprintf("SceneHis:%d", SceneHis.ID)
+	if _, ok := cache.Get(key); ok {
+		cache.Delete(key)
+	}
+	err = a.db.Model(&data).Update(SceneHis).Error
+	return
+}

+ 4 - 0
services/knowoapi/router.go

@@ -54,6 +54,7 @@ func registerRouters(srv *iris.Application, models *model.All, gen *generator.Ke
 	subDeviceService := services.NewSubDeviceService(models)
 	fileService := services.NewFileService()
 	otaService := services.NewOtaService(models)
+	sceneHisService := services.NewSceneHisService(models)
 	v1router := srv.Party("/api/v1")
 
 	// 登陆,注册
@@ -103,4 +104,7 @@ func registerRouters(srv *iris.Application, models *model.All, gen *generator.Ke
 	// subDevice api
 	subDeviceAPI := mvc.New(userRouter).Party("/sub_device")
 	subDeviceAPI.Register(subDeviceService).Handle(new(controllers.SubDeviceController))
+
+	sceneHisAPI := mvc.New(userRouter).Party("/scene_his")
+	sceneHisAPI.Register(sceneHisService).Handle(new(controllers.SceneHisController))
 }

+ 48 - 0
services/knowoapi/services/scene_his.go

@@ -0,0 +1,48 @@
+package services
+
+import (
+	"github.com/gogf/gf/util/guid"
+	"sparrow/pkg/models"
+	"sparrow/services/knowoapi/model"
+)
+
+type SceneHisService interface {
+	Create(*models.SceneHis) error
+	Delete(*models.SceneHis) error
+	Update(*models.SceneHis) error
+	Query(int, int, string) ([]models.SceneHis, int, error)
+	Get(string, string) (models.SceneHis, error)
+}
+
+type sceneHisService struct {
+	models *model.All
+}
+
+// NewSceneHisService new Ota manager
+func NewSceneHisService(models *model.All) SceneHisService {
+	return sceneHisService{
+		models: models,
+	}
+}
+
+func (a sceneHisService) Query(pi, ps int, deviceId string) ([]models.SceneHis, int, error) {
+	return a.models.SceneHis.Query(pi, ps, deviceId)
+}
+
+func (a sceneHisService) Get(vendorId, recordId string) (models.SceneHis, error) {
+	return a.models.SceneHis.Get(vendorId, recordId)
+}
+
+func (a sceneHisService) Create(SceneHis *models.SceneHis) error {
+	SceneHis.RecordId = guid.S()
+	return a.models.SceneHis.Create(SceneHis)
+}
+
+func (a sceneHisService) Delete(SceneHis *models.SceneHis) error {
+	return a.models.SceneHis.Delete(SceneHis)
+}
+
+func (a sceneHisService) Update(SceneHis *models.SceneHis) error {
+	_, err := a.models.SceneHis.Update(SceneHis)
+	return err
+}

+ 9 - 0
services/registry/registry.go

@@ -535,6 +535,15 @@ func (r *Registry) CreateEvent(args *models.Event, reply *rpcs.ReplyEmptyResult)
 	return db.Save(args).Error
 }
 
+// CreateSceneHis create sceneHis
+func (r *Registry) CreateSceneHis(args *models.SceneHis, reply *rpcs.ReplyEmptyResult) error {
+	db, err := getDB()
+	if err != nil {
+		return err
+	}
+	return db.Save(args).Error
+}
+
 // CreateDeviceNetConfig 创建设备配网信息
 func (r *Registry) CreateDeviceNetConfig(args *models.DeviceNetConfig, reply *rpcs.ReplyEmptyResult) error {
 	db, err := getDB()

+ 1 - 1
services/scene-service/internal/service/manager/device_status.go

@@ -125,7 +125,7 @@ func (d *DeviceSceneService) monitorTask(config DeviceSceneConfig) {
 				server.Log.Errorf("compare weather condition error :%s", err.Error())
 			}
 			if result {
-				if err = NewTaskExecutor(config.Actions).Do(); err != nil {
+				if err = NewTaskExecutor(config.Actions).Do(config.SceneId); err != nil {
 					server.Log.Errorf("weather do taskid :%s error:%s", config.SceneId, err.Error())
 				}
 			}

+ 23 - 1
services/scene-service/internal/service/manager/executer.go

@@ -2,6 +2,9 @@ package manager
 
 import (
 	"fmt"
+	"github.com/gogf/gf/encoding/gjson"
+	"github.com/gogf/gf/util/guid"
+	"sparrow/pkg/models"
 	"sparrow/pkg/rpcs"
 	"sparrow/pkg/server"
 	"time"
@@ -47,12 +50,17 @@ func NewTaskExecutor(actions []*Action) *TaskExecutor {
 	}
 }
 
-func (a *TaskExecutor) Do() error {
+func (a *TaskExecutor) Do(id string) error {
 	for _, action := range a.Actions {
 		if err := a.doTask(action); err != nil {
 			return err
 		}
+		err := a.saveHis(id, action)
+		if err != nil {
+			return err
+		}
 	}
+
 	return nil
 }
 
@@ -102,3 +110,17 @@ func getAccessRPCHost(deviceid string) (string, error) {
 	}
 	return reply.AccessRPCHost, nil
 }
+
+func (a *TaskExecutor) saveHis(id string, action *Action) error {
+	args := models.SceneHis{
+		RecordId:    guid.S(),
+		SceneID:     id,
+		DeviceId:    action.DeviceID,
+		SubDeviceId: action.SubDeviceId,
+		Cmd:         action.ExecutorProperty.FunctionCode,
+		Params:      gjson.New(action.ExecutorProperty.FunctionValue).MustToJsonString(),
+		Topic:       action.PlcPubMessage.Topic,
+		Payload:     string(action.PlcPubMessage.Payload),
+	}
+	return server.RPCCallByName(nil, rpcs.RegistryServerName, "Registry.CreateEvent", args, &rpcs.ReplyEmptyResult{})
+}

+ 4 - 4
services/scene-service/internal/service/manager/timer.go

@@ -46,7 +46,7 @@ func (t *TimerSceneService) Add(config string) error {
 	//	return errors.New("timer scene-manager config error")
 	//}
 	for _, v := range c.Conditions {
-		err = t.addTask(v, c.Actions)
+		err = t.addTask(c.SceneId, v, c.Actions)
 		if err != nil {
 			server.Log.Errorf("add timerTask error:sceneId:%s, taskId: %s, error: %v", c.SceneId, v.TaskId, err)
 			return err
@@ -57,9 +57,9 @@ func (t *TimerSceneService) Add(config string) error {
 	//server.Log.Debugf("AddTimeScene :%s", c.SceneId)
 	return nil
 }
-func (t *TimerSceneService) addTask(c *TimerTaskCondition, actions []*Action) error {
+func (t *TimerSceneService) addTask(sceneId string, c *TimerTaskCondition, actions []*Action) error {
 	_, err := t.cron.AddTimes(context.Background(), c.Cron, c.Times, func(ctx context.Context) {
-		if err := NewTaskExecutor(actions).Do(); err != nil {
+		if err := NewTaskExecutor(actions).Do(sceneId); err != nil {
 			server.Log.Errorf("do task :%s error:%s", c.TaskId, err.Error())
 		}
 	}, c.TaskId)
@@ -80,7 +80,7 @@ func (t *TimerSceneService) Update(config string) error {
 	}
 
 	for _, v := range c.Conditions {
-		err = t.addTask(v, c.Actions)
+		err = t.addTask(c.SceneId, v, c.Actions)
 		if err != nil {
 			server.Log.Errorf("add timerTask error:sceneId:%s, taskId: %s, error: %v", c.SceneId, v.TaskId, err)
 			return err

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

@@ -70,7 +70,7 @@ func (w *WeatherSceneService) monitorTask(task WeatherSceneConfig) {
 				server.Log.Errorf("compare weather condition error :%s", err.Error())
 			}
 			if result {
-				if err = NewTaskExecutor(task.Actions).Do(); err != nil {
+				if err = NewTaskExecutor(task.Actions).Do(task.SceneId); err != nil {
 					server.Log.Errorf("weather do taskid :%s error:%s", task.SceneId, err.Error())
 				}
 			}

+ 27 - 3
services/scene-service/internal/service/scene.go

@@ -124,19 +124,19 @@ func (m *SceneService) SubmitAction(args rpcs.ArgsSubmitSceneAction, reply *rpcs
 		m.scenes.Set(scene.Id, scene)
 		return m.saveSceneRedis(scene)
 	case "do":
-		err = m.doAction(gjson.New(scene.Action).MustToJsonString())
+		err = m.doAction(scene.Id, gjson.New(scene.Action).MustToJsonString())
 	}
 	return nil
 }
 
-func (m *SceneService) doAction(action string) error {
+func (m *SceneService) doAction(sceneId, 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()
+	return service2.NewTaskExecutor(actions).Do(sceneId)
 }
 
 func (m *SceneService) saveSceneRedis(scene SceneInfo) error {
@@ -169,3 +169,27 @@ func (m *SceneService) delSceneRedis(scene SceneInfo) error {
 	}
 	return err
 }
+
+func (m *SceneService) RestartScenes() {
+	sceneArgs := rpcs.ArgsGetAllScene{}
+	sceneReply := rpcs.ReplyScenes{}
+	err := server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.GetAllScenes", sceneArgs, &sceneReply)
+	if err != nil {
+		server.Log.Errorf("get all scene error: %v", err)
+	}
+	reply := rpcs.ReplySubmitSceneAction{}
+	for _, v := range sceneReply.Result {
+		if v.Status == 1 {
+			err = m.SubmitAction(rpcs.ArgsSubmitSceneAction{
+				Id:            v.SceneId,
+				Name:          v.Name,
+				Status:        v.Status,
+				ConditionDesc: v.ConditionDesc,
+				ActionDesc:    v.ActionDesc,
+				SceneType:     v.SceneType,
+				Config:        v.Config,
+				Action:        "start",
+			}, &reply)
+		}
+	}
+}

+ 1 - 1
services/scene-service/main.go

@@ -14,7 +14,7 @@ func main() {
 		return
 	}
 	s := service.NewSceneService()
-
+	s.RestartScenes()
 	err = server.RegisterRPCHandler(s)
 	if err != nil {
 		server.Log.Errorf("Register RPC manager Error: %s", err)