Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Carlo Gavazzi EM500 #304

Open
andig opened this issue Feb 14, 2023 · 2 comments
Open

Add Carlo Gavazzi EM500 #304

andig opened this issue Feb 14, 2023 · 2 comments
Labels
help wanted Extra attention is needed

Comments

@andig
Copy link
Contributor

andig commented Feb 14, 2023

No description provided.

@andig andig added the help wanted Extra attention is needed label Feb 14, 2023
@lsbbs
Copy link

lsbbs commented Apr 28, 2024

Quick and dirty modified from mbmd/meters/rs485/carlogavazzi-ex3x0.go for the most important values.
A complete list of Modbus register is available at https://gavazzi.se/app/uploads/2022/03/em500-cp-v1r3-eng.pdf

package rs485

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

func init() {
        Register("CGEM500", NewCarloGavazziEM500Producer)
}

type CarloGavazziEM500Producer struct {
        Opcodes
}

func NewCarloGavazziEM500Producer() Producer {
        
        ops := Opcodes{
                VoltageL1: 0x00,
                VoltageL2: 0x02,
                VoltageL3: 0x04,
                Voltage: 0x24,
                CurrentL1: 0x0C,
                CurrentL2: 0x0E,
                CurrentL3: 0x10,
                PowerL1:   0x12,
                PowerL2:   0x14,
                PowerL3:   0x16,
                ApparentPowerL1:     0x18,
                ApparentPowerL2:     0x1A,
                ApparentPowerL3:     0x1C,
                ReactivePowerL1:     0x1E,
                ReactivePowerL2:     0x20,
                ReactivePowerL3:     0x22,
                Power:     0x28,
                ApparentPower:        0x2A,
                ReactivePower:        0x2C,
                CosphiL1:  0x2C,
                CosphiL2:  0x2E,
                CosphiL3:  0x2F,
                Cosphi:    0x31,
                Frequency: 0x33,
                Import:    0x34,
                ImportL1:  0x40,
                ImportL2:  0x42,
                ImportL3:  0x44,
                Export:    0x4E,
        }
        return &CarloGavazziEM500Producer{Opcodes: ops}
}
// Description implements Producer interface
func (p *CarloGavazziEM500Producer) Description() string {
        return "Carlo Gavazzi EM 530/540"
}

func (p *CarloGavazziEM500Producer) snip16(iec Measurement, scaler ...float64) Operation {
        transform := RTUInt16ToFloat64 // default conversion
        if len(scaler) > 0 {
                transform = MakeScaledTransform(transform, scaler[0])
        }

        operation := Operation{
                FuncCode:  ReadInputReg,
                OpCode:    p.Opcode(iec),
                ReadLen:   1,
                IEC61850:  iec,
                Transform: transform,
        }
        return operation
}

func (p *CarloGavazziEM500Producer) snip32(iec Measurement, scaler ...float64) Operation {
        transform := RTUInt32ToFloat64Swapped // default conversion
        if len(scaler) > 0 {
                transform = MakeScaledTransform(transform, scaler[0])
        }

        operation := Operation{
                FuncCode:  ReadInputReg,
                OpCode:    p.Opcode(iec),
                ReadLen:   2,
                IEC61850:  iec,
                Transform: transform,
        }
        return operation
}

// Probe implements Producer interface
func (p *CarloGavazziEM500Producer) Probe() Operation {
        return p.snip32(VoltageL1, 10)
}

// Produce implements Producer interface
func (p *CarloGavazziEM500Producer) Produce() (res []Operation) {
        for _, op := range []Measurement{
                VoltageL1, VoltageL2, VoltageL3,
                Voltage,
        } {
                res = append(res, p.snip32(op, 10))
        }

        for _, op := range []Measurement{
                CurrentL1, CurrentL2, CurrentL3,
        } {
                res = append(res, p.snip32(op, 1000))
        }

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

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

        for _, op := range []Measurement{
                Power, PowerL1, PowerL2, PowerL3,
        } {
                res = append(res, p.snip32(op, 10))
        }

        for _, op := range []Measurement{
                Import, ImportL1, ImportL2, ImportL3,
                Export,
        } {
                res = append(res, p.snip32(op, 10))
        }
        
        for _, op := range[]Measurement{
                ApparentPowerL1, ApparentPowerL2, ApparentPowerL3,
                ReactivePowerL1, ReactivePowerL2, ReactivePowerL3,
                ApparentPower, ReactivePower,
        } {
                res = append(res, p.snip32(op, 10))
        }
        
        return res
}

Save it as mbmd/meters/rs485/carlogavazzi-em500.go and compile mbmd new.
Configuration somehow like this in mbmd.yaml:

- name: cg
  type: cgem500
  id: 2
  adapter: /dev/ttySC1

@andig
Copy link
Contributor Author

andig commented Apr 28, 2024

Happy to take a pr 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants