Skip to content

Commit 29539e2

Browse files
authored
Add B+G e-tech WS100 (#353)
1 parent d50c56a commit 29539e2

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ manuals for definitive guidance):
255255
| ORNO WE-504/514/515 | 1 | + | + | + | + | + | - | - | - |
256256
| ORNO WE-516/517 | 3 | + | + | + | + | + | + | + | - |
257257
| iEM3000 Series | 3 | + | + | + | + | + | + | (+) | + |
258+
| B+G e-tech WS100 | 1 | + | + | + | - | + | + | - | - |
258259

259260
- **SDM54**: Compact (3TE), 3P meter with a lot of features. Can be configured using the builtin display.
260261
- **SDM72**: Compact (4TE), 3P meter with bare minium of total measurements, no currents. Can be configured using the builtin display.
@@ -290,6 +291,7 @@ WE-515 has a lithium battery and multi-tariff support, WE-514 does not support t
290291
By default, the meter communicates using 9600 8E1. The meter ID is 1. Meter ID, bus speed and other parameters are configurable via [Software(Windows only)](https://www.partner.orno.pl/grafiki2/PC%20softwre170621.rar)
291292
WE-517 has a lithium battery and multi-tariff support, WE-516 does not support tariff zones.
292293
- **Schneider Electric iEM3000 Series**: Professional meter with loads of configurable max/average measurements with timestamp functionality.
294+
- **B+G e-tech WS100**: Cheap and small (1TE), 1P MID meter.
293295

294296
## Modbus TCP Grid Inverters
295297

docs/mbmd_inspect.md

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ mbmd inspect [flags]
4040
SDM54 Eastron SDM54
4141
SDM72 Eastron SDM72
4242
SEMTR SolarEdge SE-MTR-3Y
43+
WS100 B+G e-tech WS100
4344
X961A Eastron SMART X96-1A
4445
TCP
4546
SUNS Sunspec-compatible MODBUS TCP device (SMA, SolarEdge, KOSTAL, etc)

docs/mbmd_run.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mbmd run [flags]
3535
SDM54 Eastron SDM54
3636
SDM72 Eastron SDM72
3737
SEMTR SolarEdge SE-MTR-3Y
38+
WS100 B+G e-tech WS100
3839
X961A Eastron SMART X96-1A
3940
TCP
4041
SUNS Sunspec-compatible MODBUS TCP device (SMA, SolarEdge, KOSTAL, etc)

meters/rs485/ws100.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package rs485
2+
3+
import . "github.com/volkszaehler/mbmd/meters"
4+
5+
func init() {
6+
Register("WS100", NewWS100Producer)
7+
}
8+
9+
type WS100Producer struct {
10+
Opcodes
11+
}
12+
13+
func NewWS100Producer() Producer {
14+
/**
15+
* Opcodes as defined by B+G e-tech WS100.
16+
* See https://data.stromzähler.eu/manuals/bg_ws100serie_de.pdf
17+
*/
18+
ops := Opcodes{
19+
Voltage: 0x0100,
20+
Current: 0x0102,
21+
Power: 0x0104,
22+
ApparentPower: 0x0106,
23+
ReactivePower: 0x0108,
24+
Import: 0x010e,
25+
Export: 0x0118,
26+
Sum: 0x0122,
27+
Frequency: 0x010a,
28+
Cosphi: 0x010b,
29+
}
30+
return &WS100Producer{Opcodes: ops}
31+
}
32+
33+
func (p *WS100Producer) Description() string {
34+
return "B+G e-tech WS100"
35+
}
36+
37+
func (p *WS100Producer) snip(iec Measurement, readlen uint16, sign signedness, transform RTUTransform, scaler ...float64) Operation {
38+
snip := Operation{
39+
FuncCode: ReadHoldingReg,
40+
OpCode: p.Opcodes[iec],
41+
ReadLen: readlen,
42+
Transform: transform,
43+
IEC61850: iec,
44+
}
45+
46+
if len(scaler) > 0 {
47+
snip.Transform = MakeScaledTransform(snip.Transform, scaler[0])
48+
}
49+
50+
return snip
51+
}
52+
53+
// snip16u creates modbus operation for single register
54+
func (p *WS100Producer) snip16u(iec Measurement, scaler ...float64) Operation {
55+
return p.snip(iec, 1, unsigned, RTUUint16ToFloat64, scaler...)
56+
}
57+
58+
// snip32u creates modbus operation for double register
59+
func (p *WS100Producer) snip32u(iec Measurement, scaler ...float64) Operation {
60+
return p.snip(iec, 2, unsigned, RTUUint32ToFloat64, scaler...)
61+
}
62+
63+
func (p *WS100Producer) Probe() Operation {
64+
return p.snip32u(Voltage, 1000)
65+
}
66+
67+
func (p *WS100Producer) Produce() (res []Operation) {
68+
for _, op := range []Measurement{
69+
Voltage, Current,
70+
} {
71+
res = append(res, p.snip32u(op, 1000))
72+
}
73+
74+
for _, op := range []Measurement{
75+
Power, ApparentPower, ReactivePower,
76+
} {
77+
res = append(res, p.snip32u(op, 1))
78+
}
79+
80+
for _, op := range []Measurement{
81+
Import, Export, Sum,
82+
} {
83+
res = append(res, p.snip32u(op, 100))
84+
}
85+
86+
for _, op := range []Measurement{
87+
Frequency,
88+
} {
89+
res = append(res, p.snip16u(op, 10))
90+
}
91+
92+
for _, op := range []Measurement{
93+
Cosphi,
94+
} {
95+
res = append(res, p.snip16u(op, 1000))
96+
}
97+
98+
return res
99+
}

0 commit comments

Comments
 (0)