Skip to content

Commit 57ea758

Browse files
committed
add actions to change the rig's power state
1 parent f7d8843 commit 57ea758

4 files changed

Lines changed: 246 additions & 0 deletions

File tree

manifest.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,30 @@
128128
"Controllers": ["Keypad"],
129129
"States": [{ "Title": "Parm" }]
130130
},
131+
{
132+
"Name": "On/Off",
133+
"UUID": "com.thecodingflow.hamlibplugin.onoff",
134+
"Tooltip": "Toggle the rig power on/off",
135+
"Icon": "icons/radio_light",
136+
"DisableAutomaticStates": false,
137+
"VisibleInActionsList": true,
138+
"SupportedInMultiActions": true,
139+
"PropertyInspectorPath": "pi/empty.html",
140+
"Controllers": ["Keypad"],
141+
"States": [{ "Title": "On/Off" }]
142+
},
143+
{
144+
"Name": "Power State",
145+
"UUID": "com.thecodingflow.hamlibplugin.powerstat",
146+
"Tooltip": "Set the rig power state",
147+
"Icon": "icons/radio_light",
148+
"DisableAutomaticStates": false,
149+
"VisibleInActionsList": true,
150+
"SupportedInMultiActions": true,
151+
"PropertyInspectorPath": "pi/powerstat.html",
152+
"Controllers": ["Keypad"],
153+
"States": [{ "Title": "Power" }]
154+
},
131155
{
132156
"Name": "RIT",
133157
"UUID": "com.thecodingflow.hamlibplugin.rit",

pi/powerstat.html

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<script>
5+
let update = () => {};
6+
let statusSetting = "";
7+
8+
function connectOpenActionSocket(
9+
inPort,
10+
inPropertyInspectorUUID,
11+
inRegisterEvent,
12+
inInfo,
13+
inActionInfo,
14+
) {
15+
const websocket = new WebSocket("ws://localhost:" + inPort);
16+
inActionInfo = JSON.parse(inActionInfo);
17+
websocket.onopen = () => {
18+
websocket.send(
19+
JSON.stringify({
20+
event: inRegisterEvent,
21+
uuid: inPropertyInspectorUUID,
22+
}),
23+
);
24+
};
25+
26+
statusSetting = inActionInfo.payload.settings.status ?? "";
27+
28+
websocket.onmessage = (event) => {
29+
const data = JSON.parse(event.data);
30+
if (data.event == "didReceiveSettings") {
31+
statusSetting = data.payload.settings.status ?? "";
32+
}
33+
if (data.event == "sendToPropertyInspector") {
34+
// TODO: receive available options from the plugin
35+
}
36+
};
37+
38+
const statusElement = document.getElementById("status");
39+
statusElement.value = inActionInfo.payload.settings.status ?? "";
40+
41+
update = () => {
42+
websocket.send(
43+
JSON.stringify({
44+
event: "setSettings",
45+
context: inActionInfo.context,
46+
payload: {
47+
status: statusElement.value || "",
48+
},
49+
}),
50+
);
51+
};
52+
}
53+
54+
const connectElgatoStreamDeckSocket = connectOpenActionSocket;
55+
</script>
56+
57+
<style>
58+
* {
59+
font-family: system-ui, sans-serif;
60+
font-size: 16px;
61+
color: oklch(92.2% 0 0);
62+
}
63+
body {
64+
margin: 16px;
65+
background-color: oklch(26.9% 0 0);
66+
}
67+
label {
68+
margin-right: 4px;
69+
}
70+
select {
71+
margin: 4px;
72+
padding: 4px;
73+
background-color: oklch(37.1% 0 0);
74+
color: oklch(92.2% 0 0);
75+
border: 1px solid oklch(43.9% 0 0);
76+
border-radius: 8px;
77+
}
78+
</style>
79+
</head>
80+
81+
<body>
82+
<div>
83+
<label for="status">Power State:</label>
84+
<select id="status" onchange="update()">
85+
<option value="">-- Select --</option>
86+
<option value="0">Off</option>
87+
<option value="1">On</option>
88+
<option value="2">Standby</option>
89+
<option value="4">Operate</option>
90+
</select>
91+
</div>
92+
</body>
93+
</html>

pkg/action/action.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ type RigClient interface {
4747
SetRIT(hl.VFO, hl.Frequency) error
4848
GetXIT(hl.VFO) (hl.Frequency, error)
4949
SetXIT(hl.VFO, hl.Frequency) error
50+
GetPowerStatus() (hl.PowerStatus, error)
51+
SetPowerStatus(hl.PowerStatus) error
5052
}
5153

5254
type Deck interface {

pkg/action/powerstat.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package action
2+
3+
import (
4+
"log"
5+
"strconv"
6+
7+
sdk "github.com/SkYNewZ/streamdeck-sdk"
8+
"github.com/ftl/hl-go"
9+
)
10+
11+
const (
12+
PowerStatUUID = "com.thecodingflow.hamlibplugin.powerstat"
13+
OnOffUUID = "com.thecodingflow.hamlibplugin.onoff"
14+
)
15+
16+
func init() {
17+
Factories[PowerStatUUID] = NewPowerStat
18+
Factories[OnOffUUID] = NewOnOff
19+
}
20+
21+
type PowerStat struct {
22+
basicAction
23+
}
24+
25+
func NewPowerStat(context string, client RigClient, deck Deck) Action {
26+
return &PowerStat{
27+
basicAction: basicAction{
28+
context: context,
29+
client: client,
30+
deck: deck,
31+
},
32+
}
33+
}
34+
35+
func (a *PowerStat) parseSettings(settings map[string]any) hl.PowerStatus {
36+
statusString, ok := settings["status"].(string)
37+
if !ok {
38+
statusString = "0"
39+
}
40+
status, err := strconv.Atoi(statusString)
41+
if err != nil {
42+
status = 0
43+
}
44+
return hl.PowerStatus(status)
45+
}
46+
47+
func (a *PowerStat) DidReceiveSettings(payload *sdk.ReceivedEventPayload) error {
48+
a.UpdateVisual(payload)
49+
return nil
50+
}
51+
52+
func (a *PowerStat) UpdateVisual(payload *sdk.ReceivedEventPayload) error {
53+
status := a.parseSettings(payload.Settings)
54+
title := powerStatusTitle(status)
55+
a.deck.SetTitle(a.context, title, sdk.HardwareAndSoftware)
56+
return nil
57+
}
58+
59+
func (a *PowerStat) KeyDown(payload *sdk.ReceivedEventPayload) error {
60+
status := a.parseSettings(payload.Settings)
61+
62+
err := a.client.SetPowerStatus(status)
63+
if err != nil {
64+
log.Printf("[ERROR] set power status %d: %v", status, err)
65+
}
66+
return nil
67+
}
68+
69+
type OnOff struct {
70+
basicAction
71+
}
72+
73+
func NewOnOff(context string, client RigClient, deck Deck) Action {
74+
return &OnOff{
75+
basicAction: basicAction{
76+
context: context,
77+
client: client,
78+
deck: deck,
79+
},
80+
}
81+
}
82+
83+
func (a *OnOff) DidReceiveSettings(payload *sdk.ReceivedEventPayload) error {
84+
a.UpdateVisual(payload)
85+
return nil
86+
}
87+
88+
func (a *OnOff) UpdateVisual(payload *sdk.ReceivedEventPayload) error {
89+
a.deck.SetTitle(a.context, "On/Off", sdk.HardwareAndSoftware)
90+
return nil
91+
}
92+
93+
func (a *OnOff) KeyDown(payload *sdk.ReceivedEventPayload) error {
94+
current, err := a.client.GetPowerStatus()
95+
if err != nil {
96+
log.Printf("[ERROR] get power status: %v", err)
97+
return nil
98+
}
99+
100+
var newStatus hl.PowerStatus
101+
if current == hl.PowerOff {
102+
newStatus = hl.PowerOn
103+
} else {
104+
newStatus = hl.PowerOff
105+
}
106+
107+
err = a.client.SetPowerStatus(newStatus)
108+
if err != nil {
109+
log.Printf("[ERROR] set power status %d: %v", newStatus, err)
110+
}
111+
return nil
112+
}
113+
114+
func powerStatusTitle(status hl.PowerStatus) string {
115+
switch status {
116+
case hl.PowerOff:
117+
return "Off"
118+
case hl.PowerOn:
119+
return "On"
120+
case hl.PowerStandby:
121+
return "Standby"
122+
case hl.PowerOperate:
123+
return "Operate"
124+
default:
125+
return "Power"
126+
}
127+
}

0 commit comments

Comments
 (0)