1
0
Fork 0
Home Assistant + NATS = HATS
 
 
Go to file
Jordan Hotmann a9cb361e6b
Recoverable API wrapper
2024-04-24 13:48:46 -06:00
cmd/healthcheck Add healthcheck command 2024-01-08 14:47:35 -07:00
internal Recoverable API wrapper 2024-04-24 13:48:46 -06:00
pkg Nutrislice client 2024-01-09 13:25:06 -07:00
.gitignore Initial commit 2023-10-12 11:23:35 -06:00
Dockerfile Add healthcheck command 2024-01-08 14:47:35 -07:00
LICENSE License, readme update, command/tag changes 2023-11-20 12:24:33 -07:00
README.md Infisical API, config update 2023-12-20 11:29:23 -07:00
go.mod Fix amcrest setConfig 2023-12-14 14:25:16 -07:00
go.sum Fix amcrest setConfig 2023-12-14 14:25:16 -07:00
main.go Recoverable API wrapper 2024-04-24 13:48:46 -06:00

README.md

HATS

Home Assistant + NATS = HATS

Features

NATS Topics

  • homeassistant.states.{domain}.{entity}.{state} - Home Assistant device state changes: payload
  • homeassistant.attributes.{domain}.{entity}.{state} - When a device's attributes change but the state hasn't changed: payload
  • homeassistant.zha.{device IEEE} - ZHA events: payload
  • homeassistant.zwave-scene.{device ID} - ZwaveJS scene events: payload
  • homeassistant.nfc.{tag ID} - Home Assistant NFC tag scanned: payload
  • homeassistant.timer.{timer name}.finished - Home Assistant timer finished: payload is simply "finished"
  • schedules.{schedule name} - HATS schedule finished: payload is simply "finished"
  • command.{command name} - Command called via HATS API: payload is a byte array of the HTTP Post body

Example Client

package main

import (
	"log/slog"
	"os"
	"os/signal"
	"syscall"

	"code.jhot.me/jhot/hats/pkg/client"
	"code.jhot.me/jhot/hats/pkg/config"
	ha "code.jhot.me/jhot/hats/pkg/homeassistant"
	"code.jhot.me/jhot/hats/pkg/nats"
	n "github.com/nats-io/nats.go"
)

var (
	logger     *slog.Logger
	hatsClient *client.HatsClient
	natsClient *nats.NatsConnection
)

func main() {
	cfg := config.FromEnvironment()
	logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
		Level: cfg.GetLogLevel(),
	}))

	hatsClient = client.NewHatsClient(cfg.GetHatsBaseUrl(), cfg.HatsToken)
	natsClient = nats.DefaultNatsConnection().WithJetstream(false).WithHostName(cfg.NatsHost).
		WithPort(cfg.NatsPort).WithConnectionOption(n.Name(cfg.NatsClientName))
	err := natsClient.Connect()
	if err != nil {
		panic(err)
	}
	defer natsClient.Close()

	go natsClient.GenericStateSubscriber(logger, "sun.sun", SunHandler)

	sigch := make(chan os.Signal, 1)
	signal.Notify(sigch, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
	<-sigch
	logger.Info("SIGTERM received")
}

func SunHandler(state ha.StateData) error {
	var service string
	if up := ha.StateToBool(state.State); up {
		service = ha.Services.TurnOff
	} else {
		service = ha.Services.TurnOn
	}
	return hatsClient.CallService("light.some_light", service)
}