-
Notifications
You must be signed in to change notification settings - Fork 1
/
device.go
136 lines (110 loc) · 2.43 KB
/
device.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
Package gorfxtrx is a library for the RFXcom RFXtrx433 USB transceiver.
http://www.rfxcom.com/store/Transceivers/12103
Supported transmitter / receivers:
- Oregon weather devices (THGR810, WTGR800, THN132N, PCR800, etc.)
- X10 RF devices (Domia Lite, HE403, etc.)
- HomeEasy devices (HE300, HE301, HE303, HE305, etc.)
RFXcom devices tested:
- RFXcom RFXtrx433 USB Transceiver
Example usage:
import (
"fmt"
"github.com/barnybug/gorfxtrx"
)
func main() {
dev, err := gorfxtrx.Open("/dev/serial/by-id/usb-RFXCOM-...", true)
if err != nil {
panic("Error opening device")
}
for {
packet, err := dev.Read()
if err != nil {
continue
}
fmt.Println("Received", packet)
}
dev.Close()
}
*/
package gorfxtrx
import (
"io"
"log"
"time"
"github.com/tarm/serial"
)
// Device representing the serial connection to the USB device.
type Device struct {
ser io.ReadWriteCloser
debug bool
}
// Open the device at the given path.
func Open(path string, debug bool) (*Device, error) {
dev := Device{debug: debug}
c := &serial.Config{Name: path, Baud: 38400}
ser, err := serial.OpenPort(c)
if err != nil {
return nil, err
}
if debug {
dev.ser = LogReadWriteCloser{ser}
} else {
dev.ser = ser
}
log.Println("Sending reset")
reset, _ := NewReset()
err = dev.Send(reset)
if err != nil {
return nil, err
}
return &dev, nil
}
// Close the device.
func (self *Device) Close() {
self.ser.Close()
}
// Read a packet from the device. Blocks until data is available.
func (self *Device) Read() (Packet, error) {
buf := make([]byte, 257)
for {
// read length
i, err := self.ser.Read(buf[0:1])
if i == 0 && err == io.EOF {
// empty read, sleep a bit recheck
time.Sleep(time.Millisecond * 200)
continue
}
if err != nil {
return nil, err
}
if i == 0 {
continue
}
// read rest of data
l := int(buf[0])
buf = buf[0 : l+1]
for read := 0; read < l; read += i {
i, err = self.ser.Read(buf[read+1:])
if i == 0 && err == io.EOF {
time.Sleep(time.Millisecond * 200)
continue
}
if err != nil {
return nil, err
}
}
// parse packet
packet, err := Parse(buf)
if self.debug {
log.Printf("Parse(%#v) = (%#v, %v)\n", buf, packet, err)
}
return packet, err
}
}
// Send (transmit) a packet.
func (self *Device) Send(p OutPacket) error {
buf := p.Send()
_, err := self.ser.Write(buf)
return err
}