diff --git a/README.md b/README.md index 2be263d3..bb4a6dce 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,7 @@ manuals for definitive guidance): | Meter | Phases | Voltage | Current | Power | Power Factor | Total Import | Total Export | Per-phase Import/Export | Line/Neutral THD | |---|---|---|---|---|---|---|---|---|---| +| SDM54 | 3 | + | + | + | + | + | + | + | + | | SDM72 | 3 | - | - | + | - | + | + | - | - | | SDM120/220 | 1 | + | + | + | + | + | + | - | - | | SDM530 | 3 | + | + | + | + | + | + | - | - | @@ -255,6 +256,7 @@ manuals for definitive guidance): | ORNO WE-516/517 | 3 | + | + | + | + | + | + | + | - | | iEM3000 Series | 3 | + | + | + | + | + | + | (+) | + | +- **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. - **SDM120**: Cheap and small (1TE), but communication parameters can only be set over MODBUS, which is currently not supported by this project. You can use e.g. [SDM120C](https://github.com/gianfrdp/SDM120C) to change parameters. diff --git a/docs/mbmd_inspect.md b/docs/mbmd_inspect.md index ea11c28a..c5862159 100644 --- a/docs/mbmd_inspect.md +++ b/docs/mbmd_inspect.md @@ -37,6 +37,7 @@ mbmd inspect [flags] SDM Eastron SDM630 SDM220 Eastron SDM220 SDM230 Eastron SDM230 + SDM54 Eastron SDM54 SDM72 Eastron SDM72 SEMTR SolarEdge SE-MTR-3Y X961A Eastron SMART X96-1A diff --git a/docs/mbmd_run.md b/docs/mbmd_run.md index 94c04bfc..f02d54c6 100644 --- a/docs/mbmd_run.md +++ b/docs/mbmd_run.md @@ -32,6 +32,7 @@ mbmd run [flags] SDM Eastron SDM630 SDM220 Eastron SDM220 SDM230 Eastron SDM230 + SDM54 Eastron SDM54 SDM72 Eastron SDM72 SEMTR SolarEdge SE-MTR-3Y X961A Eastron SMART X96-1A diff --git a/meters/rs485/sdm54.go b/meters/rs485/sdm54.go new file mode 100644 index 00000000..34e73fa4 --- /dev/null +++ b/meters/rs485/sdm54.go @@ -0,0 +1,90 @@ +package rs485 + +import . "github.com/volkszaehler/mbmd/meters" + +func init() { + Register("SDM54", NewSDM54Producer) +} + +type SDM54Producer struct { + Opcodes +} + +func NewSDM54Producer() Producer { + /** + * Opcodes as defined by Eastron SDM54. + * See https://www.eastrongroup.com/eastrongroup/2024/08/21/eastronsdm54seriesusermanualv1.2.pdf + * This is to a large extent a superset of all SDM devices, however there are + * subtle differences (see 220, 230). Some opcodes might not work on some devices. + */ + ops := Opcodes{ + VoltageL1: 0x0000, // 220, 230 + VoltageL2: 0x0002, + VoltageL3: 0x0004, + CurrentL1: 0x0006, // 220, 230 + CurrentL2: 0x0008, + CurrentL3: 0x000A, + PowerL1: 0x000C, // 230 + PowerL2: 0x000E, + PowerL3: 0x0010, + ApparentPowerL1: 0x0012, + ApparentPowerL2: 0x0014, + ApparentPowerL3: 0x0016, + ReactivePowerL1: 0x0018, + ReactivePowerL2: 0x001A, + ReactivePowerL3: 0x001C, + CosphiL1: 0x001e, // 230 + CosphiL2: 0x0020, + CosphiL3: 0x0022, + Power: 0x0034, + ApparentPower: 0x0038, + ReactivePower: 0x003C, + ImportPower: 0x0054, + ImportL1: 0x015a, + ImportL2: 0x015c, + ImportL3: 0x015e, + Import: 0x0048, // 220, 230 + ExportL1: 0x0160, + ExportL2: 0x0162, + ExportL3: 0x0164, + Export: 0x004a, // 220, 230 + SumL1: 0x0166, + SumL2: 0x0168, + SumL3: 0x016a, + Sum: 0x0156, // 220 + Cosphi: 0x003e, + THDL1: 0x00ea, // voltage + THDL2: 0x00ec, // voltage + THDL3: 0x00ee, // voltage + THD: 0x00F8, // voltage + Frequency: 0x0046, // 230 + } + return &SDM54Producer{Opcodes: ops} +} + +func (p *SDM54Producer) Description() string { + return "Eastron SDM54" +} + +func (p *SDM54Producer) snip(iec Measurement) Operation { + operation := Operation{ + FuncCode: ReadInputReg, + OpCode: p.Opcode(iec), + ReadLen: 2, + IEC61850: iec, + Transform: RTUIeee754ToFloat64, + } + return operation +} + +func (p *SDM54Producer) Probe() Operation { + return p.snip(VoltageL1) +} + +func (p *SDM54Producer) Produce() (res []Operation) { + for op := range p.Opcodes { + res = append(res, p.snip(op)) + } + + return res +}