Fixing slack stuff
This commit is contained in:
@@ -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():
|
||||||
|
|||||||
@@ -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: |
|
||||||
|
|||||||
@@ -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: |
|
||||||
|
|||||||
Reference in New Issue
Block a user