场景是指通过SA实现设施联动。例如,自动检测明天的天气情况,明天无雨,定时智能音箱播放浇花揭示,并且播报明天的天气情况。 依据本身需要,把多种管制并发的事件编辑成一个场景,并命名,能够通过场景管制很多设施,实现一键操作的性能。

场景的相干操作

1.1创立场景

创立智能场景前请确保您的家庭已增加设施,且用户是否领有创立智能场景的权限。

·场景名称

场景名称在该家庭下须要确保唯一性。

·触发条件

通过配置触发条件,达到条件后能执行对应的工作,并且能够设置触发条件的失效时段。触发条件分为三种

·手动执行,点击即可执行

·定时执行,如每天8点

·设施状态变动时,如开灯时,感应到人时

当触发条件为手动触发时只能增加一种触发条件。而抉择其余两种能够增加多种,同时须要确定条件关系。条件关系能够抉择

·满足所有条件

·满足任一条件

·技术实现

零碎中启动一个服务,作为音讯队列(以下简称smq)的消费者,消费者一直去轮训音讯队列,看看有没有新的数据,如果有就生产。 查看上面为伪代码:

for {    select {    case ct := <-ticker.C:        fmt.Printf("current ticket at: %d:%d \n", ct.Minute(), ct.Second())        if pq.Len() == 0 {            ticker.Reset(sleepTickTime)            continue        }        task := heap.Pop(pq).(*Task)        now := time.Now()        timeAt := now.Unix()        if task.Priority > timeAt {            nextTick := time.Unix(task.Priority, 0).Sub(now)            ticker.Reset(nextTick)            qs.push(task)        } else {            ticker.Reset(defaultTickTime)            go task.Run()        }    }}

当设置为手动执行的场景时,会增加一条工作数据,执行工夫为以后工夫,加进smq,期待消费者生产。

t = NewTask(WrapSceneFunc(scene, false), 0)PushTask(t, scene)

而设置为主动执行的场景时,会计算工作明天的下次执行工夫,并增加工作数据,加进smq,期待消费者生产。

// 获取工作明天的下次执行工夫days := time.Now().Sub(c.TimingAt).Hours() / 24nextTime := c.TimingAt.AddDate(0, 0, int(days))t = NewTaskAt(WrapSceneFunc(scene, true), nextTime)PushTask(t, scene)

如果主动执行场景的失效时段为重复性,那么会在每天 23: 55:00 进行第二天工作编排

// AddArrangeSceneTask 每天定时编排场景工作func AddArrangeSceneTask(executeTime time.Time) {    var f TaskFunc    f = func(task *Task) error {        addSceneTaskByTime(executeTime.AddDate(0, 0, 1))            // 将下一个定时编排工作排进队列        AddArrangeSceneTask(executeTime.AddDate(0, 0, 1))        return nil    }        task := NewTaskAt(f, executeTime)    MinHeapQueue.Push(task)}// 每天 23:55:00 进行第二天工作编排AddArrangeSceneTask(now.EndOfDay().Add(-5 * time.Minute))

1.2执行工作

当满足触发条件后,能够主动执行配置好的执行工作。执行工作认为两种

·智能设施,如开灯,播放音乐

·管制场景,如开启冬季晚会场景

·技术实现

工作执行,通过消费者生产smq中的工作,去执行run办法去执行对应的工作。

func (item *Task) Run() {    fmt.Println("Run ", item.ToString())    if item.f != nil {        f := item.f        for _, wrapper := range item.wrappers {            f = wrapper(f)        }        if err := f(item); err != nil {            log.Println("task run err:", err)        }    }}

1.3查看场景

场景分成 “手动” 和 “主动” 两个执行类型,页面加载时判断用户是否领有管制场景的权限,在页面展现中 “手动”场景排在“主动”场景的上方;

·手动类场景为“执行”按键,可间接点击触发执行工作

·主动类场景为“开关”按键,设置关上或者敞开状态

  1. 注意事项

· 场景的批改和管制不仅仅取决于用户是否领有批改和管制场景的权限,还包含该用户是否有对场景中的设施操作项的管制权限。

eg:如果您领有管制场景A的权限,然而您没有场景A外面设施B的开关管制权限,则您同样没有管制该场景A的权限。批改的场景也是如此。