Fixing slack stuff

This commit is contained in:
lwoodard
2026-04-14 05:43:30 -06:00
parent 91b7028382
commit 6c5f3072a2
3 changed files with 26 additions and 3 deletions

View File

@@ -172,6 +172,7 @@ func run(ctx context.Context, sd *device.StreamDeck, cfg *config.Config, reg *mo
for keyIdx, keyCfg := range cfg.Keys { for keyIdx, keyCfg := range cfg.Keys {
// Resolve module-based commands to shell strings before any other logic. // Resolve module-based commands to shell strings before any other logic.
// keyCfg is a copy from the map, so we must write it back after modification.
if keyCfg.Module != "" { if keyCfg.Module != "" {
resolved, err := reg.Resolve(keyCfg.Module, keyCfg.Function, keyCfg.Params) resolved, err := reg.Resolve(keyCfg.Module, keyCfg.Function, keyCfg.Params)
if err != nil { if err != nil {
@@ -179,6 +180,7 @@ func run(ctx context.Context, sd *device.StreamDeck, cfg *config.Config, reg *mo
continue continue
} }
keyCfg.Command = resolved keyCfg.Command = resolved
cfg.Keys[keyIdx] = keyCfg
} }
if keyCfg.Poll != nil && keyCfg.Poll.Module != "" { if keyCfg.Poll != nil && keyCfg.Poll.Module != "" {
resolved, err := reg.Resolve(keyCfg.Poll.Module, keyCfg.Poll.Function, keyCfg.Poll.Params) resolved, err := reg.Resolve(keyCfg.Poll.Module, keyCfg.Poll.Function, keyCfg.Poll.Params)
@@ -187,6 +189,7 @@ func run(ctx context.Context, sd *device.StreamDeck, cfg *config.Config, reg *mo
continue continue
} }
keyCfg.Poll.Command = resolved keyCfg.Poll.Command = resolved
cfg.Keys[keyIdx] = keyCfg
} }
// Toggle/status key: managed by a polling goroutine. // Toggle/status key: managed by a polling goroutine.
@@ -414,7 +417,14 @@ func mustConnect(vendorID, productID uint16) *device.StreamDeck {
} }
// animateKey cycles pre-encoded GIF frames on a key until ctx is cancelled. // animateKey cycles pre-encoded GIF frames on a key until ctx is cancelled.
//
// Transient HID write errors (USB bus contention, especially with multiple
// concurrent GIFs) are suppressed after the first occurrence to avoid log spam.
// A summary is logged when errors stop or when they become persistent enough
// to indicate a real device problem.
func animateKey(ctx context.Context, sd *device.StreamDeck, keyIdx int, frames [][]byte, delays []time.Duration) { func animateKey(ctx context.Context, sd *device.StreamDeck, keyIdx int, frames [][]byte, delays []time.Duration) {
var writeErrors int // consecutive HID write failures
for { for {
for i, frame := range frames { for i, frame := range frames {
select { select {
@@ -423,7 +433,20 @@ func animateKey(ctx context.Context, sd *device.StreamDeck, keyIdx int, frames [
default: default:
} }
if err := sd.SetKeyFrame(keyIdx, frame); err != nil { if err := sd.SetKeyFrame(keyIdx, frame); err != nil {
log.Printf("key %d: animate frame %d: %v", keyIdx, i, err) writeErrors++
if writeErrors == 1 {
// Log the first error so the user knows something happened.
log.Printf("key %d: frame write error: %v", keyIdx, err)
} else if writeErrors == 50 {
// Persistent errors — likely a real device issue, not transient.
log.Printf("key %d: %d consecutive frame write errors — device may be unhealthy", keyIdx, writeErrors)
}
} else if writeErrors > 0 {
// Recovered — log a summary if we suppressed errors.
if writeErrors > 1 {
log.Printf("key %d: recovered after %d frame write errors", keyIdx, writeErrors)
}
writeErrors = 0
} }
select { select {
case <-ctx.Done(): case <-ctx.Done():

View File

@@ -50,7 +50,7 @@ modules:
curl -s -X POST https://slack.com/api/users.profile.set \ curl -s -X POST https://slack.com/api/users.profile.set \
-H "Authorization: Bearer {{env "SLACK_TOKEN"}}" \ -H "Authorization: Bearer {{env "SLACK_TOKEN"}}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"profile":{"status_emoji":"","status_text":"","status_expiration":0}}' -d '{"profile":{"status_emoji":":dumpsterfire:","status_text":"Offline","status_expiration":0}}'
end_snooze: end_snooze:
exec: | exec: |

View File

@@ -50,7 +50,7 @@ modules:
curl -s -X POST https://slack.com/api/users.profile.set \ curl -s -X POST https://slack.com/api/users.profile.set \
-H "Authorization: Bearer {{env "SLACK_TOKEN"}}" \ -H "Authorization: Bearer {{env "SLACK_TOKEN"}}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"profile":{"status_emoji":"","status_text":"","status_expiration":0}}' -d '{"profile":{"status_emoji":":dumpsterfire:","status_text":"Offline","status_expiration":0}}'
end_snooze: end_snooze:
exec: | exec: |