@@ -2,8 +2,6 @@ package main
2
2
3
3
import (
4
4
"context"
5
- "fmt"
6
- "slices"
7
5
"strings"
8
6
"time"
9
7
@@ -16,16 +14,19 @@ import (
16
14
// TYPES
17
15
18
16
type haEntity struct {
19
- Id string `json:"entity_id"`
17
+ Id string `json:"entity_id,width:40 "`
20
18
Name string `json:"name,omitempty"`
21
19
Class string `json:"class,omitempty"`
20
+ Domain string `json:"domain,omitempty"`
22
21
State string `json:"state,omitempty"`
23
22
Attributes map [string ]interface {} `json:"attributes,omitempty,wrap"`
24
- UpdatedAt time.Time `json:"last_updated,omitempty"`
23
+ UpdatedAt time.Time `json:"last_updated,omitempty,width:34"`
24
+ ChangedAt time.Time `json:"last_changed,omitempty,width:34"`
25
25
}
26
26
27
- type haClass struct {
28
- Class string `json:"class,omitempty"`
27
+ type haDomain struct {
28
+ Name string `json:"domain"`
29
+ Services string `json:"services,omitempty"`
29
30
}
30
31
31
32
///////////////////////////////////////////////////////////////////////////////
@@ -49,8 +50,9 @@ func haRegister(flags *Flags) {
49
50
Description : "Information from home assistant" ,
50
51
Parse : haParse ,
51
52
Fn : []Fn {
52
- {Name : "classes" , Call : haClasses , Description : "Return entity classes" },
53
- {Name : "states" , Call : haStates , Description : "Return entity states" },
53
+ {Name : "domains" , Call : haDomains , Description : "Enumerate entity domains" },
54
+ {Name : "states" , Call : haStates , Description : "Show current entity states" , MaxArgs : 1 , Syntax : "(<name>)" },
55
+ {Name : "services" , Call : haServices , Description : "Show services for an entity" , MinArgs : 1 , MaxArgs : 1 , Syntax : "<entity>" },
54
56
},
55
57
})
56
58
}
@@ -71,14 +73,25 @@ func haParse(flags *Flags, opts ...client.ClientOpt) error {
71
73
// METHODS
72
74
73
75
func haStates (_ context.Context , w * tablewriter.Writer , args []string ) error {
74
- if states , err := haGetStates (args ); err != nil {
76
+ var result []haEntity
77
+ states , err := haGetStates (nil )
78
+ if err != nil {
75
79
return err
76
- } else {
77
- return w .Write (states )
78
80
}
81
+
82
+ for _ , state := range states {
83
+ if len (args ) == 1 {
84
+ if ! haMatchString (args [0 ], state .Name , state .Id ) {
85
+ continue
86
+ }
87
+
88
+ }
89
+ result = append (result , state )
90
+ }
91
+ return w .Write (result )
79
92
}
80
93
81
- func haClasses (_ context.Context , w * tablewriter.Writer , args []string ) error {
94
+ func haDomains (_ context.Context , w * tablewriter.Writer , args []string ) error {
82
95
states , err := haGetStates (nil )
83
96
if err != nil {
84
97
return err
@@ -89,17 +102,42 @@ func haClasses(_ context.Context, w *tablewriter.Writer, args []string) error {
89
102
classes [state .Class ] = true
90
103
}
91
104
92
- result := []haClass {}
105
+ result := []haDomain {}
93
106
for c := range classes {
94
- result = append (result , haClass {Class : c })
107
+ result = append (result , haDomain {
108
+ Name : c ,
109
+ })
95
110
}
96
111
return w .Write (result )
97
112
}
98
113
114
+ func haServices (_ context.Context , w * tablewriter.Writer , args []string ) error {
115
+ service , err := haClient .State (args [0 ])
116
+ if err != nil {
117
+ return err
118
+ }
119
+ services , err := haClient .Services (service .Domain ())
120
+ if err != nil {
121
+ return err
122
+ }
123
+ return w .Write (services )
124
+ }
125
+
99
126
///////////////////////////////////////////////////////////////////////////////
100
127
// PRIVATE METHODS
101
128
102
- func haGetStates (classes []string ) ([]haEntity , error ) {
129
+ func haMatchString (q string , values ... string ) bool {
130
+ q = strings .ToLower (q )
131
+ for _ , v := range values {
132
+ v = strings .ToLower (v )
133
+ if strings .Contains (v , q ) {
134
+ return true
135
+ }
136
+ }
137
+ return false
138
+ }
139
+
140
+ func haGetStates (domains []string ) ([]haEntity , error ) {
103
141
var result []haEntity
104
142
105
143
// Get states from the remote service
@@ -112,37 +150,29 @@ func haGetStates(classes []string) ([]haEntity, error) {
112
150
for _ , state := range states {
113
151
entity := haEntity {
114
152
Id : state .Entity ,
115
- State : state .State ,
153
+ Name : state .Name (),
154
+ Domain : state .Domain (),
155
+ Class : state .Class (),
156
+ State : state .Value (),
116
157
Attributes : state .Attributes ,
117
- UpdatedAt : state .LastChanged ,
158
+ UpdatedAt : state .LastUpdated ,
159
+ ChangedAt : state .LastChanged ,
118
160
}
119
161
120
- // Ignore entities without state
121
- if entity .State == "" || entity . State == "unknown" || entity . State == "unavailable" {
162
+ // Ignore any fields where the state is empty
163
+ if entity .State == "" {
122
164
continue
123
165
}
124
166
125
- // Set entity type and name from entity id
126
- parts := strings .SplitN (entity .Id , "." , 2 )
127
- if len (parts ) >= 2 {
128
- entity .Class = strings .ToLower (parts [0 ])
129
- entity .Name = parts [1 ]
130
- }
131
-
132
- // Set entity type from device class
133
- if t , exists := state .Attributes ["device_class" ]; exists {
134
- entity .Class = fmt .Sprint (t )
167
+ // Add unit of measurement
168
+ if unit := state .UnitOfMeasurement (); unit != "" {
169
+ entity .State += " " + unit
135
170
}
136
171
137
- // Filter classes
138
- if len (classes ) > 0 && ! slices .Contains (classes , entity .Class ) {
139
- continue
140
- }
141
-
142
- // Set entity name from attributes
143
- if name , exists := state .Attributes ["friendly_name" ]; exists {
144
- entity .Name = fmt .Sprint (name )
145
- }
172
+ // Filter domains
173
+ //if len(domains) > 0 && !slices.Contains(domains, entity.Domain) {
174
+ // continue
175
+ //}
146
176
147
177
// Append results
148
178
result = append (result , entity )
0 commit comments