diff options
Diffstat (limited to 'cfa635/report.go')
-rw-r--r-- | cfa635/report.go | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/cfa635/report.go b/cfa635/report.go new file mode 100644 index 0000000..84541bc --- /dev/null +++ b/cfa635/report.go @@ -0,0 +1,109 @@ +// Copyright 2022 Benjamin Barenblat +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +package cfa635 + +import ( + "encoding/binary" + "errors" +) + +var ( + errUnknownReportType = errors.New("failed to read report: unknown type") + errUnknownKey = errors.New("failed to read key activity report: unknown key") + errFBSCAB = errors.New("failed to read fan speed report: FBSCAB module disconnected") + errDOW = errors.New("failed to read temperature report: DOW sensor error") +) + +// KeyActivity is a report that a key has been pressed or released. +type KeyActivity struct { + K Key + Pressed bool +} + +// Key represents a button on the CFA635. +type Key int + +const ( + _ Key = iota + UpButton + DownButton + LeftButton + RightButton + EnterButton + ExitButton +) + +// FanSpeed is a report on the speed of a system fan. +type FanSpeed struct { + N int + TachCycles int + TimerTicks int +} + +// Temperature is a report on the system temperature. +type Temperature struct { + N int // Sensor number. + Celsius float64 +} + +// decodeReport converts a packet into either a *KeyActivity, a *FanSpeed, or a +// *Temperature, depending on the packet's type tag. +func decodeReport(p []byte) (any, error) { + switch p[0] { + case 0x80: + return decodeKeyActivity(p[2]) + case 0x81: + return decodeFanSpeed(p[2:6]) + case 0x82: + return decodeTemperature(p[2:6]) + default: + return nil, errUnknownReportType + } +} + +// decodeKeyActivity converts the data byte from a key activity report to a +// KeyActivity. +func decodeKeyActivity(b byte) (*KeyActivity, error) { + if b == 0 || b > 12 { + return nil, errUnknownKey + } + + var a KeyActivity + if b < 7 { + a.Pressed = true + } else { + b -= 6 + } + a.K = Key(b) + return &a, nil +} + +// decodeFanSpeed converts the data part of a fan speed report packet to a +// FanSpeed. +func decodeFanSpeed(b []byte) (*FanSpeed, error) { + if b[1] == 0 && b[2] == 0 && b[3] == 0 { + return nil, errFBSCAB + } + return &FanSpeed{int(b[0]), int(b[1]), int(binary.BigEndian.Uint16(b[2:4]))}, nil +} + +// decodeTemperature converts the data part of a temperature report packet to a +// Temperature. +func decodeTemperature(b []byte) (*Temperature, error) { + if b[3] == 0 { + return nil, errDOW + } + return &Temperature{int(b[0]), float64(binary.BigEndian.Uint16(b[1:3])) / 16}, nil +} |