mirror of https://git.sr.ht/~michalr/go-satel
87 lines
2.6 KiB
Go
87 lines
2.6 KiB
Go
package satel
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/text/encoding/charmap"
|
|
)
|
|
|
|
type DeviceType byte
|
|
|
|
const (
|
|
DeviceType_Partition DeviceType = 0
|
|
DeviceType_Zone DeviceType = 1
|
|
DeviceType_User DeviceType = 2
|
|
DeviceType_ExpanderOrLCD DeviceType = 3
|
|
DeviceType_Output DeviceType = 4
|
|
DeviceType_ZoneWithPartitionAssignment DeviceType = 5
|
|
DeviceType_Timer DeviceType = 6
|
|
DeviceType_Telephone DeviceType = 7
|
|
DeviceType_Object DeviceType = 15
|
|
DeviceType_PartitionWithObjectAssignment DeviceType = 16
|
|
DeviceType_OutputWithDurationTime DeviceType = 17
|
|
DeviceType_PartitionWithObjectAssignmentAndOptions DeviceType = 18
|
|
)
|
|
|
|
type NameEvent struct {
|
|
DevType DeviceType
|
|
DevNumber byte
|
|
DevTypeFunction byte
|
|
DevName string
|
|
}
|
|
|
|
func makeNameEvent(bytes []byte) (*NameEvent, error) {
|
|
if len(bytes) < 19 {
|
|
return nil, errors.New(fmt.Sprint("Received data too short: ", hex.Dump(bytes)))
|
|
}
|
|
cp1250dec := charmap.Windows1250.NewDecoder()
|
|
name, err := cp1250dec.String(string(bytes[3:19]))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &NameEvent{
|
|
DevType: DeviceType(bytes[0]),
|
|
DevNumber: bytes[1],
|
|
DevTypeFunction: bytes[2],
|
|
DevName: strings.TrimSpace(name),
|
|
}, nil
|
|
}
|
|
|
|
type getNameResult struct {
|
|
ev *NameEvent
|
|
err error
|
|
}
|
|
|
|
func (s *Satel) GetName(devType DeviceType, devIndex byte) (*NameEvent, error) {
|
|
resultChan := make(chan getNameResult)
|
|
|
|
s.commandQueue <- func() {
|
|
err := s.sendCmd(SatelCommand_ReadDeviceName, byte(devType), devIndex)
|
|
if err != nil {
|
|
resultChan <- getNameResult{nil, errors.New("Could not send Satel read device name")}
|
|
return
|
|
}
|
|
|
|
var bytes = <-s.rawEvents
|
|
if len(bytes) < (1 + 2) {
|
|
resultChan <- getNameResult{nil, errors.New(fmt.Sprint("Received data too short to get name: ", hex.Dump(bytes)))}
|
|
return
|
|
}
|
|
cmd := bytes[0]
|
|
bytes = bytes[1 : len(bytes)-2]
|
|
if cmd == Satel_Result {
|
|
resultChan <- getNameResult{nil, errors.New(fmt.Sprint("Received an error instead of a name: ", hex.Dump(bytes)))}
|
|
} else if cmd == SatelCommand_ReadDeviceName {
|
|
name, err := makeNameEvent(bytes)
|
|
resultChan <- getNameResult{name, err}
|
|
} else {
|
|
resultChan <- getNameResult{nil, errors.New(fmt.Sprint("Received unexpected reply: ", hex.Dump(bytes)))}
|
|
}
|
|
}
|
|
nameResult := <-resultChan
|
|
return nameResult.ev, nameResult.err
|
|
}
|