Poo recorder almost ported to go, needs to have perodically backup

This commit is contained in:
2024-09-17 16:28:12 +02:00
parent c357c533e3
commit bcba9f8a11
8 changed files with 469 additions and 167 deletions

View File

@@ -13,14 +13,17 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/go-co-op/gocron/v2"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
pooRecorder "github.com/t-liu93/home-automation-backend/components" "github.com/t-liu93/home-automation-backend/components/homeassistant"
"github.com/t-liu93/home-automation-backend/components/pooRecorder"
"github.com/t-liu93/home-automation-backend/util/notion" "github.com/t-liu93/home-automation-backend/util/notion"
) )
var port string var port string
var scheduler gocron.Scheduler
// serveCmd represents the serve command // serveCmd represents the serve command
var serveCmd = &cobra.Command{ var serveCmd = &cobra.Command{
@@ -41,11 +44,12 @@ func initUtil() {
func initComponent() { func initComponent() {
// init pooRecorder // init pooRecorder
pooRecorder.Init() pooRecorder.Init(&scheduler)
} }
func serve(cmd *cobra.Command, args []string) { func serve(cmd *cobra.Command, args []string) {
slog.Info("Starting server...") slog.Info("Starting server..")
viper.SetConfigName("config") // name of config file (without extension) viper.SetConfigName("config") // name of config file (without extension)
viper.SetConfigType("yaml") viper.SetConfigType("yaml")
viper.AddConfigPath("$HOME/.config/home-automation") viper.AddConfigPath("$HOME/.config/home-automation")
@@ -56,23 +60,46 @@ func serve(cmd *cobra.Command, args []string) {
os.Exit(1) os.Exit(1)
} }
viper.WatchConfig() viper.WatchConfig()
viper.SetDefault("logLevel", "info")
logLevelCfg := viper.GetString("logLevel")
switch logLevelCfg {
case "debug":
slog.SetLogLoggerLevel(slog.LevelDebug)
case "info":
slog.SetLogLoggerLevel(slog.LevelInfo)
case "warn":
slog.SetLogLoggerLevel(slog.LevelWarn)
case "error":
slog.SetLogLoggerLevel(slog.LevelError)
}
if viper.InConfig("port") { if viper.InConfig("port") {
port = viper.GetString("port") port = viper.GetString("port")
} else { } else {
slog.Error("Port not found in config file, exiting..") slog.Error("Port not found in config file, exiting..")
os.Exit(1) os.Exit(1)
} }
scheduler, err = gocron.NewScheduler()
defer scheduler.Shutdown()
if err != nil {
slog.Error(fmt.Sprintf("Cannot create scheduler, %s, exiting..", err))
os.Exit(1)
}
initUtil() initUtil()
initComponent() initComponent()
scheduler.Start()
// routing // routing
router := mux.NewRouter() router := mux.NewRouter()
router.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { router.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK")) w.Write([]byte("OK"))
}).Methods("GET") }).Methods("GET")
router.HandleFunc("/poo/latest", pooRecorder.HandleNotifyLatestPoo).Methods("GET")
router.HandleFunc("/poo/record", pooRecorder.HandleRecordPoo).Methods("POST") router.HandleFunc("/poo/record", pooRecorder.HandleRecordPoo).Methods("POST")
router.HandleFunc("/homeassistant/publish", homeassistant.HandleHaMessage).Methods("POST")
srv := &http.Server{ srv := &http.Server{
Addr: ":" + port, Addr: ":" + port,
Handler: router, Handler: router,

View File

@@ -0,0 +1,54 @@
package homeassistant
import (
"encoding/json"
"fmt"
"log/slog"
"net/http"
"time"
"github.com/spf13/viper"
)
type haMessage struct {
Target string `json:"target"`
Action string `json:"action"`
Content string `json:"content"`
}
func HandleHaMessage(w http.ResponseWriter, r *http.Request) {
var message haMessage
decoder := json.NewDecoder(r.Body)
decoder.DisallowUnknownFields()
err := decoder.Decode(&message)
if err != nil {
slog.Warn(fmt.Sprintln("HandleHaMessage Error decoding request body", err))
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
switch message.Target {
case "poo_recorder":
handlePooRecorderMsg(message)
}
}
func handlePooRecorderMsg(message haMessage) {
switch message.Action {
case "get_latest":
handleGetLatestPoo()
}
}
func handleGetLatestPoo() {
client := &http.Client{
Timeout: time.Second * 1,
}
port := viper.GetString("port")
_, err := client.Get("http://localhost:" + port + "/poo/latest")
if err != nil {
slog.Warn(fmt.Sprintln("handleGetLatestPoo Error sending request to poo recorder", err))
}
}

View File

@@ -1,156 +0,0 @@
package pooRecorder
import (
"bytes"
"database/sql"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
"github.com/spf13/viper"
"github.com/t-liu93/home-automation-backend/util/notion"
"golang.org/x/exp/slog"
)
type recordDetail struct {
Status string `json:"status"`
Latitude string `json:"latitude"`
Longitude string `json:"longitude"`
}
type pooStatusHttpSensorAttributes struct {
LastPoo string `json:"last_poo"`
}
type pooStatusHttpSensor struct {
EntityId string `json:"entity_id"`
State string `json:"state"`
Attributes pooStatusHttpSensorAttributes `json:"attributes"`
}
var (
db *sql.DB
)
func publishPooStatus(pooStatus pooStatusHttpSensor) {
if viper.InConfig("pooRecorder.homeassistantIp") &&
viper.InConfig("pooRecorder.homeassistantPort") &&
viper.InConfig("pooRecorder.homeassistantToken") {
homeAssistantIp := viper.GetString("pooRecorder.homeassistantIp")
homeAssistantPort := viper.GetString("pooRecorder.homeassistantPort")
url := fmt.Sprintf("http://%s:%s/api/states/%s", homeAssistantIp, homeAssistantPort, pooStatus.EntityId)
payload, err := json.Marshal(pooStatus)
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error marshalling poo status", err))
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error creating request", err))
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+viper.GetString("pooRecorder.homeassistantToken"))
client := &http.Client{
Timeout: time.Second * 1,
}
resp, err := client.Do(req)
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error sending request", err))
}
if resp.StatusCode != http.StatusOK {
slog.Warn(fmt.Sprintln("HandleRecordPoo Unexpected response status", resp.StatusCode))
}
defer resp.Body.Close()
} else {
slog.Warn("HandleRecordPoo Home Assistant IP, port, or token not found in config file")
}
}
func storeStatus(record recordDetail, timestamp time.Time) {
tableId := viper.GetString("pooRecorder.tableId")
recordDate := timestamp.Format("2006-01-02")
recordTime := timestamp.Format("15:04")
slog.Info(fmt.Sprintln("Recording poo", record.Status, "at", record.Latitude, record.Longitude))
go func() {
header, err := notion.GetTableRows(tableId, 1, "")
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Failed to get table header", err))
return
}
if len(header) == 0 {
slog.Warn("HandleRecordPoo Table header not found")
return
}
headerId := header[0].GetID()
err = notion.WriteTableRow([]string{recordDate, recordTime, record.Status, record.Latitude + "," + record.Longitude}, tableId, headerId.String())
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Failed to write table row", err))
}
}()
}
func migrateDb() {
}
func initDb() {
if !viper.InConfig("pooRecorder.dbPath") {
slog.Info("HandleRecordPoo dbPath not found in config file, using default: pooRecorder.db")
viper.SetDefault("pooRecorder.dbPath", "pooRecorder.db")
}
dbPath := viper.GetString("pooRecorder.dbPath")
err := error(nil)
db, err = sql.Open("sqlite3", dbPath)
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error opening database", err))
os.Exit(1)
}
err = db.Ping()
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error pinging database", err))
os.Exit(1)
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS poo_records (
timestamp TEXT PRIMARY KEY,
status TEXT,
latitude TEXT,
longitude TEXT)`)
}
func Init() {
initDb()
}
func HandleRecordPoo(w http.ResponseWriter, r *http.Request) {
var record recordDetail
if !viper.InConfig("pooRecorder.tableId") {
slog.Warn("HandleRecordPoo Table ID not found in config file")
http.Error(w, "Table ID not found in config file", http.StatusInternalServerError)
return
}
decorder := json.NewDecoder(r.Body)
decorder.DisallowUnknownFields()
err := decorder.Decode(&record)
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error decoding request body", err))
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
now := time.Now()
storeStatus(record, now)
timeAttribute := now.Format("Mon | 2006-01-02 | 15:04")
pooStatus := pooStatusHttpSensor{
EntityId: "sensor.test_poo_sensor",
State: record.Status,
Attributes: pooStatusHttpSensorAttributes{
LastPoo: timeAttribute,
},
}
publishPooStatus(pooStatus)
}

View File

@@ -0,0 +1,210 @@
package pooRecorder
import (
"database/sql"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
"log/slog"
"github.com/go-co-op/gocron/v2"
"github.com/spf13/viper"
"github.com/t-liu93/home-automation-backend/util/homeassistantutil"
"github.com/t-liu93/home-automation-backend/util/notion"
_ "modernc.org/sqlite"
)
var (
db *sql.DB
scheduler *gocron.Scheduler
)
type recordDetail struct {
Status string `json:"status"`
Latitude string `json:"latitude"`
Longitude string `json:"longitude"`
}
type pooStatusSensorAttributes struct {
LastPoo string `json:"last_poo"`
}
type pooStatusWebhookBody struct {
Status string `json:"status"`
}
type pooStatusDbEntry struct {
Timestamp string
Status string
Latitude float64
Longitude float64
}
func Init(mainScheduler *gocron.Scheduler) {
initDb()
initScheduler(mainScheduler)
}
func HandleRecordPoo(w http.ResponseWriter, r *http.Request) {
var record recordDetail
if !viper.InConfig("pooRecorder.tableId") {
slog.Warn("HandleRecordPoo Table ID not found in config file")
http.Error(w, "Table ID not found in config file", http.StatusInternalServerError)
return
}
decoder := json.NewDecoder(r.Body)
decoder.DisallowUnknownFields()
err := decoder.Decode(&record)
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error decoding request body", err))
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
now := time.Now()
err = storeStatus(record, now)
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Error storing status", err))
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
pooStatus := homeassistantutil.HttpSensor{
EntityId: "sensor.test_poo_sensor",
State: record.Status,
Attributes: pooStatusSensorAttributes{
LastPoo: now.Format("Mon | 2006-01-02 | 15:04"),
},
}
homeassistantutil.PublishSensor(pooStatus)
if viper.InConfig("pooRecorder.webhookId") {
homeassistantutil.TriggerWebhook(viper.GetString("pooRecorder.webhookId"), pooStatusWebhookBody{Status: record.Status})
} else {
slog.Warn("HandleRecordPoo Webhook ID not found in config file")
}
}
func HandleNotifyLatestPoo(w http.ResponseWriter, r *http.Request) {
var latest pooStatusDbEntry
err := db.QueryRow(`SELECT timestamp, status, latitude, longitude FROM poo_records ORDER BY timestamp DESC LIMIT 1`).Scan(&latest.Timestamp, &latest.Status, &latest.Latitude, &latest.Longitude)
if err != nil {
slog.Warn(fmt.Sprintln("HandleGetLatestPoo Error getting latest poo", err))
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
recordTime, err := time.Parse("2006-01-02T15:04Z07:00", latest.Timestamp)
if err != nil {
slog.Warn(fmt.Sprintln("HandleGetLatestPoo Error parsing timestamp", err))
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
recordTime = recordTime.Local()
pooStatus := homeassistantutil.HttpSensor{
EntityId: "sensor.test_poo_sensor",
State: latest.Status,
Attributes: pooStatusSensorAttributes{
LastPoo: recordTime.Format("Mon | 2006-01-02 | 15:04"),
},
}
homeassistantutil.PublishSensor(pooStatus)
slog.Debug(fmt.Sprintln("HandleGetLatestPoo Latest poo", pooStatus.State, "at", pooStatus.Attributes.(pooStatusSensorAttributes).LastPoo))
}
func initDb() {
if !viper.InConfig("pooRecorder.dbPath") {
slog.Info("HandleRecordPoo dbPath not found in config file, using default: pooRecorder.db")
viper.SetDefault("pooRecorder.dbPath", "pooRecorder.db")
}
dbPath := viper.GetString("pooRecorder.dbPath")
err := error(nil)
db, err = sql.Open("sqlite", dbPath)
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error opening database", err))
os.Exit(1)
}
err = db.Ping()
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error pinging database", err))
os.Exit(1)
}
migrateDb()
}
func migrateDb() {
var userVersion int
err := db.QueryRow("PRAGMA user_version").Scan(&userVersion)
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error getting db user version", err))
os.Exit(1)
}
if userVersion == 0 {
migrateDb0To1(&userVersion)
}
}
func migrateDb0To1(userVersion *int) {
// this is actually create new db
slog.Info("Creating database version 1..")
_, err := db.Exec(`CREATE TABLE IF NOT EXISTS poo_records (
timestamp TEXT NOT NULL,
status TEXT NOT NULL,
latitude REAL NOT NULL,
longitude REAL NOT NULL,
PRIMARY KEY (timestamp))`)
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error creating table", err))
os.Exit(1)
}
_, err = db.Exec(`PRAGMA user_version = 1`)
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error setting user version to 1", err))
os.Exit(1)
}
*userVersion = 1
}
func initScheduler(mainScheduler *gocron.Scheduler) {
scheduler = mainScheduler
_, err := (*scheduler).NewJob(gocron.CronJob("0 5 * * *", false), gocron.NewTask(
per,
))
if err != nil {
slog.Error(fmt.Sprintln("PooRecorderInit Error creating scheduled task", err))
os.Exit(1)
}
}
func per() {
slog.Info("PooRecorderInit Running scheduled task ")
}
func storeStatus(record recordDetail, timestamp time.Time) error {
tableId := viper.GetString("pooRecorder.tableId")
recordDate := timestamp.Format("2006-01-02")
recordTime := timestamp.Format("15:04")
slog.Debug(fmt.Sprintln("Recording poo", record.Status, "at", record.Latitude, record.Longitude))
_, err := db.Exec(`INSERT OR IGNORE INTO poo_records (timestamp, status, latitude, longitude) VALUES (?, ?, ?, ?)`,
timestamp.UTC().Format("2006-01-02T15:04Z07:00"), record.Status, record.Latitude, record.Longitude)
if err != nil {
return err
}
go func() {
header, err := notion.GetTableRows(tableId, 1, "")
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Failed to get table header", err))
return
}
if len(header) == 0 {
slog.Warn("HandleRecordPoo Table header not found")
return
}
headerId := header[0].GetID()
err = notion.WriteTableRow([]string{recordDate, recordTime, record.Status, record.Latitude + "," + record.Longitude}, tableId, headerId.String())
if err != nil {
slog.Warn(fmt.Sprintln("HandleRecordPoo Failed to write table row", err))
}
}()
return nil
}

View File

@@ -3,20 +3,30 @@ module github.com/t-liu93/home-automation-backend
go 1.23.0 go 1.23.0
require ( require (
github.com/go-co-op/gocron/v2 v2.11.0
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/jomei/notionapi v1.13.2 github.com/jomei/notionapi v1.13.2
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0 github.com/spf13/viper v1.19.0
golang.org/x/term v0.24.0 golang.org/x/term v0.24.0
modernc.org/sqlite v1.33.1
) )
require ( require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect
@@ -26,9 +36,15 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/sys v0.25.0 // indirect golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.55.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
) )

View File

@@ -3,33 +3,53 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/go-co-op/gocron/v2 v2.11.0 h1:IOowNA6SzwdRFnD4/Ol3Kj6G2xKfsoiiGq2Jhhm9bvE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/go-co-op/gocron/v2 v2.11.0/go.mod h1:xY7bJxGazKam1cz04EebrlP4S9q4iWdiAylMGP3jY9w=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jomei/notionapi v1.13.2 h1:YpHKNpkoTMlUfWTlVIodOmQDgRKjfwmtSNVa6/6yC9E= github.com/jomei/notionapi v1.13.2 h1:YpHKNpkoTMlUfWTlVIodOmQDgRKjfwmtSNVa6/6yC9E=
github.com/jomei/notionapi v1.13.2/go.mod h1:BqzP6JBddpBnXvMSIxiR5dCoCjKngmz5QNl1ONDlDoM= github.com/jomei/notionapi v1.13.2/go.mod h1:BqzP6JBddpBnXvMSIxiR5dCoCjKngmz5QNl1ONDlDoM=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -63,21 +83,56 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=

BIN
src/pooRecorder.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,96 @@
package homeassistantutil
import (
"bytes"
"encoding/json"
"fmt"
"log/slog"
"net/http"
"time"
"github.com/spf13/viper"
)
const (
ipField string = "homeassistant.ip"
portField string = "homeassistant.port"
authTokenField string = "homeassistant.authToken"
webhookPath string = "/api/webhook/"
sensorPath string = "/api/states/"
)
type HttpSensor struct {
EntityId string `json:"entity_id"`
State string `json:"state"`
Attributes interface{} `json:"attributes"`
}
type WebhookBody interface{}
func TriggerWebhook(webhookId string, body WebhookBody) {
if viper.InConfig(ipField) &&
viper.InConfig(portField) &&
viper.InConfig(authTokenField) {
url := fmt.Sprintf("http://%s:%s%s%s", viper.GetString(ipField), viper.GetString(portField), webhookPath, webhookId)
payload, err := json.Marshal(body)
if err != nil {
slog.Warn(fmt.Sprintln("TriggerWebhook Error marshalling", err))
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
if err != nil {
slog.Warn(fmt.Sprintln("TriggerWebhook Error creating request", err))
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+viper.GetString(authTokenField))
client := &http.Client{
Timeout: time.Second * 1,
}
go func() {
resp, err := client.Do(req)
if err != nil {
slog.Warn(fmt.Sprintln("TriggerWebhook Error sending request", err))
}
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
slog.Warn(fmt.Sprintln("TriggerWebhook Unexpected response status", resp.StatusCode))
}
defer resp.Body.Close()
}()
} else {
slog.Warn("TriggerWebhook Home Assistant IP, port, or token not found in config file")
}
}
func PublishSensor(sensor HttpSensor) {
if viper.InConfig(ipField) &&
viper.InConfig(portField) &&
viper.InConfig(authTokenField) {
url := fmt.Sprintf("http://%s:%s%s%s", viper.GetString(ipField), viper.GetString(portField), sensorPath, sensor.EntityId)
payload, err := json.Marshal(sensor)
if err != nil {
slog.Warn(fmt.Sprintln("PublishSensor Error marshalling", err))
return
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
if err != nil {
slog.Warn(fmt.Sprintln("PublishSensor Error creating request", err))
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+viper.GetString(authTokenField))
client := &http.Client{
Timeout: time.Second * 1,
}
resp, err := client.Do(req)
if err != nil {
slog.Warn(fmt.Sprintln("PublishSensor Error sending request", err))
}
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
slog.Warn(fmt.Sprintln("PublishSensor Unexpected response status", resp.StatusCode))
}
defer resp.Body.Close()
} else {
slog.Warn("PublishSensor Home Assistant IP, port, or token not found in config file")
}
}