dbus-mqtt-devices icon indicating copy to clipboard operation
dbus-mqtt-devices copied to clipboard

Request for support com.victronenergy.battery

Open xury77 opened this issue 1 year ago • 4 comments

Is it possible to add support for com.victronenergy.battery? I have a DIY BMS that can send MQTT messages with cell value and alarms. Alternatively, would it be possible to put some messages from my BMS into Lynx shunt? I mean something similar to https://github.com/Louisvdw/dbus-serialbattery but via mqtt. More precisely https://github.com/Louisvdw/dbus-serialbattery/blob/master/etc/dbus-serialbattery/dbushelper.py

xury77 avatar Nov 03 '22 11:11 xury77

Hi, thanks for the suggestion. Looking at https://github.com/Louisvdw/dbus-serialbattery/blob/bd20bd57052023f6a88ac4bb7e5ea0bf09bb9464/etc/dbus-serialbattery/dbushelper.py, it should be possible to replicate the same dbus paths. I don't have access to a suitable battery system to test against, so would need to write a simple simulator. Do you have an example of an MQTT enabled battery?

freakent avatar Nov 03 '22 23:11 freakent

Hi freakent. Thank You for your interest. Currently I was able to add these temperature values thanks to your design. As I said, my "bms" is my own poor design. As I'm not a good software developer. Very basic. Sample object from my construction: I think is most important is cell voltage data and alarms. {"BatteryID":"40:F5:20:8A:0E:B0", "Time":1667547573, "Version":205, "Flags":208, "Temperatura1":124, "Temperatura2":116, "Current":10, "CellV_01":316, "CellV_02":320, "CellV_03":322, "CellV_04":321, "CellV_05":321, "CellV_06":321, "CellV_07":320, "CellV_08":323, "CellV_09":322, "CellV_10":323, "CellV_11":319, "CellV_12":322, "CellV_13":324, "CellV_14":320, "CellV_15":322, "CellV_16":324, "Obudowa":false, "cellnum":16, "BMS_charge":true, "BMS_dicharge":true, "BMS_Vcell_min":false, "BMS_Vcell_max":false, "BMS_T_min":false, "BMS_T_max":false, "BMS_I_chg_max":false, "BMS_I_dchg_max":false, "BMS_V_batt_min":false, "BMS_V_bat_max":false}

Where:

Temperatura is temperature in Celsius /10 Current is current A/1000 CellV_ is cell voltage /10 BMS_charge - allow to charge true/false BMS_dicharge - allow to discharge true/false BMS_Vcell_min - alarm cell voltage below minimum value BMS_Vcell_max - alarm cell voltage above maximum value BMS_T_min - alarm battery temperature is below minimum value BMS_T_max - alarm battery temperature is over maximum value BMS_I_chg_max - alarm battery charge current is above max value BMS_I_dchg_max - alarm battery discharge current is above maximum value BMS_V_batt_min - alarm battery voltage is below minimum value BMS_V_bat_max - alarm battery voltage is above maximum value For me, it was enough to view these values in cerbo gui and react to alarms.

xury77 avatar Nov 04 '22 09:11 xury77

This looks like a good start. So I assume you have added these battery fields to the ~~settings.yml~~ services.yml file? If so can you provide a copy for me to review? Any other modifications you have had to make?

freakent avatar Nov 05 '22 09:11 freakent

If you could just tell me how to start the services.yml file? For example, some of the first basic lines. I think that I would be able to do it already. I just don't know how to start :) I don't fully understand dbus.

xury77 avatar Nov 08 '22 15:11 xury77

Each section in the services.yml file is for a different service, so you want to start a new section something like this:

# https://github.com/victronenergy/venus/wiki/dbus#battery
battery:
  ProductId:
    default: 45069 # 0xB00D, ESS Demo mode uses 45058
  CustomName:
    default: "My Battery"
    persist: true

