From 2bd57e945ec7aaec5e9d760c78e47b7a39537286 Mon Sep 17 00:00:00 2001 From: Michael Wuertinger Date: Tue, 23 Oct 2018 21:52:23 +0200 Subject: [PATCH 1/2] Timer WIP --- main.go | 14 +++++++++ pkg/timer/timer.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 pkg/timer/timer.go diff --git a/main.go b/main.go index 88b1809..b3880f4 100644 --- a/main.go +++ b/main.go @@ -6,12 +6,14 @@ import ( "os" "os/signal" "syscall" + "time" "github.com/mwuertinger/hal/pkg/config" "github.com/mwuertinger/hal/pkg/device" "github.com/mwuertinger/hal/pkg/frontend" "github.com/mwuertinger/hal/pkg/mqtt" "github.com/mwuertinger/hal/pkg/persistence" + "github.com/mwuertinger/hal/pkg/timer" ) func main() { @@ -35,6 +37,11 @@ func main() { log.Fatalf("persistence.Start: %v", err) } + timerSvc := timer.NewService() + if err := timerSvc.Start(); err != nil { + log.Fatalf("timerSvc.Start: %v", err) + } + mqttBroker := mqtt.New() if err := mqttBroker.Connect(c.Mqtt); err != nil { log.Fatalf("mqttBroker.Connect: %v", err) @@ -49,6 +56,13 @@ func main() { log.Fatalf("frontend.Start: %v", err) } + // TODO remove + timerSvc.AddJob(timer.Job{ + Timestamp: time.Now().Add(1 * time.Minute), + Status: false, + Switches: []device.Switch{device.Get("socket01").(device.Switch)}, + }) + log.Println("Server ready") // Wait for receiving a signal. diff --git a/pkg/timer/timer.go b/pkg/timer/timer.go new file mode 100644 index 0000000..f3268e8 --- /dev/null +++ b/pkg/timer/timer.go @@ -0,0 +1,74 @@ +package timer + +import ( + "errors" + "github.com/mwuertinger/hal/pkg/device" + "log" + "math/rand" + "sync" + "time" +) + +type Service interface { + Start() error + AddJob(job Job) (uint64, error) +} + +type Job struct { + ID uint64 + Timestamp time.Time // execution time + Switches []device.Switch // list of switches + Status bool // target status +} + +type service struct { + mu sync.Mutex // protects everything below + initialized bool + jobs map[uint64]Job +} + +func NewService() Service { + return &service{jobs: map[uint64]Job{}} +} + +func (s *service) Start() error { + s.mu.Lock() + defer s.mu.Unlock() + if s.initialized { + return errors.New("already initialized") + } + + go func() { + for now := range time.Tick(time.Minute) { + log.Print("Timer tick: ", now) + s.mu.Lock() + log.Print("Timer.jobs: ", s.jobs) + for id, job := range s.jobs { + if job.Timestamp.Before(now) { + log.Print("Timer: ", job) + for _, sw := range job.Switches { + sw.Switch(job.Status) + } + delete(s.jobs, id) + } + } + s.mu.Unlock() + } + }() + return nil +} + +func (s *service) AddJob(job Job) (uint64, error) { + job.ID = rand.Uint64() + + // defensive copying + switches := make([]device.Switch, len(job.Switches)) + copy(switches, job.Switches) + job.Switches = switches + + s.mu.Lock() + defer s.mu.Unlock() + s.jobs[job.ID] = job + + return job.ID, nil +} From 05d19acf895274cf704bec427a398ebc1de4c4b2 Mon Sep 17 00:00:00 2001 From: Michael Wuertinger Date: Sun, 16 Dec 2018 21:06:00 +0100 Subject: [PATCH 2/2] Timer WIP --- main.go | 10 +++++++--- pkg/timer/timer.go | 1 - 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index b3880f4..d1dcdca 100644 --- a/main.go +++ b/main.go @@ -57,10 +57,14 @@ func main() { } // TODO remove + var switches []device.Switch + for _, dev := range device.List() { + switches = append(switches, dev.(device.Switch)) + } timerSvc.AddJob(timer.Job{ - Timestamp: time.Now().Add(1 * time.Minute), - Status: false, - Switches: []device.Switch{device.Get("socket01").(device.Switch)}, + Timestamp: time.Date(2018, 10, 26, 5, 0, 0, 0, time.UTC), + Status: true, + Switches: switches, }) log.Println("Server ready") diff --git a/pkg/timer/timer.go b/pkg/timer/timer.go index f3268e8..e8b9789 100644 --- a/pkg/timer/timer.go +++ b/pkg/timer/timer.go @@ -40,7 +40,6 @@ func (s *service) Start() error { go func() { for now := range time.Tick(time.Minute) { - log.Print("Timer tick: ", now) s.mu.Lock() log.Print("Timer.jobs: ", s.jobs) for id, job := range s.jobs {