Gisle Aune
1 year ago
16 changed files with 434 additions and 27 deletions
-
1cmd/lucifer4-server/main.go
-
2events/log.go
-
16events/time.go
-
27services/httpapiv1/service.go
-
18services/mysqldb/migrations/20230829192814_script_trigger.sql
-
30services/mysqldb/mysqlgen/db.go
-
11services/mysqldb/mysqlgen/models.go
-
77services/mysqldb/mysqlgen/script.sql.go
-
12services/mysqldb/queries/script.sql
-
72services/mysqldb/service.go
-
4services/resolver.go
-
35services/script/commands.go
-
40services/script/service.go
-
70services/script/trigger.go
-
44services/ticker.go
-
2services/uistate/service.go
@ -0,0 +1,16 @@ |
|||||
|
package events |
||||
|
|
||||
|
import "fmt" |
||||
|
|
||||
|
type Time struct { |
||||
|
Hour int |
||||
|
Minute int |
||||
|
} |
||||
|
|
||||
|
func (t Time) EventDescription() string { |
||||
|
return fmt.Sprintf("Time(%02d:%02d)", t.Hour, t.Minute) |
||||
|
} |
||||
|
|
||||
|
func (t Time) VerboseKey() string { |
||||
|
return "time" |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
-- +goose Up |
||||
|
-- +goose StatementBegin |
||||
|
CREATE TABLE script_trigger ( |
||||
|
id CHAR(36) NOT NULL PRIMARY KEY, |
||||
|
event VARCHAR(255) NOT NULL, |
||||
|
device_match TEXT NOT NULL, |
||||
|
parameter TEXT NOT NULL, |
||||
|
script_target TEXT NOT NULL, |
||||
|
script_name VARCHAR(255) NOT NULL, |
||||
|
script_pre JSON NOT NULL, |
||||
|
script_post JSON NOT NULL |
||||
|
) |
||||
|
-- +goose StatementEnd |
||||
|
|
||||
|
-- +goose Down |
||||
|
-- +goose StatementBegin |
||||
|
DROP TABLE IF EXISTS script_trigger; |
||||
|
-- +goose StatementEnd |
@ -0,0 +1,70 @@ |
|||||
|
package script |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
lucifer3 "git.aiterp.net/lucifer3/server" |
||||
|
"git.aiterp.net/lucifer3/server/device" |
||||
|
"git.aiterp.net/lucifer3/server/events" |
||||
|
"github.com/google/uuid" |
||||
|
"strconv" |
||||
|
) |
||||
|
|
||||
|
type TriggerEvent string |
||||
|
|
||||
|
const ( |
||||
|
TEButton TriggerEvent = "Button" |
||||
|
TETime TriggerEvent = "Time" |
||||
|
TETemperatureAbove TriggerEvent = "TemperatureAbove" |
||||
|
TETemperatureBelow TriggerEvent = "TemperatureBelow" |
||||
|
) |
||||
|
|
||||
|
type Trigger struct { |
||||
|
ID uuid.UUID `json:"id"` |
||||
|
Event TriggerEvent `json:"event"` |
||||
|
DeviceMatch string `json:"deviceMatch"` |
||||
|
Parameter string `json:"parameter"` |
||||
|
ScriptTarget string `json:"scriptTarget"` |
||||
|
ScriptName string `json:"scriptName"` |
||||
|
ScriptPre []Line `json:"scriptPre"` |
||||
|
ScriptPost []Line `json:"scriptPost"` |
||||
|
} |
||||
|
|
||||
|
func (t *Trigger) Check(event lucifer3.Event, res device.Resolver) bool { |
||||
|
devices := res.Resolve(t.DeviceMatch) |
||||
|
|
||||
|
switch event := event.(type) { |
||||
|
case events.ButtonPressed: |
||||
|
if t.Event != TEButton { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
for _, dev := range devices { |
||||
|
if dev.ID == event.ID { |
||||
|
return t.Parameter == event.Name |
||||
|
} |
||||
|
} |
||||
|
case events.Time: |
||||
|
if t.Event != TETime { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
return fmt.Sprintf("%02d:%02d", event.Hour, event.Minute) == t.Parameter |
||||
|
case events.TemperatureChanged: |
||||
|
if t.Event != TETemperatureAbove && t.Event != TETemperatureBelow { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
num, err := strconv.ParseFloat(t.Parameter, 64) |
||||
|
if err != nil { |
||||
|
return false |
||||
|
} |
||||
|
|
||||
|
for _, dev := range devices { |
||||
|
if dev.ID == event.ID { |
||||
|
return (event.Temperature >= num) == (t.Event == TETemperatureAbove) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
package services |
||||
|
|
||||
|
import ( |
||||
|
lucifer3 "git.aiterp.net/lucifer3/server" |
||||
|
"git.aiterp.net/lucifer3/server/events" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
func NewTicker() lucifer3.Service { |
||||
|
return &tickerService{} |
||||
|
} |
||||
|
|
||||
|
type tickerService struct{} |
||||
|
|
||||
|
func (s *tickerService) Active() bool { |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
func (s *tickerService) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) { |
||||
|
if _, ok := event.(events.Started); ok { |
||||
|
go func() { |
||||
|
now := time.Now() |
||||
|
bus.RunEvent(events.Time{ |
||||
|
Hour: now.Hour(), |
||||
|
Minute: now.Minute(), |
||||
|
}) |
||||
|
|
||||
|
time.Sleep(time.Now().Truncate(time.Minute).Add(time.Minute).Sub(time.Now())) |
||||
|
|
||||
|
now = time.Now() |
||||
|
bus.RunEvent(events.Time{ |
||||
|
Hour: now.Hour(), |
||||
|
Minute: now.Minute(), |
||||
|
}) |
||||
|
|
||||
|
for t := range time.NewTicker(time.Minute).C { |
||||
|
bus.RunEvent(events.Time{ |
||||
|
Hour: t.Hour(), |
||||
|
Minute: t.Minute(), |
||||
|
}) |
||||
|
} |
||||
|
}() |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue