Skip to content

Commit 14a83ab

Browse files
committed
introduce cli and gh actions for executables
Signed-off-by: Jeeva Kandasamy <jkandasa@gmail.com>
1 parent 18233af commit 14a83ab

20 files changed

+1008
-23
lines changed

.github/workflows/lint.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: golangci-lint
2+
on:
3+
push:
4+
branches: [main]
5+
tags: ["v*"]
6+
pull_request:
7+
8+
jobs:
9+
golang-lint:
10+
name: lint
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
- uses: actions/setup-go@v2
15+
with:
16+
go-version: ^1.21
17+
18+
- name: golangci-lint
19+
uses: golangci/golangci-lint-action@v2
20+
with:
21+
version: latest
22+
skip-go-installation: true
23+
# Optional: show only new issues if it's a pull request. The default value is `false`.
24+
# only-new-issues: true
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: publish executables
2+
on:
3+
push:
4+
branches: [main]
5+
tags: ["v*"]
6+
7+
jobs:
8+
setup:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- name: checkout the source code
13+
uses: actions/checkout@v2
14+
15+
- uses: actions/setup-go@v2
16+
with:
17+
go-version: ^1.21
18+
19+
- name: Cache go modules
20+
uses: actions/cache@v2
21+
with:
22+
path: ~/go/pkg/mod
23+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
24+
restore-keys: |
25+
${{ runner.os }}-go-
26+
27+
- name: build executable bundles
28+
run: ./scripts/generate_executables.sh
29+
30+
- name: generate a build timestamp and sha256sum files
31+
run: |
32+
cd builds
33+
echo `date -u +'%Y%m%d%H%M%S'` > ./build_timestamp.txt
34+
echo `date -u +'%Y-%m-%dT%H:%M:%S%:z'` >> ./build_timestamp.txt
35+
sha256sum *.tar.gz > ./SHA256SUMS.txt
36+
sha256sum *.zip >> ./SHA256SUMS.txt
37+
38+
- name: update release notes and executables
39+
if: startsWith(github.ref, 'refs/tags/') # executes only for new release
40+
uses: softprops/action-gh-release@v1
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
43+
with:
44+
files: |
45+
builds/*.tar.gz
46+
builds/*.zip
47+
builds/build_timestamp.txt
48+
builds/SHA256SUMS.txt
49+
50+
- name: Update executables for main branch changes
51+
if: startsWith(github.ref, 'refs/heads/main') # executes only for changes in main
52+
uses: "marvinpinto/action-automatic-releases@latest"
53+
with:
54+
repo_token: "${{ secrets.GH_TOKEN }}"
55+
automatic_release_tag: development
56+
prerelease: true
57+
title: "Development Build - Pre Release"
58+
files: |
59+
builds/*.tar.gz
60+
builds/*.zip
61+
builds/build_timestamp.txt
62+
builds/SHA256SUMS.txt

cli/command/device/device.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package device
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
rootCmd "github.com/mycontroller-org/esphome_api/cli/command/root"
8+
"github.com/mycontroller-org/server/v2/pkg/utils/printer"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
func init() {
13+
rootCmd.AddCommand(deviceContextCmd)
14+
rootCmd.AddCommand(getDevicesCmd)
15+
}
16+
17+
var deviceContextCmd = &cobra.Command{
18+
Use: "device",
19+
Short: "Switch or set a device",
20+
Example: ` # set a node
21+
esphomectl device my-device-1
22+
23+
# get the active device
24+
esphomectl device
25+
`,
26+
Args: cobra.MaximumNArgs(1),
27+
Run: func(cmd *cobra.Command, args []string) {
28+
if len(args) == 0 {
29+
if rootCmd.CONFIG.Active == "" {
30+
fmt.Fprintln(cmd.OutOrStdout(), "No resource found")
31+
return
32+
}
33+
fmt.Fprintf(cmd.ErrOrStderr(), "Active node '%s'\n", rootCmd.CONFIG.Active)
34+
return
35+
}
36+
rootCmd.CONFIG.Active = strings.TrimSpace(args[0])
37+
client, err := rootCmd.GetActiveClient(nil)
38+
if err != nil {
39+
fmt.Fprintln(cmd.ErrOrStderr(), "Error on login", err)
40+
return
41+
}
42+
if client != nil {
43+
rootCmd.WriteConfigFile()
44+
fmt.Fprintf(cmd.OutOrStdout(), "Switched to '%s'\n", rootCmd.CONFIG.Active)
45+
}
46+
},
47+
}
48+
49+
var getDevicesCmd = &cobra.Command{
50+
Use: "devices",
51+
Short: "Display configured devices",
52+
Example: ` # display configured devices
53+
esphomectl devices
54+
`,
55+
Run: func(cmd *cobra.Command, args []string) {
56+
if len(rootCmd.CONFIG.Devices) == 0 {
57+
fmt.Fprintln(cmd.OutOrStdout(), "No resource found")
58+
return
59+
}
60+
headers := []printer.Header{
61+
{Title: "address", ValuePath: "address"},
62+
{Title: "name", ValuePath: "info.name"},
63+
{Title: "model", ValuePath: "info.model"},
64+
{Title: "mac address", ValuePath: "info.macAddress"},
65+
{Title: "version", ValuePath: "info.esphomeVersion"},
66+
{Title: "compilation time", ValuePath: "info.compilationTime"},
67+
{Title: "uses password", ValuePath: "info.usesPassword"},
68+
{Title: "has deep sleep", ValuePath: "info.hasDeepSleep"},
69+
{Title: "timeout", ValuePath: "timeout", IsWide: true},
70+
{Title: "status on", ValuePath: "info.statusOn", DisplayStyle: printer.DisplayStyleRelativeTime},
71+
}
72+
data := make([]interface{}, 0)
73+
for _, device := range rootCmd.CONFIG.Devices {
74+
data = append(data, device)
75+
}
76+
printer.Print(cmd.OutOrStdout(), headers, data, rootCmd.HideHeader, rootCmd.OutputFormat, rootCmd.Pretty)
77+
},
78+
}

cli/command/device/get.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package device
2+
3+
import (
4+
rootCmd "github.com/mycontroller-org/esphome_api/cli/command/root"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func init() {
9+
rootCmd.AddCommand(getCmd)
10+
}
11+
12+
var getCmd = &cobra.Command{
13+
Use: "get",
14+
Short: "List resources",
15+
}

cli/command/device/get_entities.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package device
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"time"
7+
8+
rootCmd "github.com/mycontroller-org/esphome_api/cli/command/root"
9+
"github.com/mycontroller-org/esphome_api/pkg/api"
10+
"github.com/mycontroller-org/server/v2/pkg/utils/convertor"
11+
filterUtils "github.com/mycontroller-org/server/v2/pkg/utils/filter_sort"
12+
"github.com/mycontroller-org/server/v2/pkg/utils/printer"
13+
"github.com/spf13/cobra"
14+
"google.golang.org/protobuf/proto"
15+
)
16+
17+
var (
18+
entitiesTimeout time.Duration
19+
)
20+
21+
func init() {
22+
getCmd.AddCommand(getEntitiesCmd)
23+
getEntitiesCmd.Flags().DurationVar(&entitiesTimeout, "timeout", 5*time.Second, "Timeout to wait for entities")
24+
}
25+
26+
var getEntitiesCmd = &cobra.Command{
27+
Use: "entity",
28+
Short: "Lists available entities",
29+
Aliases: []string{"entities"},
30+
Example: ` # lists available entities
31+
esphomectl get entities
32+
33+
# list entities with a timeout
34+
esphomectl get entities --timeout 10s
35+
`,
36+
Run: func(cmd *cobra.Command, args []string) {
37+
38+
entitiesCollectionDone := false
39+
entities := map[string][]interface{}{}
40+
collectEntities := func(msg proto.Message) {
41+
switch entity := msg.(type) {
42+
case *api.ListEntitiesDoneResponse:
43+
entitiesCollectionDone = true
44+
45+
default:
46+
_, _deviceClass, err := filterUtils.GetValueByKeyPath(entity, "deviceClass")
47+
if err != nil {
48+
fmt.Fprintln(cmd.ErrOrStderr(), "error:", err)
49+
return
50+
}
51+
deviceClass := convertor.ToString(_deviceClass)
52+
_sensors, found := entities[deviceClass]
53+
if !found {
54+
_sensors = make([]interface{}, 0)
55+
}
56+
_sensors = append(_sensors, entity)
57+
entities[deviceClass] = _sensors
58+
}
59+
}
60+
61+
client, err := rootCmd.GetActiveClient(collectEntities)
62+
if err != nil {
63+
fmt.Fprintln(cmd.ErrOrStderr(), "error:", err.Error())
64+
return
65+
}
66+
67+
err = client.ListEntities()
68+
if err != nil {
69+
fmt.Fprintln(cmd.ErrOrStderr(), "error:", err.Error())
70+
return
71+
}
72+
73+
ticker := time.NewTicker(200 * time.Millisecond)
74+
timeoutTime := time.Now().Add(entitiesTimeout)
75+
for range ticker.C {
76+
if entitiesCollectionDone || time.Now().Before(timeoutTime) {
77+
break
78+
}
79+
}
80+
81+
if len(entities) == 0 {
82+
fmt.Fprintln(cmd.OutOrStdout(), "No resource found")
83+
return
84+
}
85+
86+
for k, _sensors := range entities {
87+
fmt.Fprintln(cmd.OutOrStdout())
88+
fmt.Fprintln(cmd.OutOrStdout(), strings.ToUpper(k))
89+
90+
switch k {
91+
case "light":
92+
headers := []printer.Header{
93+
{Title: "name", ValuePath: "name"},
94+
{Title: "object id", ValuePath: "objectId"},
95+
{Title: "key", ValuePath: "key"},
96+
{Title: "unique id", ValuePath: "uniqueId"},
97+
{Title: "effects", ValuePath: "effects"},
98+
{Title: "icon", ValuePath: "icon"},
99+
}
100+
printer.Print(cmd.OutOrStdout(), headers, _sensors, rootCmd.HideHeader, rootCmd.OutputFormat, rootCmd.Pretty)
101+
102+
default:
103+
headers := []printer.Header{
104+
{Title: "name", ValuePath: "name"},
105+
{Title: "object id", ValuePath: "objectId"},
106+
{Title: "key", ValuePath: "key"},
107+
{Title: "unique id", ValuePath: "uniqueId"},
108+
{Title: "device class", ValuePath: "deviceClass"},
109+
}
110+
printer.Print(cmd.OutOrStdout(), headers, _sensors, rootCmd.HideHeader, rootCmd.OutputFormat, rootCmd.Pretty)
111+
112+
}
113+
114+
}
115+
116+
},
117+
}

cli/command/device/set.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package device
2+
3+
import (
4+
rootCmd "github.com/mycontroller-org/esphome_api/cli/command/root"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func init() {
9+
rootCmd.AddCommand(setCmd)
10+
}
11+
12+
var setCmd = &cobra.Command{
13+
Use: "set",
14+
Short: "update resource state",
15+
}

cli/command/device/set_entities.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package device
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
)
6+
7+
func init() {
8+
setCmd.AddCommand(setEntitiesCmd)
9+
}
10+
11+
var setEntitiesCmd = &cobra.Command{
12+
Use: "entity",
13+
Short: "Updates entity value",
14+
Example: ` # lists available entities
15+
esphomectl set entities unique_id --payload test=on
16+
`,
17+
Args: cobra.MinimumNArgs(1),
18+
Run: func(cmd *cobra.Command, args []string) {
19+
// _client, err := rootCmd.GetActiveClient(nil)
20+
// if err != nil {
21+
// fmt.Fprintln(cmd.ErrOrStderr(), "error:", err.Error())
22+
// return
23+
// }
24+
//
25+
// var request proto.Message
26+
27+
},
28+
}

0 commit comments

Comments
 (0)