Skip to content

Commit

Permalink
feat: add temperature command targetting climate entities (#63)
Browse files Browse the repository at this point in the history
* feat: add temperature command targetting climate entities

---------

Co-authored-by: Fabian Sylvester <[email protected]>
  • Loading branch information
mrene and xx4h authored Oct 27, 2024
1 parent d4127f8 commit fc9c13f
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ And here we are!
- Set brightness on all capable devices
- Play local and remote music files
- Set volume on media players
- Set temperature on capable devices
- List all Domains & Domain-Services
- Completion for `bash`, `zsh`, `fish` and `powershell`, auto completing all capable devices
- Add shortcuts/mappings for devices and media files
Expand Down
9 changes: 8 additions & 1 deletion cmd/completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func Test_compListStates(t *testing.T) {
[]string{"turn_on"},
nil,
"",
11,
12,
},
"serviceCap turn_on + state off": {
nil,
Expand Down Expand Up @@ -81,6 +81,13 @@ func Test_compListStates(t *testing.T) {
"",
3,
},
"serviceCap climate": {
nil,
[]string{"set_temperature"},
nil,
"",
2,
},
}

for name, tt := range tests {
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func newRootCmd(h *pkg.Hctl, out io.Writer, _ []string) *cobra.Command {
newToggleCmd(h, out),
newVersionCmd(out),
newVolumeCmd(h, out),
newTemperatureCmd(h, out),
)

cmd.PersistentFlags().StringVarP(&logLevel, "log-level", "l", "", "Set the log level")
Expand Down
48 changes: 48 additions & 0 deletions cmd/temperature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2024 Fabian `xx4h` Sylvester
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"io"

"github.com/spf13/cobra"

"github.com/xx4h/hctl/pkg"
o "github.com/xx4h/hctl/pkg/output"
)

func newTemperatureCmd(h *pkg.Hctl, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "temperature",
Short: "Set the temperature of a climate entity",
Aliases: []string{"te", "temp"},
Args: cobra.MatchAll(cobra.ExactArgs(2)),
ValidArgsFunction: func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return compListStates(toComplete, args, []string{"set_temperature"}, nil, "", h)
}
return nil, cobra.ShellCompDirectiveDefault
},
Run: func(_ *cobra.Command, args []string) {
obj, state, err := h.TemperatureSet(args[0], args[1])
if err != nil {
o.FprintError(out, err)
}
o.FprintSuccessAction(out, obj, state)
},
}

return cmd
}
39 changes: 39 additions & 0 deletions cmd/temperature_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2024 Fabian `xx4h` Sylvester
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"testing"

"github.com/xx4h/hctl/pkg/hctltest"
)

func Test_newCmdTemperature(t *testing.T) {
ms := hctltest.MockServer(t)
h := newTestingHctl(t)
if err := h.SetConfigValue("hub.url", ms.URL); err != nil {
t.Error(err)
}

var tests = map[string]cmdTest{
"set volume": {
"temperature climate.heating 21.5",
"(?m)^.*heating temperature set to 21.5",
"",
},
}

testCmd(t, h, tests)
}
15 changes: 15 additions & 0 deletions pkg/hctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ func (h *Hctl) VolumeSet(obj string, volume string) (string, string, error) {
return obj, state, nil
}

func (h *Hctl) TemperatureSet(obj string, temp string) (string, string, error) {
tint, err := strconv.ParseFloat(temp, 64)
if err != nil {
log.Debug().Caller().Msgf("Error: %+v", err)
return "", "", err
}
obj, state, sub, err := h.GetRest().TemperatureSet(obj, tint)
if err != nil {
log.Debug().Caller().Msgf("Error: %+v", err)
return "", "", err
}
log.Debug().Caller().Msgf("Result: %s(%s) to %s", obj, sub, state)
return obj, state, nil
}

func (h *Hctl) SetLogging(level string) error {
lvl, err := zerolog.ParseLevel(level)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
24 changes: 24 additions & 0 deletions pkg/hctltest/testdata/states.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,29 @@
"parent_id": null,
"user_id": null
}
},
{
"entity_id": "climate.heating",
"state": "heat",
"attributes": {
"hvac_modes": ["heat", "off"],
"min_temp": 10,
"max_temp": 32,
"preset_modes": ["none", "eco"],
"current_temperature": 21.8,
"temperature": 21.0,
"hvac_action": "idle",
"preset_mode": "none",
"friendly_name": "Heating",
"supported_features": 401
},
"last_changed": "2024-10-26T15:44:30.745281+00:00",
"last_reported": "2024-10-27T12:16:14.818589+00:00",
"last_updated": "2024-10-27T12:16:14.818589+00:00",
"context": {
"id": "ABDCDEFGHIJKLMNOPQRSTUVW11",
"parent_id": null,
"user_id": null
}
}
]
2 changes: 1 addition & 1 deletion pkg/rest/states_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

const (
statesCount = 10
statesCount = 11
)

func Test_GetStates(t *testing.T) {
Expand Down
40 changes: 40 additions & 0 deletions pkg/rest/temperature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2024 Fabian `xx4h` Sylvester
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rest

import "fmt"

func (h *Hass) TemperatureSet(obj string, temp float64) (string, string, string, error) {
svc := "set_temperature"
sub, obj, err := h.entityArgHandler([]string{obj}, svc)
if err != nil {
return "", "", "", err
}

payload := map[string]any{
"entity_id": fmt.Sprintf("%s.%s", sub, obj),
"temperature": fmt.Sprintf("%.1f", temp),
}
res, err := h.api("POST", fmt.Sprintf("/services/%s/%s", sub, svc), payload)
if err != nil {
return "", "", "", err
}

if err := h.getResult(res); err != nil {
return "", "", "", err
}
return obj, fmt.Sprintf("temperature set to %.1f", temp), sub, nil

}

0 comments on commit fc9c13f

Please sign in to comment.