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