freakent / dbus-mqtt-devices

A driver for Victron VenusOS GX devices to support use of dbus-mqtt/flashmq-mqtt
MIT License
111 stars 24 forks source link

Request for support com.victronenergy.battery #24

Closed xury77 closed 1 year ago

xury77 commented 1 year ago

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

freakent commented 1 year ago

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?

xury77 commented 1 year ago

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.

freakent commented 1 year ago

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?

xury77 commented 1 year ago

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.

freakent commented 1 year ago

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.

xury77 commented 1 year ago

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"
freakent commented 1 year ago

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.

xury77 commented 1 year ago

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?

freakent commented 1 year ago

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 commented 1 year ago

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.

xury77 commented 1 year ago

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.

fibrinogen commented 1 year ago

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);

freakent commented 1 year ago

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

xury77 commented 1 year ago

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?

freakent commented 1 year ago

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
KaiGrassnick commented 1 year ago

@xury77 you need to add a description to each of the entries (if no other subentry exists e.g. format). Otherwise the Device is not recognized. (Maybe a bug?)

You can try my Configuration:

# https://github.com/victronenergy/venus/wiki/dbus#battery
battery:
  ProductId:
    default: 65535 # 0xFFFF
  CustomName:
    default: "My Battery"
    persist: true
  Dc/0/Voltage:
    description: "V"
    format: "{:.2f}"
  Dc/0/Current:
    description: "A"
    format: "{:.2f}"
  Dc/0/Power:
    description: "W"
    format: "{:.2f}"
  Dc/0/Temperature:
    description: "C"
  Dc/0/MidVoltage:
    description: "V"
    format: "{:.2f}"
  Dc/0/MidVoltageDeviation:
    description: "V"
    format: "{:.3f}"
  ConsumedAmphours:
    description: "Ah"
    format: "{:.0f}"
  Soc:
    description: "%"
    format: "{:.0f}"
  Capacity:
    description: "Ah"
    format: "{:.2f}"
  InstalledCapacity:
    description: "Ah"
    format: "{:.0f}"
  SystemSwitch:
    description: ""
  Balancing:
    description: ""
  Info/MaxChargeCurrent:
    description: "A"
    format: "{:.2f}"
  Info/MaxDischargeCurrent:
    description: "A"
    format: "{:.2f}"
  Info/MaxChargeVoltage:
    description: "V"
    format: "{:.2f}"
  Info/BatteryLowVoltage:
    description: "V"
    format: "{:.2f}"
#  Info/ChargeRequest:
#    description: "Request Charge if Battery is low"
  Alarms/LowVoltage:
    description: ""
  Alarms/HighVoltage:
    description: ""
#  Alarms/LowStarterVoltage:
#    description: ""
#  Alarms/HighStarterVoltage:
#    description: ""
  Alarms/LowSoc:
    description: ""
  Alarms/HighChargeCurrent:
    description: ""
  Alarms/HighDischargeCurrent:
    description: ""
  Alarms/HighCurrent:
    description: ""
  Alarms/CellImbalance:
    description: ""
#  Alarms/InternalFailure:
#    description: ""
  Alarms/HighChargeTemperature:
    description: ""
  Alarms/LowChargeTemperature:
    description: ""
  Alarms/LowCellVoltage:
    description: ""
  Alarms/LowTemperature:
    description: ""
  Alarms/HighTemperature:
    description: ""
  Alarms/MidVoltage:
    description: ""
#  Alarms/Contactor:
#    description: ""
#  Alarms/BmsCable:
#    description: ""
#  Alarms/HighInternalTemperature:
#    description: ""
#  Alarms/FuseBlown:
#    description: ""
  System/MinVoltageCellId:
    description: ""
  System/MaxVoltageCellId:
    description: ""
  System/MinCellVoltage:
    description: "V"
    format: "{:.3f}"
  System/MaxCellVoltage:
    description: "V"
    format: "{:.3f}"
  System/MinTemperatureCellId:
    description: ""
  System/MaxTemperatureCellId:
    description: ""
  System/MinCellTemperature:
    description: "°C"
  System/MaxCellTemperature:
    description: "°C"
  System/NrOfBatteries:
    description: ""
  System/BatteriesParallel:
    description: ""
  System/BatteriesSeries:
    description: ""
  System/NrOfCellsPerBattery:
    description: ""
  System/NrOfModulesBlockingCharge:
    description: ""
  System/NrOfModulesBlockingDischarge:
    description: ""
  System/NrOfModulesOnline:
    description: ""
  System/NrOfModulesOffline:
    description: ""
  Io/AllowToCharge:
    default: 0
  Io/AllowToDischarge:
    default: 0
  Io/ExternalRelay:
    description: ""
  History/ChargeCycles:
    description: ""
  History/TotalAhDrawn:
    description: "Ah"
    format: "{:.2f}"

Format is set to match dbus-serialbattery.

With the config above, all values are supposed to be numbers (float, int) not strings. So if you have 3.23V as your Value, you need to adjust the Format accordingly.

As https://github.com/Louisvdw/dbus-serialbattery/blob/d92a34a25d66fca5b4202821914b9cb230d4ac89/etc/dbus-serialbattery/utils.py#L154 states. Cell Voltage to be shown in Remote Console should be on path: Voltages/Cell1

But i couldn't find them anywhere looking through the Menu. So i removed that part.

@freakent i used this simple nodejs mqtt client to test the service: https://gist.github.com/KaiGrassnick/bb6a01d87941ad01143f42a4abb971c0

pos-ei-don commented 1 year ago

@KaiGrassnick

You can try my Configuration: KaiGrassnick

Great, thank you! I tried it and create and fill it directly within victrons-nodered ! Works great!! I hope your template finds its way in the default installation ;-)

Joe

freakent commented 1 year ago

Can this be closed now?

xury77 commented 1 year ago

Unfortunately is not work for me. Perhaps I have Lynx shunt as battery monitor already? Tried on unchanged @KaiGrassnick files (except mqtt credentials on app.js)

pos-ei-don commented 1 year ago

What exactly does not work for you? How do you send the values from the shunt to the virtual battery?