diff --git a/README.md b/README.md index 29414ce..b013385 100644 --- a/README.md +++ b/README.md @@ -223,5 +223,26 @@ alert: 2023/03/29 08:00:15 Switch On: 'uvb' (Setting Day Time configuration) ``` +## Switch Metrics +Switch metrics can be accessed via the following endpoints:- +- `/switch` +- `/switch/` + +Example response:- +```json +{ + "Id": "big_led", + "On": "http://meross-lan-api:8080/turnOn/big-led", + "Off": "http://meross-lan-api:8080/turnOff/big-led", + "StatusUrl": "http://meross-lan-api:8080/status/big-led", + "JsonPath": "Status", + "Insecure": false, + "State": "on", + "Disabled": 0, + "DisabledAt": "0001-01-01T00:00:00Z", + "LastAction": "2023-04-01T09:10:26.746657+01:00" +} +``` + ## The End Hopefully the configuration should be pretty self explanitory, if you get stuck or there are any features you think might be missing then feel free to create an issue :slightly_smiling_face:. diff --git a/cmd/terrarium-bot/action.go b/cmd/terrarium-bot/action.go index e1b7862..36d95ff 100644 --- a/cmd/terrarium-bot/action.go +++ b/cmd/terrarium-bot/action.go @@ -90,7 +90,7 @@ func runTriggerAction(args []string, reason string) bool { } func runSwitchAction(args []string, reason string) bool { - s := GetSwitch(args[1]) + s := GetSwitch(args[1], true) switch strings.ToLower(args[2]) { case "on": if len(args) == 4 { diff --git a/cmd/terrarium-bot/apiserver.go b/cmd/terrarium-bot/apiserver.go index 2ec5761..253c401 100644 --- a/cmd/terrarium-bot/apiserver.go +++ b/cmd/terrarium-bot/apiserver.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net/http" + "strings" "time" ) @@ -21,6 +22,10 @@ func (apiServer APIServer) Endpoint(w http.ResponseWriter, r *http.Request) { switch path := r.URL.Path[1:]; { case path == "health/live" || path == "health/ready": fmt.Fprintf(w, "ok") + case path == "switch": + writeResponse(w, config.Switch, false) + case strings.HasPrefix(path, "switch/"): + GetSwitch(strings.Split(path, "/")[1], false).WriteStatus(w) default: if path == "favicon.ico" { // ignore diff --git a/cmd/terrarium-bot/functions.go b/cmd/terrarium-bot/functions.go index 4ab258c..1494955 100644 --- a/cmd/terrarium-bot/functions.go +++ b/cmd/terrarium-bot/functions.go @@ -1,7 +1,9 @@ package main import ( + "encoding/json" "log" + "net/http" "github.com/thedevsaddam/gojsonq" ) @@ -10,6 +12,13 @@ func getJsonValue(json string, path string) interface{} { return gojsonq.New().FromString(json).Find(path) } +func writeResponse(w http.ResponseWriter, response any, Error bool) { + if Error { + w.WriteHeader(http.StatusBadRequest) + } + json.NewEncoder(w).Encode(response) +} + func Debug(s string, v ...any) { if config.Debug { log.Printf(s, v...) diff --git a/cmd/terrarium-bot/switch.go b/cmd/terrarium-bot/switch.go index b616034..24c00d3 100644 --- a/cmd/terrarium-bot/switch.go +++ b/cmd/terrarium-bot/switch.go @@ -4,18 +4,23 @@ import ( "encoding/json" "fmt" "log" + "net/http" "os" "strings" "time" ) -func GetSwitch(id string) *Switch { +func GetSwitch(id string, exitOnError bool) *Switch { for _, s := range config.Switch { if s.Id == id { return s } } - log.Fatalf("Switch '%s' not found in configuration.yaml", id) + if exitOnError { + log.Fatalf("Switch '%s' not found in configuration.yaml", id) + } else { + log.Printf("Switch '%s' not found in configuration.yaml", id) + } return nil } @@ -23,6 +28,8 @@ func InitSwitches() { for _, s := range config.Switch { // some urls include env vars s.fixURLs() + // update status if possible on startup + s.getStatus() } } @@ -157,3 +164,7 @@ func (s *Switch) TurnOff(reason string) { s.setStatus("off") log.Printf("Switch Off: '%s' (%s)", s.Id, reason) } + +func (s *Switch) WriteStatus(w http.ResponseWriter) { + writeResponse(w, s, false) +} diff --git a/cmd/terrarium-bot/switch_test.go b/cmd/terrarium-bot/switch_test.go index 6b51398..144a99c 100644 --- a/cmd/terrarium-bot/switch_test.go +++ b/cmd/terrarium-bot/switch_test.go @@ -18,7 +18,7 @@ func TestGetSwitch(t *testing.T) { {Id: "fan"}, } expected := config.Switch[0] - result := GetSwitch("heating") + result := GetSwitch("heating", true) if result != expected { t.Errorf("Expected '%+v' but got '%+v'", expected, result)