-
Notifications
You must be signed in to change notification settings - Fork 0
/
base.go
127 lines (112 loc) · 2.75 KB
/
base.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
package gohome
import (
"encoding/json"
"fmt"
"regexp"
"github.com/pkg/errors"
)
const COMMAND = "COMMAND"
const REQUEST = "REQUEST"
const SPECIAL = "SPECIAL"
const DIMENSIONGET = "DIMENSIONGET"
const DIMENSIONSET = "DIMENSIONSET"
const INVALID = "INVALID"
var ErrWhatNotFound = errors.New("WHAT not found")
var ErrWhoNotFound = errors.New("WHO not found")
var regexpCommand = regexp.MustCompile(`^\*([0-9]{1,2})\*([0-9]{1,2})\*([0-9]{1,2})##`)
var regexpRequest = regexp.MustCompile(`^\*#([0-9]{1,2})\*([0-9]{1,2})##`)
var regexpDimensionGet = regexp.MustCompile(`^\*#([0-9]{1,2})\*([0-9]{1,2})\*([0-9]{1,2})##`)
var regexpDimensionSet = regexp.MustCompile(`^\*#([0-9]{1,2})\*([0-9]{1,2})\*#([0-9]{1,2})(\*[0-9]{1,2})+##`)
type Dimension string
type Value string
type What struct {
Code string
Desc string
}
type Message struct {
Who *Who `json:"who"`
What What `json:"what"`
Where Where `json:"where"`
Kind string `json:"kind"`
special string
}
func (m Message) MarshalJSON() ([]byte, error) {
var whoD, whatD, whereD string
if m.Who != nil {
whoD = m.Who.Desc
}
if m.What != (What{}) {
whatD = m.What.Desc
}
if m.Where != (Where{}) {
whereD = m.Where.Desc
}
mj := struct {
Who string `json:"who"`
What string `json:"what"`
Where string `json:"where"`
Kind string `json:"kind"`
}{
Who: whoD,
What: whatD,
Where: whereD,
Kind: m.Kind,
}
js, err := json.Marshal(&mj)
return js, err
}
func (m Message) Frame() string {
if m.IsSpecial() {
return m.special
}
switch m.Kind {
case REQUEST:
frame := fmt.Sprintf("*#%s*%s##", m.Who.Code, m.Where.Code)
return frame
case COMMAND:
frame := fmt.Sprintf("*%s*%s*%s##", m.Who.Code, m.What.Code, m.Where.Code)
return frame
}
return ""
}
func (m Message) IsSpecial() bool {
if m.special != "" {
return true
}
return false
}
func (m Message) IsValid() bool {
if m.Kind != INVALID {
return true
}
return false
}
//NewCommand build a new Command to send to the home plant
func NewCommand(who *Who, what What, where Where) Message {
return Message{Who: who, What: what, Where: where, Kind: COMMAND}
}
//NewRequest build a new Request to send to the home plant
func NewRequest(who *Who, what What, where Where) Message {
return Message{Who: who, What: what, Where: where, Kind: REQUEST}
}
func IsValid(msg string) (bool, string) {
if len(msg) < 5 {
return false, INVALID
}
for _, m := range SystemMessages {
if msg == m.Frame() {
return true, SPECIAL
}
}
switch {
case regexpCommand.MatchString(msg):
return true, COMMAND
case regexpRequest.MatchString(msg):
return true, REQUEST
case regexpDimensionGet.MatchString(msg):
return true, DIMENSIONGET
case regexpDimensionSet.MatchString(msg):
return true, DIMENSIONSET
}
return false, INVALID
}