2023-10-12 17:23:35 +00:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2023-10-13 20:31:23 +00:00
|
|
|
"code.jhot.me/jhot/hats/internal/api"
|
2023-10-16 16:54:09 +00:00
|
|
|
ha "code.jhot.me/jhot/hats/pkg/homeassistant"
|
2023-11-08 23:12:04 +00:00
|
|
|
"code.jhot.me/jhot/hats/pkg/ntfy"
|
2023-10-12 17:23:35 +00:00
|
|
|
"github.com/go-resty/resty/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type HatsClient struct {
|
|
|
|
client *resty.Client
|
|
|
|
}
|
|
|
|
|
2023-11-17 18:24:12 +00:00
|
|
|
func NewHatsClient(baseUrl string, token string) *HatsClient {
|
2023-10-12 17:23:35 +00:00
|
|
|
client := resty.New().SetBaseURL(baseUrl)
|
2023-11-17 18:24:12 +00:00
|
|
|
if token != "" {
|
|
|
|
client.SetHeader("Authorization", fmt.Sprintf("Bearer %s", token))
|
|
|
|
}
|
2023-10-12 17:23:35 +00:00
|
|
|
return &HatsClient{
|
|
|
|
client: client,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-16 16:54:09 +00:00
|
|
|
func (c *HatsClient) GetStateFull(entityId string) (ha.StateData, error) {
|
|
|
|
var data ha.StateData
|
|
|
|
resp, err := c.client.R().SetResult(&data).SetQueryParam("full", "true").Get(fmt.Sprintf("api/state/%s", entityId))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return data, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2023-10-12 17:23:35 +00:00
|
|
|
func (c *HatsClient) GetState(entityId string) (string, error) {
|
|
|
|
resp, err := c.client.R().Get(fmt.Sprintf("api/state/%s", entityId))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.String(), nil
|
|
|
|
}
|
|
|
|
|
2023-10-16 21:20:08 +00:00
|
|
|
func (c *HatsClient) GetStateWithDefault(entityId string, defaultValue string) string {
|
|
|
|
state, err := c.GetState(entityId)
|
|
|
|
if err != nil {
|
|
|
|
return defaultValue
|
|
|
|
}
|
|
|
|
return state
|
|
|
|
}
|
|
|
|
|
2023-10-12 17:23:35 +00:00
|
|
|
func (c *HatsClient) GetStateBool(entityId string) (bool, error) {
|
|
|
|
stateString, err := c.GetState(entityId)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2023-10-16 16:54:09 +00:00
|
|
|
return ha.StateToBool(stateString), nil
|
2023-10-12 17:23:35 +00:00
|
|
|
}
|
|
|
|
|
2023-10-17 19:58:34 +00:00
|
|
|
func (c *HatsClient) CallService(entityId string, service string, extras ...map[string]any) error {
|
2023-10-12 17:23:35 +00:00
|
|
|
req := c.client.R()
|
|
|
|
if len(extras) > 0 {
|
|
|
|
data := map[string]interface{}{}
|
|
|
|
for _, extra := range extras {
|
|
|
|
for k, v := range extra {
|
2023-11-07 23:09:10 +00:00
|
|
|
switch k {
|
|
|
|
case "domain":
|
|
|
|
req.SetQueryParam(k, fmt.Sprintf("%v", v))
|
|
|
|
default:
|
|
|
|
data[k] = v
|
|
|
|
}
|
2023-10-12 17:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
req.SetBody(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := req.Post(fmt.Sprintf("api/state/%s/%s", entityId, service))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2023-10-13 20:31:23 +00:00
|
|
|
|
|
|
|
func (c *HatsClient) GetTimer(name string) (string, error) {
|
|
|
|
resp, err := c.client.R().Get(fmt.Sprintf("api/timer/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.String(), nil
|
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
// Start a timer
|
2023-10-17 19:58:34 +00:00
|
|
|
//
|
|
|
|
// name: the name of the timer (should be unique)
|
|
|
|
// duration: time.Duration string for how long the timer should last
|
|
|
|
// force: if true, will start the timer over even if it is already running
|
2023-10-18 18:35:46 +00:00
|
|
|
func (c *HatsClient) StartTimer(name string, duration string, force bool) (string, error) {
|
|
|
|
data := api.StartTimerData{
|
2023-10-13 20:31:23 +00:00
|
|
|
Duration: duration,
|
|
|
|
Force: force,
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := c.client.R().SetBody(data).Post(fmt.Sprintf("api/timer/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.String(), nil
|
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func (c *HatsClient) CancelTimer(name string) error {
|
2023-10-13 20:31:23 +00:00
|
|
|
resp, err := c.client.R().Delete(fmt.Sprintf("api/timer/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *HatsClient) GetSchedule(name string) (string, error) {
|
|
|
|
resp, err := c.client.R().Get(fmt.Sprintf("api/schedule/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.String(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSchedule: set a cron schedule
|
|
|
|
//
|
|
|
|
// name: a unique identifying string
|
|
|
|
// cron: a cron expression with seconds, like "0 */5 * * * *" (every 5 minutes)
|
|
|
|
func (c *HatsClient) SetSchedule(name string, cron string) (string, error) {
|
|
|
|
data := api.CreateScheduleData{
|
|
|
|
Cron: cron,
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := c.client.R().SetBody(data).Post(fmt.Sprintf("api/schedule/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.String(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *HatsClient) DeleteSchedule(name string) error {
|
|
|
|
resp, err := c.client.R().Delete(fmt.Sprintf("api/schedule/%s", name))
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
2023-11-08 23:12:04 +00:00
|
|
|
|
|
|
|
func (c *HatsClient) SendNtfyMessage(data ntfy.Message) error {
|
|
|
|
resp, err := c.client.R().SetBody(data).Post("api/ntfy")
|
|
|
|
if err == nil && !resp.IsSuccess() {
|
|
|
|
err = fmt.Errorf("%d status code received: %s", resp.StatusCode(), resp.String())
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|