pulse-monitor-v2/hass.go

76 lines
1.6 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// HASS handles Home Assistant communication
type HASS struct {
url string
token string
}
// NewHASS creates a new Home Assistant client
func NewHASS(url, token string) *HASS {
return &HASS{
url: url,
token: token,
}
}
// PostSpO2 posts SpO2 value to Home Assistant
func (h *HASS) PostSpO2(value int) error {
return h.post("sensor.pulse_spo2", value, "%", "Pulse Oximeter SpO2")
}
// PostHR posts heart rate value to Home Assistant
func (h *HASS) PostHR(value int) error {
return h.post("sensor.pulse_hr", value, "bpm", "Pulse Oximeter Heart Rate")
}
// post sends a value to Home Assistant
func (h *HASS) post(entityID string, value int, unit, friendlyName string) error {
url := fmt.Sprintf("%s/api/states/%s", h.url, entityID)
payload := map[string]interface{}{
"state": fmt.Sprintf("%d", value),
"attributes": map[string]interface{}{
"unit_of_measurement": unit,
"friendly_name": friendlyName,
"device_class": "measurement",
},
}
jsonData, err := json.Marshal(payload)
if err != nil {
return err
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+h.token)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 5 * time.Second}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 && resp.StatusCode != 201 {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
return nil
}