github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/mappers/bluetooth_mapper/scheduler/scheduler.go (about) 1 /* 2 Copyright 2019 The KubeEdge Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package scheduler 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "strings" 23 "time" 24 25 "k8s.io/klog" 26 27 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/action_manager" 28 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/data_converter" 29 "github.com/kubeedge/kubeedge/mappers/bluetooth_mapper/helper" 30 ) 31 32 const ( 33 MapperTopicPrefix = "$ke/device/bluetooth-mapper/" 34 SchedulerResultSuffix = "/scheduler/result" 35 defaultEventFrequency = 5000 36 ) 37 38 // Schedule is structure to define a schedule 39 type Schedule struct { 40 // Name is name of the schedule. It should be unique so that a stop-chan 41 // can be made corresponding to name to stop the schedule. 42 Name string `yaml:"name" json:"name"` 43 // Interval is the time in milliseconds after which this action are to be performed 44 Interval int `yaml:"interval" json:"interval"` 45 //OccurrenceLimit refers to the number of time the action can occur, if it is 0, then the event will execute infinitely 46 OccurrenceLimit int `yaml:"occurrence-limit" json:"occurrence-limit"` 47 // Actions is list of Actions to be performed in this schedule 48 Actions []string `yaml:"actions"` 49 } 50 51 //Scheduler structure contains the list of schedules to be scheduled 52 type Scheduler struct { 53 Schedules []Schedule `yaml:"schedules" json:"schedules"` 54 } 55 56 //ScheduleResult structure contains the format in which telemetry data will be published on the MQTT topic 57 type ScheduleResult struct { 58 EventName string 59 TimeStamp int64 60 EventResult string 61 } 62 63 // ExecuteSchedule is responsible for scheduling the operations 64 func (schedule *Schedule) ExecuteSchedule(actionManager []actionmanager.Action, dataConverter dataconverter.DataRead, deviceID string) { 65 klog.Infof("Executing schedule: %s", schedule.Name) 66 if schedule.OccurrenceLimit != 0 { 67 for iteration := 0; iteration < schedule.OccurrenceLimit; iteration++ { 68 schedule.performScheduleOperation(actionManager, dataConverter, deviceID) 69 } 70 } else { 71 for { 72 schedule.performScheduleOperation(actionManager, dataConverter, deviceID) 73 } 74 } 75 helper.ControllerWg.Done() 76 } 77 78 // performScheduleOperation is responsible for performing the operations associated with the schedule 79 func (schedule *Schedule) performScheduleOperation(actionManager []actionmanager.Action, dataConverter dataconverter.DataRead, deviceID string) { 80 var scheduleResult ScheduleResult 81 actionExists := false 82 for _, actionName := range schedule.Actions { 83 for _, action := range actionManager { 84 if strings.EqualFold(action.Name, actionName) { 85 actionExists = true 86 klog.Infof("Performing scheduled operation: %s", action.Name) 87 action.PerformOperation(dataConverter) 88 scheduleResult.EventName = actionName 89 scheduleResult.TimeStamp = time.Now().UnixNano() / 1e6 90 scheduleResult.EventResult = fmt.Sprintf("%s", action.Operation.Value) 91 publishScheduleResult(scheduleResult, deviceID) 92 } 93 } 94 if schedule.Interval == 0 { 95 schedule.Interval = defaultEventFrequency 96 } 97 if !actionExists { 98 klog.Errorf("Action %s does not exist. Exiting from schedule !!!", actionName) 99 break 100 } 101 time.Sleep(time.Duration(time.Duration(schedule.Interval) * time.Millisecond)) 102 } 103 } 104 105 //publishScheduleResult publishes the telemetry data on the given MQTT topic 106 func publishScheduleResult(scheduleResult ScheduleResult, deviceID string) { 107 scheduleResultTopic := MapperTopicPrefix + deviceID + SchedulerResultSuffix 108 klog.Infof("Publishing schedule: %s result on topic: %s", scheduleResult.EventName, scheduleResultTopic) 109 scheduleResultBody, err := json.Marshal(scheduleResult) 110 if err != nil { 111 klog.Errorf("Error: %s", err) 112 } 113 helper.TokenClient = helper.Client.Publish(scheduleResultTopic, 0, false, scheduleResultBody) 114 if helper.TokenClient.Wait() && helper.TokenClient.Error() != nil { 115 klog.Errorf("client.publish() Error in device twin get is %s", helper.TokenClient.Error()) 116 } 117 }