What comes next needs some investigation. If you look at https://github.com/victronenergy/venus/wiki/dbus#battery, all the dbus paths are listed and explained. You can also see many of the same dbus paths in the serial driver https://github.com/Louisvdw/dbus-serialbattery/blob/bd20bd57052023f6a88ac4bb7e5ea0bf09bb9464/etc/dbus-serialbattery/dbushelper.py.

In the next release of the mqqt driver I am going move from one big services yaml files to separate json files in a services folder. My ccgx completely reset when I tried to add the python yaml parser, so I think JSON will be safer.

freakent avatar Nov 08 '22 20:11 freakent

I trying as you mentioned. Am I going in the right direction?

# https://github.com/victronenergy/venus/wiki/dbus#battery
battery:
  ProductId:
    default: 45069 # 0xB00D, ESS Demo mode uses 45058
  CustomName:
    default: "My Battery"
    persist: true
  Dc/0/Voltage:
    description: "V"
    format: "{} V"
  Dc/0/Current:
    description: "A"
    format: "{} A"
  Dc/0/Temperature:
    description: "C"
  Info/BatteryLowVoltage:
    description: "V"
  Info/BatteryLowVoltage:
    description: "V"
  Info/MaxChargeVoltage:
    description: "V"
  Info/MaxChargeCurrent:
    description: "A"
  Info/MaxDischargeCurrent:
    description: "A"
  System/MaxCellVoltage:
    description: "V"
    format: "{} V"
  System/MinCellVoltage:
    description: "V"
    format: "{} V"
  Io/AllowToCharge: # I don't know how to set true false for it
  Io/AllowToDischarge:
  Alarms/LowVoltage:
  Alarms/HighVoltage:
  Alarms/LowCellVoltage:
  Alarms/HighCellVoltage:
  Alarms/HighChargeCurrent:
  Alarms/HighDischargeCurrent:
  Alarms/HighTemperature:
  Alarms/LowTemperature:
  Cell/1/Volts:
    description: "V"
    format: "{} V"
  Cell/2/Volts:
    description: "V"
    format: "{} V"
  Cell/3/Volts:
    description: "V"
    format: "{} V"
  Cell/4/Volts:
    description: "V"
    format: "{} V"
  Cell/5/Volts:
    description: "V"
    format: "{} V"    
  Cell/6/Volts:
    description: "V"
    format: "{} V"
  Cell/7/Volts:
    description: "V"
    format: "{} V"
  Cell/8/Volts:
    description: "V"
    format: "{} V"
  Cell/9/Volts:
    description: "V"
    format: "{} V"
  Cell/10/Volts:
    description: "V"
    format: "{} V"
  Cell/11/Volts:
    description: "V"
    format: "{} V"
  Cell/12/Volts:
    description: "V"
    format: "{} V"
  Cell/13/Volts:
    description: "V"
    format: "{} V"
  Cell/14/Volts:
    description: "V"
    format: "{} V"
  Cell/15/Volts:
    description: "V"
    format: "{} V"
  Cell/16/Volts:
    description: "V"
    format: "{} V"

xury77 avatar Nov 09 '22 09:11 xury77

It looks like you are going in the right direction. My advice would be to create a minimal set of parameters first then add to it if the simpler set are working ok.

looking at louisvdw's code:

      self._dbusservice.add_path('/Dc/0/Voltage', None, writeable=True, gettextcallback=lambda p, v: "{:2.2f}V".format(v))
        self._dbusservice.add_path('/Dc/0/Current', None, writeable=True, gettextcallback=lambda p, v: "{:2.2f}A".format(v))
        self._dbusservice.add_path('/Dc/0/Power', None, writeable=True, gettextcallback=lambda p, v: "{:0.0f}W".format(v))
        self._dbusservice.add_path('/Dc/0/Temperature', None, writeable=True)
        self._dbusservice.add_path('/Dc/0/MidVoltage', None, writeable=True,
                                   gettextcallback=lambda p, v: "{:0.2f}V".format(v))
        self._dbusservice.add_path('/Dc/0/MidVoltageDeviation', None, writeable=True,
                                   gettextcallback=lambda p, v: "{:0.1f}%".format(v))

