| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package main
- import (
- "errors"
- "fmt"
- "github.com/spf13/cobra"
- intrgb "netdome.biz/paul/qmk-rgb/internal/rgb"
- "netdome.biz/paul/qmk-rgb/internal/via"
- )
- type infoGetter interface {
- GetValue(via.Channel, uint8) ([]byte, error)
- }
- type infoColor struct {
- Hue uint8 `json:"hue"`
- Saturation uint8 `json:"saturation"`
- }
- type zoneInfo struct {
- Zone intrgb.Zone `json:"zone"`
- Channel uint8 `json:"channel"`
- Enabled bool `json:"enabled"`
- Effect string `json:"effect"`
- EffectID uint8 `json:"effectId"`
- Brightness uint8 `json:"brightness"`
- Speed uint8 `json:"speed"`
- Color infoColor `json:"color"`
- Error string `json:"error,omitempty"`
- }
- type infoOutput struct {
- Enabled bool `json:"enabled"`
- Mode string `json:"mode"`
- Brightness uint8 `json:"brightness"`
- Speed uint8 `json:"speed"`
- Zones []zoneInfo `json:"zones"`
- }
- func readInfo(proto infoGetter, zones []intrgb.Zone) (infoOutput, error) {
- out := infoOutput{Zones: make([]zoneInfo, 0, len(zones))}
- var queryErrors []error
- for _, zone := range zones {
- record, err := readZoneInfo(proto, zone)
- out.Zones = append(out.Zones, record)
- if err != nil {
- queryErrors = append(queryErrors, err)
- }
- }
- if len(out.Zones) > 0 {
- first := out.Zones[0]
- out.Enabled = first.Enabled
- out.Mode = first.Effect
- out.Brightness = first.Brightness
- out.Speed = first.Speed
- }
- return out, errors.Join(queryErrors...)
- }
- func readZoneInfo(proto infoGetter, zone intrgb.Zone) (zoneInfo, error) {
- record := zoneInfo{Zone: zone, Channel: zone.Channel()}
- channel := via.Channel(zone.Channel())
- brightness, err := getInfoValue(proto, channel, uint8(intrgb.Brightness), 1)
- if err != nil {
- record.Error = err.Error()
- return record, err
- }
- record.Brightness = brightness[0]
- effect, err := getInfoValue(proto, channel, uint8(intrgb.EffectID), 1)
- if err != nil {
- record.Error = err.Error()
- return record, err
- }
- record.EffectID = effect[0]
- record.Effect = intrgb.EffectName(zone, record.EffectID)
- record.Enabled = lightingEnabled(record.EffectID, record.Brightness)
- speed, err := getInfoValue(proto, channel, uint8(intrgb.Speed), 1)
- if err != nil {
- record.Error = err.Error()
- return record, err
- }
- record.Speed = speed[0]
- color, err := getInfoValue(proto, channel, uint8(intrgb.ColorValue), 2)
- if err != nil {
- record.Error = err.Error()
- return record, err
- }
- record.Color = infoColor{Hue: color[0], Saturation: color[1]}
- return record, nil
- }
- func getInfoValue(proto infoGetter, channel via.Channel, param uint8, size int) ([]byte, error) {
- value, err := proto.GetValue(channel, param)
- if err != nil {
- return nil, err
- }
- if len(value) < size {
- return nil, fmt.Errorf("short value response: got %d, want %d", len(value), size)
- }
- return value, nil
- }
- func NewInfoCmd() *cobra.Command {
- return &cobra.Command{
- Use: "info",
- Short: "Show current RGB state",
- Args: cobra.NoArgs,
- RunE: func(cmd *cobra.Command, args []string) error {
- zones, err := selectedZones()
- if err != nil {
- return err
- }
- proto, err := openRGBProtocol()
- if err != nil {
- return err
- }
- defer proto.Close()
- out, queryErr := readInfo(proto, zones)
- if err := encodeJSON(cmd.OutOrStdout(), out); err != nil {
- return err
- }
- return queryErr
- },
- }
- }
|