Device name from SATEL with error checking

main
Michał Rudowicz 2024-03-04 20:24:13 +01:00
rodzic fcbf3bd29f
commit d8d20e35e5
3 zmienionych plików z 51 dodań i 44 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
package satel
import (
"errors"
"strings"
"golang.org/x/text/encoding/charmap"
@ -30,16 +31,52 @@ type NameEvent struct {
DevName string
}
func makeNameEvent(bytes []byte) NameEvent {
func makeNameEvent(bytes []byte) (*NameEvent, error) {
if len(bytes) < 19 {
return nil, errors.New("Received data too short")
}
cp1250dec := charmap.Windows1250.NewDecoder()
name, err := cp1250dec.String(string(bytes[3:19]))
if err != nil {
name = "CP1250 DECODE ERROR"
return nil, err
}
return NameEvent{
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(0xEE, byte(devType), devIndex)
if err != nil {
resultChan <- getNameResult{nil, errors.New("Could not send Satel read device name")}
}
var bytes = <-s.rawEvents
if len(bytes) < (1 + 19 + 2) {
resultChan <- getNameResult{nil, errors.New("Received data too short")}
}
cmd := bytes[0]
bytes = bytes[1 : len(bytes)-2]
if cmd == 0xEF {
resultChan <- getNameResult{nil, errors.New("Did not receive a name")}
} else if cmd == 0xEE {
name, err := makeNameEvent(bytes)
resultChan <- getNameResult{name, err}
} else {
resultChan <- getNameResult{nil, errors.New("Received unexpected result instead of a name")}
}
}
nameResult := <-resultChan
return nameResult.ev, nameResult.err
}

Wyświetl plik

@ -7,10 +7,19 @@ import (
func TestMakeNameEvent(t *testing.T) {
assert := assert.New(t)
name, err := makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0xFF})
assert.Equal(NameEvent{
DevType: DeviceType(1),
DevNumber: 2,
DevTypeFunction: 3,
DevName: "0123456789ABCDEF",
}, makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0xFF}))
}, *name)
assert.NoError(err)
}
func TestMakeNameEvent_tooShort(t *testing.T) {
assert := assert.New(t)
name, err := makeNameEvent([]byte{01, 02, 03, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
assert.Nil(name)
assert.Error(err)
}

Wyświetl plik

@ -3,7 +3,6 @@ package satel
import (
"bufio"
"errors"
"fmt"
"net"
"sync"
"time"
@ -105,44 +104,6 @@ func (s *Satel) SetOutput(code string, index int, value bool) error {
return s.sendCmd(bytes...)
}
func (s *Satel) GetName(devType DeviceType, devIndex byte) NameEvent {
resultChan := make(chan NameEvent)
s.commandQueue <- func() {
err := s.sendCmd(0xEE, byte(devType), devIndex)
if err != nil {
resultChan <- NameEvent{
DevType: DeviceType(devType),
DevNumber: devIndex,
DevTypeFunction: 0,
DevName: fmt.Sprint("ERROR RETRIEVING NAME ", devType, devIndex),
}
}
var bytes = <-s.rawEvents
cmd := bytes[0]
bytes = bytes[1 : len(bytes)-2]
if cmd == 0xEF {
resultChan <- NameEvent{
DevType: DeviceType(devType),
DevNumber: devIndex,
DevTypeFunction: 0,
DevName: fmt.Sprint("NO NAME ", devType, devIndex),
}
} else if cmd == 0xEE {
resultChan <- makeNameEvent(bytes)
} else {
resultChan <- NameEvent{
DevType: DeviceType(devType),
DevNumber: devIndex,
DevTypeFunction: 0,
DevName: fmt.Sprint("ERROR GETTING NAME ", devType, devIndex),
}
}
}
return <-resultChan
}
func prepareCommand(code string, cmd byte, data ...byte) []byte {
bytes := append([]byte{cmd}, transformCode(code)...)
return append(bytes, data...)