@@ -16,7 +16,7 @@ import (
16
16
"github.com/volkszaehler/mbmd/meters"
17
17
)
18
18
19
- type sunSpec struct {
19
+ type SunSpec struct {
20
20
models []sunspec.Model
21
21
descriptor meters.DeviceDescriptor
22
22
}
@@ -37,15 +37,15 @@ func (e partialError) Cause() error {
37
37
func (e partialError ) PartiallyInitialized () {}
38
38
39
39
// NewDevice creates a Sunspec device
40
- func NewDevice (meterType string ) meters. Device {
41
- return & sunSpec {
40
+ func NewDevice (meterType string ) * SunSpec {
41
+ return & SunSpec {
42
42
descriptor : meters.DeviceDescriptor {
43
43
Manufacturer : meterType ,
44
44
},
45
45
}
46
46
}
47
47
48
- func (d * sunSpec ) Initialize (client modbus.Client ) error {
48
+ func (d * SunSpec ) Initialize (client modbus.Client ) error {
49
49
in , err := sunspecbus .Open (client )
50
50
if err != nil && in == nil {
51
51
return err
@@ -79,7 +79,7 @@ func (d *sunSpec) Initialize(client modbus.Client) error {
79
79
return err
80
80
}
81
81
82
- func (d * sunSpec ) readCommonBlock (device sunspec.Device ) error {
82
+ func (d * SunSpec ) readCommonBlock (device sunspec.Device ) error {
83
83
// TODO catch panic
84
84
commonModel := device .MustModel (sunspec .ModelId (1 ))
85
85
// TODO catch panic
@@ -100,7 +100,7 @@ func (d *sunSpec) readCommonBlock(device sunspec.Device) error {
100
100
}
101
101
102
102
// collect and sort supported models except for common
103
- func (d * sunSpec ) collectModels (device sunspec.Device ) error {
103
+ func (d * SunSpec ) collectModels (device sunspec.Device ) error {
104
104
d .models = device .Collect (sunspec .OneOfSeveralModelIds (d .relevantModelIds ()))
105
105
if len (d .models ) == 0 {
106
106
return errors .New ("sunspec: could not find supported model" )
@@ -110,7 +110,7 @@ func (d *sunSpec) collectModels(device sunspec.Device) error {
110
110
return nil
111
111
}
112
112
113
- func (d * sunSpec ) relevantModelIds () []sunspec.ModelId {
113
+ func (d * SunSpec ) relevantModelIds () []sunspec.ModelId {
114
114
modelIds := make ([]sunspec.ModelId , 0 , len (modelMap ))
115
115
for k := range modelMap {
116
116
modelIds = append (modelIds , sunspec .ModelId (k ))
@@ -120,7 +120,7 @@ func (d *sunSpec) relevantModelIds() []sunspec.ModelId {
120
120
}
121
121
122
122
// remove model 101 if model 103 found
123
- func (d * sunSpec ) sanitizeModels () {
123
+ func (d * SunSpec ) sanitizeModels () {
124
124
m101 := - 1
125
125
for i , m := range d .models {
126
126
if m .Id () == sunspec .ModelId (101 ) {
@@ -133,12 +133,12 @@ func (d *sunSpec) sanitizeModels() {
133
133
}
134
134
}
135
135
136
- func (d * sunSpec ) Descriptor () meters.DeviceDescriptor {
136
+ func (d * SunSpec ) Descriptor () meters.DeviceDescriptor {
137
137
return d .descriptor
138
138
}
139
139
140
- func (d * sunSpec ) Probe (client modbus.Client ) (res meters.MeasurementResult , err error ) {
141
- if d .notInitilized () {
140
+ func (d * SunSpec ) Probe (client modbus.Client ) (res meters.MeasurementResult , err error ) {
141
+ if d .notInitialized () {
142
142
return res , errors .New ("sunspec: not initialized" )
143
143
}
144
144
@@ -172,12 +172,11 @@ func (d *sunSpec) Probe(client modbus.Client) (res meters.MeasurementResult, err
172
172
return res , fmt .Errorf ("sunspec: could not find model for probe snip" )
173
173
}
174
174
175
- func (d * sunSpec ) notInitilized () bool {
175
+ func (d * SunSpec ) notInitialized () bool {
176
176
return len (d .models ) == 0
177
177
}
178
178
179
- func (d * sunSpec ) convertPoint (b sunspec.Block , blockID int , pointID string , m meters.Measurement ) (meters.MeasurementResult , error ) {
180
- p := b .MustPoint (pointID )
179
+ func (d * SunSpec ) convertPoint (b sunspec.Block , p sunspec.Point , m meters.Measurement ) (meters.MeasurementResult , error ) {
181
180
v := p .ScaledValue ()
182
181
183
182
if math .IsNaN (v ) {
@@ -198,24 +197,59 @@ func (d *sunSpec) convertPoint(b sunspec.Block, blockID int, pointID string, m m
198
197
return mr , nil
199
198
}
200
199
201
- func (d * sunSpec ) Query (client modbus.Client ) (res []meters.MeasurementResult , err error ) {
202
- if d .notInitilized () {
200
+ // QueryOp executes a single query operation on the bus
201
+ func (d * SunSpec ) QueryOp (client modbus.Client , measurement meters.Measurement ) (res meters.MeasurementResult , err error ) {
202
+ if d .notInitialized () {
203
+ return res , errors .New ("sunspec: not initialized" )
204
+ }
205
+
206
+ for _ , model := range d .models {
207
+ supportedID := model .Id ()
208
+ for modelID , blockMap := range modelMap {
209
+ if modelID != supportedID {
210
+ continue
211
+ }
212
+
213
+ for blockID , pointMap := range blockMap {
214
+ for pointID , m := range pointMap {
215
+ if m == measurement {
216
+ block := model .MustBlock (blockID )
217
+ if err = block .Read (); err != nil {
218
+ return
219
+ }
220
+
221
+ point := block .MustPoint (pointID )
222
+ return d .convertPoint (block , point , m )
223
+ }
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ return meters.MeasurementResult {}, fmt .Errorf ("sunspec: %s not found" , measurement )
230
+ }
231
+
232
+ // Query is called by the handler after preparing the bus by setting the device id and waiting for rate limit
233
+ func (d * SunSpec ) Query (client modbus.Client ) (res []meters.MeasurementResult , err error ) {
234
+ if d .notInitialized () {
203
235
return res , errors .New ("sunspec: not initialized" )
204
236
}
205
237
206
238
for _ , model := range d .models {
207
239
blockID := 0
208
240
209
- model .Do (func (b sunspec.Block ) {
241
+ model .Do (func (block sunspec.Block ) {
210
242
defer func () { blockID ++ }()
211
243
212
- if err = b .Read (); err != nil {
244
+ if err = block .Read (); err != nil {
213
245
return
214
246
}
215
247
216
248
if bps , ok := modelMap [model .Id ()][blockID ]; ok {
217
249
for pointID , m := range bps {
218
- if mr , err := d .convertPoint (b , blockID , pointID , m ); err == nil {
250
+ point := block .MustPoint (pointID )
251
+
252
+ if mr , err := d .convertPoint (block , point , m ); err == nil {
219
253
res = append (res , mr )
220
254
}
221
255
}
0 commit comments