1
0
Fork 0

Device name from SATEL with error checking

This commit is contained in:
Michał Rudowicz 2024-03-04 20:24:13 +01:00
parent fcbf3bd29f
commit d8d20e35e5
3 changed files with 51 additions and 44 deletions

View File

@ -1,6 +1,7 @@
package satel package satel
import ( import (
"errors"
"strings" "strings"
"golang.org/x/text/encoding/charmap" "golang.org/x/text/encoding/charmap"
@ -30,16 +31,52 @@ type NameEvent struct {
DevName string 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() cp1250dec := charmap.Windows1250.NewDecoder()
name, err := cp1250dec.String(string(bytes[3:19])) name, err := cp1250dec.String(string(bytes[3:19]))
if err != nil { if err != nil {
name = "CP1250 DECODE ERROR" return nil, err
} }
return NameEvent{ return &NameEvent{
DevType: DeviceType(bytes[0]), DevType: DeviceType(bytes[0]),
DevNumber: bytes[1], DevNumber: bytes[1],
DevTypeFunction: bytes[2], DevTypeFunction: bytes[2],
DevName: strings.TrimSpace(name), 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
}

View File

@ -7,10 +7,19 @@ import (
func TestMakeNameEvent(t *testing.T) { func TestMakeNameEvent(t *testing.T) {
assert := assert.New(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{ assert.Equal(NameEvent{
DevType: DeviceType(1), DevType: DeviceType(1),
DevNumber: 2, DevNumber: 2,
DevTypeFunction: 3, DevTypeFunction: 3,
DevName: "0123456789ABCDEF", 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)
} }

View File

@ -3,7 +3,6 @@ package satel
import ( import (
"bufio" "bufio"
"errors" "errors"
"fmt"
"net" "net"
"sync" "sync"
"time" "time"
@ -105,44 +104,6 @@ func (s *Satel) SetOutput(code string, index int, value bool) error {
return s.sendCmd(bytes...) 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 { func prepareCommand(code string, cmd byte, data ...byte) []byte {
bytes := append([]byte{cmd}, transformCode(code)...) bytes := append([]byte{cmd}, transformCode(code)...)
return append(bytes, data...) return append(bytes, data...)