Skip to content

Commit

Permalink
Add B+G e-tech WS100 (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrostek authored Jan 5, 2025
1 parent d50c56a commit 29539e2
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ manuals for definitive guidance):
| ORNO WE-504/514/515 | 1 | + | + | + | + | + | - | - | - |
| ORNO WE-516/517 | 3 | + | + | + | + | + | + | + | - |
| iEM3000 Series | 3 | + | + | + | + | + | + | (+) | + |
| B+G e-tech WS100 | 1 | + | + | + | - | + | + | - | - |

- **SDM54**: Compact (3TE), 3P meter with a lot of features. Can be configured using the builtin display.
- **SDM72**: Compact (4TE), 3P meter with bare minium of total measurements, no currents. Can be configured using the builtin display.
Expand Down Expand Up @@ -290,6 +291,7 @@ WE-515 has a lithium battery and multi-tariff support, WE-514 does not support t
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)
WE-517 has a lithium battery and multi-tariff support, WE-516 does not support tariff zones.
- **Schneider Electric iEM3000 Series**: Professional meter with loads of configurable max/average measurements with timestamp functionality.
- **B+G e-tech WS100**: Cheap and small (1TE), 1P MID meter.

## Modbus TCP Grid Inverters

Expand Down
1 change: 1 addition & 0 deletions docs/mbmd_inspect.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ mbmd inspect [flags]
SDM54 Eastron SDM54
SDM72 Eastron SDM72
SEMTR SolarEdge SE-MTR-3Y
WS100 B+G e-tech WS100
X961A Eastron SMART X96-1A
TCP
SUNS Sunspec-compatible MODBUS TCP device (SMA, SolarEdge, KOSTAL, etc)
Expand Down
1 change: 1 addition & 0 deletions docs/mbmd_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mbmd run [flags]
SDM54 Eastron SDM54
SDM72 Eastron SDM72
SEMTR SolarEdge SE-MTR-3Y
WS100 B+G e-tech WS100
X961A Eastron SMART X96-1A
TCP
SUNS Sunspec-compatible MODBUS TCP device (SMA, SolarEdge, KOSTAL, etc)
Expand Down
99 changes: 99 additions & 0 deletions meters/rs485/ws100.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package rs485

import . "github.com/volkszaehler/mbmd/meters"

func init() {
Register("WS100", NewWS100Producer)
}

type WS100Producer struct {
Opcodes
}

func NewWS100Producer() Producer {
/**
* Opcodes as defined by B+G e-tech WS100.
* See https://data.stromzähler.eu/manuals/bg_ws100serie_de.pdf
*/
ops := Opcodes{
Voltage: 0x0100,
Current: 0x0102,
Power: 0x0104,
ApparentPower: 0x0106,
ReactivePower: 0x0108,
Import: 0x010e,
Export: 0x0118,
Sum: 0x0122,
Frequency: 0x010a,
Cosphi: 0x010b,
}
return &WS100Producer{Opcodes: ops}
}

func (p *WS100Producer) Description() string {
return "B+G e-tech WS100"
}

func (p *WS100Producer) snip(iec Measurement, readlen uint16, sign signedness, transform RTUTransform, scaler ...float64) Operation {
snip := Operation{
FuncCode: ReadHoldingReg,
OpCode: p.Opcodes[iec],
ReadLen: readlen,
Transform: transform,
IEC61850: iec,
}

if len(scaler) > 0 {
snip.Transform = MakeScaledTransform(snip.Transform, scaler[0])
}

return snip
}

// snip16u creates modbus operation for single register
func (p *WS100Producer) snip16u(iec Measurement, scaler ...float64) Operation {
return p.snip(iec, 1, unsigned, RTUUint16ToFloat64, scaler...)
}

// snip32u creates modbus operation for double register
func (p *WS100Producer) snip32u(iec Measurement, scaler ...float64) Operation {
return p.snip(iec, 2, unsigned, RTUUint32ToFloat64, scaler...)
}

func (p *WS100Producer) Probe() Operation {
return p.snip32u(Voltage, 1000)
}

func (p *WS100Producer) Produce() (res []Operation) {
for _, op := range []Measurement{
Voltage, Current,
} {
res = append(res, p.snip32u(op, 1000))
}

for _, op := range []Measurement{
Power, ApparentPower, ReactivePower,
} {
res = append(res, p.snip32u(op, 1))
}

for _, op := range []Measurement{
Import, Export, Sum,
} {
res = append(res, p.snip32u(op, 100))
}

for _, op := range []Measurement{
Frequency,
} {
res = append(res, p.snip16u(op, 10))
}

for _, op := range []Measurement{
Cosphi,
} {
res = append(res, p.snip16u(op, 1000))
}

return res
}

0 comments on commit 29539e2

Please sign in to comment.