You need to use different formats for the Dc/*/Voltage,Current,Power etc, for example {:2.2f}V, {:2.2f}A, {:0.0f}W

for Io/AllowToCharge and Io/AllowToDischarge, I would try:

Io/AllowToCharge
    default: 0
Io/AllowToDischarge
    default: 0

Having to create a new parameter cell for each cell number is not ideal, that's not a scenario I thought of when defining this, maybe an enhancement for the future. For the dbus to work you may also need to match the /System/NrOfCellsPerBattery parameter to the maximum number of cell numbers too.

freakent avatar Nov 09 '22 11:11 freakent

Very thanks for explanation. I've fixed settings.yaml One more question(s): ( I hope last one ) If I have for example Dc/0/Voltage already - is my Lynx shunt I think is should be registered to another number like DC/1/Voltage ? Or is possible to overwrite these data? Most important I would like to see first in vrm and GX console is cell max voltage and cell min voltage. These values can be computed from my data on the fly. So first of all I have to register it using proper MQTT topic like: { "clientId": "fe012", "connected": 1, "version": "v0.1preAlpha", "services": {"vbat1": "Dc/1/Voltage", "cellnr": "System/NrOfCellsPerBattery", "max_cell_V": "System/MaxCellVoltage", "min_cell_V": "System/MinCellVoltage", "Alarm_min_cell_V": "Alarms/LowCellVoltage" "Alarm_max_cell_V": "Alarms/HighCellVoltage" } } Can some services be omitted?

xury77 avatar Nov 09 '22 13:11 xury77

I think you misunderstand the registration protocol. The "services" object is a collection of chosen names and service names. The service name is the name in the services.yml file. So in your case, I would expect something like : { "clientId": "fe012", "connected": 1, "version": "v0.1preAlpha", "services": {"<a name of your choice>", "battery"} }

This line says : I wish to register a device named fe012, the device has 1 service named <name of your choice> which uses the battery settings.

by the way "fexxx" is just a name I made up based on my domain name FreakEnt (F.E.). You can use what ever names you like. Just be careful with special characters.

freakent avatar Nov 09 '22 14:11 freakent

I just realised, I incorrectly called the configuration file settings.yml instead of services.yml, I have corrected my replies in case anyone reading this later is confused.

freakent avatar Nov 09 '22 14:11 freakent

Ok I just started understanding dbus path structure. I tried as you suggested register it using Nodered to send a message like that:

msg.topic = "device/fe012/Status";
msg.payload = { "clientId": "fe012", "connected": 1 , "version": "v0.1preAlpha", "services": {"gtfenergy": "battery"} };
return msg;

Unfortunately device not appeared. I think then I have to set battery instance, but I don't know how.

xury77 avatar Nov 10 '22 14:11 xury77

For me that looks good. I'm registering my inverter from node-red like this:

msg.topic = 'device/solaxx1mini/Status'; msg.payload = {"clientId":"solaxx1mini", "connected":1, "version":"v1.0", "services":{ "pv2":"pvinverter"} }; node.send(msg);

fibrinogen avatar Nov 10 '22 14:11 fibrinogen

You have to install the driver and make sure it is running. It is the driver that receives the status messages and registers your device on the dbus for you.  Regards, Martin

freakent avatar Nov 10 '22 14:11 freakent

Im sure driver is loaded because before trying with battery I've done dwo devices with temperature.: temperaturki Do I have to install the driver again after editing services.yml? Or reboot GX device only?

xury77 avatar Nov 10 '22 17:11 xury77

No need to re-install or restart.

Check the log file and the troubleshooting instructions in the readme.

more /var/log/dbus-mqtt-devices/current

freakent avatar Nov 10 '22 18:11 freakent