package hwinfostreamdeckplugin import ( "fmt" "image/color" "strconv" hwsensorsservice "github.com/shayne/hwinfo-streamdeck/pkg/service" "github.com/shayne/hwinfo-streamdeck/pkg/streamdeck" ) func (p *Plugin) handleSensorSelect(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { sensorid := sdpi.Value readings, err := p.hw.ReadingsForSensorID(sensorid) if err != nil { return fmt.Errorf("handleSensorSelect ReadingsBySensor failed: %v", err) } evreadings := []*evSendReadingsPayloadReading{} for _, r := range readings { evreadings = append(evreadings, &evSendReadingsPayloadReading{ID: r.ID(), Label: r.Label(), Prefix: r.Unit()}) } settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleReadingSelect getSettings: %v", err) } // only update settings if SensorUID is changing // this covers case where PI sends event when tile // selected in SD UI if settings.SensorUID != sensorid { settings.SensorUID = sensorid settings.ReadingID = 0 settings.IsValid = false } payload := evSendReadingsPayload{Readings: evreadings, Settings: &settings} err = p.sd.SendToPropertyInspector(event.Action, event.Context, payload) if err != nil { return fmt.Errorf("sensorsSelect SendToPropertyInspector: %v", err) } err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleSensorSelect SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func getDefaultMinMaxForReading(r hwsensorsservice.Reading) (int, int) { switch r.Unit() { case "%": return 0, 100 case "Yes/No": return 0, 1 } min := r.ValueMin() max := r.ValueMax() min -= min * .2 if min <= 0 { min = 0. } max += max * .2 return int(min), int(max) } func (p *Plugin) handleReadingSelect(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { rid64, err := strconv.ParseInt(sdpi.Value, 10, 32) if err != nil { return fmt.Errorf("handleReadingSelect Atoi failed: %s, %v", sdpi.Value, err) } rid := int32(rid64) settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleReadingSelect getSettings: %v", err) } // no action if reading didn't change if settings.ReadingID == rid { return nil } settings.ReadingID = rid // set default min/max r, err := p.getReading(settings.SensorUID, settings.ReadingID) if err != nil { return fmt.Errorf("handleReadingSelect getReading: %v", err) } g, ok := p.graphs[event.Context] if !ok { return fmt.Errorf("handleReadingSelect no graph for context: %s", event.Context) } defaultMin, defaultMax := getDefaultMinMaxForReading(r) settings.Min = defaultMin g.SetMin(settings.Min) settings.Max = defaultMax g.SetMax(settings.Max) settings.IsValid = true // set IsValid once we choose reading err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleReadingSelect SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func (p *Plugin) handleSetMin(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { min, err := strconv.Atoi(sdpi.Value) if err != nil { return fmt.Errorf("handleSetMin strconv: %v", err) } g, ok := p.graphs[event.Context] if !ok { return fmt.Errorf("handleSetMax no graph for context: %s", event.Context) } g.SetMin(min) settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleSetMin getSettings: %v", err) } settings.Min = min err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleSetMin SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func (p *Plugin) handleSetMax(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { max, err := strconv.Atoi(sdpi.Value) if err != nil { return fmt.Errorf("handleSetMax strconv: %v", err) } g, ok := p.graphs[event.Context] if !ok { return fmt.Errorf("handleSetMax no graph for context: %s", event.Context) } g.SetMax(max) settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleSetMax getSettings: %v", err) } settings.Max = max err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleSetMax SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func (p *Plugin) handleSetFormat(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { format := sdpi.Value settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleSetFormat getSettings: %v", err) } settings.Format = format err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleSetFormat SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func (p *Plugin) handleDivisor(event *streamdeck.EvSendToPlugin, sdpi *evSdpiCollection) error { divisor := sdpi.Value settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleDivisor getSettings: %v", err) } settings.Divisor = divisor err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleDivisor SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } const ( hexFormat = "#%02x%02x%02x" hexShortFormat = "#%1x%1x%1x" hexToRGBFactor = 17 ) func hexToRGBA(hex string) *color.RGBA { var r, g, b uint8 if len(hex) == 4 { fmt.Sscanf(hex, hexShortFormat, &r, &g, &b) r *= hexToRGBFactor g *= hexToRGBFactor b *= hexToRGBFactor } else { fmt.Sscanf(hex, hexFormat, &r, &g, &b) } return &color.RGBA{R: r, G: g, B: b, A: 255} } func (p *Plugin) handleColorChange(event *streamdeck.EvSendToPlugin, key string, sdpi *evSdpiCollection) error { hex := sdpi.Value settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("handleDivisor getSettings: %v", err) } g, ok := p.graphs[event.Context] if !ok { return fmt.Errorf("handleSetMax no graph for context: %s", event.Context) } clr := hexToRGBA(hex) switch key { case "foreground": settings.ForegroundColor = hex g.SetForegroundColor(clr) case "background": settings.BackgroundColor = hex g.SetBackgroundColor(clr) case "highlight": settings.HighlightColor = hex g.SetHighlightColor(clr) case "valuetext": settings.ValueTextColor = hex g.SetLabelColor(1, clr) } err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("handleColorChange SetSettings: %v", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil } func (p *Plugin) handleSetFontSize(event *streamdeck.EvSendToPlugin, key string, sdpi *evSdpiCollection) error { sv := sdpi.Value size, err := strconv.ParseFloat(sv, 64) if err != nil { return fmt.Errorf("failed to convert value to float: %w", err) } settings, err := p.am.getSettings(event.Context) if err != nil { return fmt.Errorf("getSettings failed: %w", err) } g, ok := p.graphs[event.Context] if !ok { return fmt.Errorf("no graph for context: %s", event.Context) } switch key { case "titleFontSize": settings.TitleFontSize = size g.SetLabelFontSize(0, size) case "valueFontSize": settings.ValueFontSize = size g.SetLabelFontSize(1, size) default: return fmt.Errorf("invalid key: %s", sdpi.Key) } err = p.sd.SetSettings(event.Context, &settings) if err != nil { return fmt.Errorf("SetSettings failed: %w", err) } p.am.SetAction(event.Action, event.Context, &settings) return nil }