Louisvdw / dbus-serialbattery

Battery Monitor driver for serial battery in VenusOS GX systems
MIT License
525 stars 164 forks source link

Reduce the big inrush current if the CVL jumps from Bulk/Absorbtion to Float #659

Closed Rikkert-RS closed 1 year ago

Rikkert-RS commented 1 year ago

Is your feature request related to a problem? Please describe.

The problem is when a very large battery is present and a voltage drop from bulk 55.2V to 54V float voltage happens in one go. A lot of energy is suddenly discharged from the battery. This can be up to 5kw or more.

Describe the solution you'd like

My solution is in the battery.py.

To reduce the inrush current i do this in steps with the update interval to the float voltage my change is at line 275

OLD:

self.control_voltage = round(
  (utils.FLOAT_CELL_VOLTAGE * self.cell_count), 3
)
  self.charge_mode = "Float"

NEW

floatVoltage = round((utils.FLOAT_CELL_VOLTAGE * self.cell_count), 3)`
if self.control_voltage:
    if self.control_voltage >= (floatVoltage + 0.005):
        self.control_voltage -= 0.005
    else:
        self.control_voltage = floatVoltage
else:
    self.control_voltage = floatVoltage
self.charge_mode = "Float"

Describe alternatives you've considered

Maybe also something for the coinfig file

Additional context

Nice Driver. ;) i have installed Version: v1.0.20230508beta

mr-manuel commented 1 year ago

Could you please post also your diagrams from the VRM portal where we can see this behaviour before and after?

Rikkert-RS commented 1 year ago

Yes, I can do that, but the VRM portal has currently performance problems. As soon as this is running again I will send pictures.

Rikkert-RS commented 1 year ago

Here you can see that the current is not so large and also rises slowly. You can also no longer hear the inverters as they try to lower the voltage as quickly as possible.

Before: Screenshot 2023-05-23 183941

After: Screenshot 2023-05-23 183813

mr-manuel commented 1 year ago

Perfect, I will test it a few days and then add it.

Rikkert-RS commented 1 year ago

I also have an adaptation for aggregate batteries for this problem but that is probably better placed at @DR-Gigavolt . What do you mean? I used the new "Chargemodes" for that. With Aggregate Batteries the problem is that as soon as the first battery goes into float, all other batteries that are not yet balanced go into float as well.

mr-manuel commented 1 year ago

@Rikkert-RS for the aggregate batteries you have to open an issue in the related repository as you said.

@ogurevich what do you think about this code change? Do you see the same in your charts?

ogurevich commented 1 year ago

can confirm, the inrush current at the moment the battery goes in float mode is significant (in ESS mode with DC-coupled PV - Feed in excess - ON)

it make sense to reduce control voltage gently wenn going in to float. We could in addition in this time period self.charge_mode = "Float (dynamic)" the proposed code change is charming. the management function called every second, we achieve the desired effect.

it make sense imho

Dr-Gigavolt commented 1 year ago

Hello guys, ESS does not support the lead-acid algorithm at all, this works only with stand-alone MPPTs or Multis/Quattros. Why do you try to maintain it? Just reduce the CVL and balancing-start voltage in BMS in order to to extend the battery life. What is the gain of charging the battery to 100% and than discharge it into the grid? The battery does not need to be at 100% to be balanced. I tried to reduce my LTOs (although there is the battery life not a limiting factor) from 2.5V to 2.35V and it works without any troubles.

mr-manuel commented 1 year ago

@ogurevich thanks

@Dr-Gigavolt I think we already talked about this a few times. It's the flat charging curve of LFP batteries where it's better to balance at voltage where the curve is steeper.

ogurevich commented 1 year ago

What is the gain of charging the battery to 100% and than discharge it into the grid? that is a very valid question.

nevertheless, it is not wrong to make the transition to float mode smooth. The user can use the MAX_CELL_VOLTAGE and FLOAT_CELL_VOLTAGE parameters control how he wants to do that. If you set the parameters the same, you have eliminated the float mode. So everyone would be happy. (...this is a new topic for me, maybe I don't see some moments deeply enough)

Dr-Gigavolt commented 1 year ago

LTOs are even flatter. IMHO there is no difference at which voltage the balancing is performed. As there is almost no leakage current, it does not help to balance in the knee. The charge that must be transferred by balancer is always the same. When I built my batteries, I tried the initial balancing at Vmax = 2.7V, it did not help at all. Once above knee (2.5V for LTO) the balancer has no chance against peaking. I reduced to 2.5V and it was OK. And now with 2.35V is OK as well.

mr-manuel commented 1 year ago

I had huge problems, if I balanced the LFP batteries in the flat area. Two batteries were much less charged than all others. This happend multiple times with different cells. Right now I'm asking me what would be more efficient. Only balancing in the top voltage section or always? If you don't need it, just set float and max voltage to the same.

mr-manuel commented 1 year ago

This was implemented and is available tomorrow in the dev branch. It will be available also in the next version.

Rikkert-RS commented 1 year ago

Hello,

Just as feedback. Thanks for the implementation. I've been running this for a few weeks now and you can't hear anything, it runs very smoothly.

@Dr-Gigavolt , @ogurevich The goal was also not to dictate how anyone charges their battery. By this function it is only made smother. Everybody can decide for himself. Yes, feeding energy into the grid at all makes no sense at this point. In sum, not much energy is pushed into the grid but in such a short time that does not have to be. For me it is much better to balance at 55.2V (16S) than at less voltage (Lifepo4). And then to keep the battery permanently until the next discharge at 55.2V is also not good.

If someone is still interested in the changes from the "aggregate batteries" code. Then I can also share this and post it here. @mr-manuel Keeping everything together on this Issue (topic) makes sense if someone is looking for it?

What I noticed in particular and what does not work with "aggregate batteries" is that if you have for e.g. 2 battery packs installed and the first pack is ready woth balancing, the whole BattterieBank then goes into float mode even if the other pack is not yet finished with the balance process. My change waits until all battery packs are ready with balancing process.

@Dr-Gigavolt If there is also interest here I would rise an "enhancement" Issue in your repo and would share the code there.

best regards Rikkert-RS

mr-manuel commented 1 year ago

@Rikkert-RS for the aggregate batteries you have to open an issue in the related repository as you said.

You can then link the issue here by just pasting the URL of the issue.

ogurevich commented 1 year ago

What I noticed in particular and what does not work with "aggregate batteries" is that if you have for e.g. 2 battery packs installed and the first pack is ready woth balancing, the whole BattterieBank then goes into float mode even if the other pack is not yet finished with the balance process. My change waits until all battery packs are ready with balancing process.

In abstract terms, aggregator does its job correctly. As soon as one of the several battery packs (the driver) reports "I am full, please reduce the charge voltage", the aggregator forwards the signal to the DVCC logic. Control question: what is more damaging in this case, reducing the voltage, or grilling the fast pack a little longer because of "slow" batteries?

I could see this effect on myself too. For me, reducing the VOLTAGE_DROP parameter to the value 0.03 achieved the desired effect. Thanks to the aggregator (it takes the smaller value for the control), the slower battery lowers the charging voltage in system, that the faster battery does not start absorption mode yet either. The driver does exactly the job for which it is there.

Thanks guys for the driver

seidler2547 commented 1 year ago

Sorry for being late to the party. I tested this code as well, and after a few days I changed the slope from 0.005 to 0.001 and I'm more happy with that. Not sure if everybody wants it that slow. but if we go from 3.45 to 3.35, then it will be only 20 seconds (JKBMS Bluetooth only 10 seconds) but with 0.001 it will be 100 or 50 seconds.

mr-manuel commented 1 year ago

Maybe in this case it would be better not to use cycles but time. Like every minute 0.10 V.

ogurevich commented 1 year ago

or even duration of the transition phase as parameter ?

mr-manuel commented 1 year ago

Can you specify this better?

ogurevich commented 1 year ago
# Duration in seconds for smooth voltage drop from absorption to float 
TRANSITION_TIME_INTO_FLOAT_MODE_VOLTAGE_LEVEL = 180
mr-manuel commented 1 year ago

I would not let the user decide this. This makes the driver unnecessary complex. Better, if we discuss a reasonable V/time for this.

ogurevich commented 1 year ago

makes sense, a constant 👍

Dr-Gigavolt commented 1 year ago

What I noticed in particular and what does not work with "aggregate batteries" is that if you have for e.g. 2 battery packs installed and the first pack is ready woth balancing, the whole BattterieBank then goes into float mode even if the other pack is not yet finished with the balance process. My change waits until all battery packs are ready with balancing process.

In abstract terms, aggregator does its job correctly. As soon as one of the several battery packs (the driver) reports "I am full, please reduce the charge voltage", the aggregator forwards the signal to the DVCC logic. Control question: what is more damaging in this case, reducing the voltage, or grilling the fast pack a little longer because of "slow" batteries?

This is exactly what I wanted to do.

Another question: why do we need an exact balancing? The only reason I see is full charging, to avoid peaking. But if the goal is 80...90% to extend battery life, who cares about few % difference?

When I'll have some time to do it, I'll try to implement an array of CVLs for each month for Aggregate Batteries. In winter full, in summer less full and e.g. once or twice per month full charging for re-balancing and reset of the SoC counter. A good trade-off between usage and life.

For LTO I found this datasheet: https://www.global.toshiba/content/dam/toshiba/ww/products-solutions/battery/scib/pdf/ToshibaRechargeableBattery-en.pdf

please look onto "long life", right chart. Do you know such a curve for LFP? Just to understand how harmful is to keep the cells fully charged over certain period of time.

Best regards, Anton

mr-manuel commented 1 year ago

Do you know such a curve for LFP? Just to understand how harmful is to keep the cells fully charged over certain period of time.

See https://github.com/Louisvdw/dbus-serialbattery/issues/458#issuecomment-1537219671

Dr-Gigavolt commented 1 year ago

Hi @mr-manuel , this one you've shared already. I mean depending on the float voltage over the time, without cycling: image

And what is even more interesting: Is the wear out in this case proportional to the total time at given voltage, or it is different if continuously or pulsed. If the first case is true, it would be more reasonable to balance for longer period of time (until Vdif falls under certain threshold), but less frequently to save some 100% charges.

Dr-Gigavolt commented 1 year ago

During experiments yesterday and today I observe something strange what I haven't seen before. The setting of CVL is slow at Multis, it is known. But the CCL does not work at all when the CVL is adjusted dynamically to avoid peaking of the most full cell. If limited to zero or few A, the charge current of several 10A continues to flow, the battery is charged more then set up and then is discharged by large current, the system oscillates. I tried to downgrade Venus 3.0 to 2.94, no change. Have you an idea?

ogurevich commented 1 year ago

During experiments yesterday and today I observe something strange what I haven't seen before. The setting of CVL is slow at Multis, it is known. But the CCL does not work at all when the CVL is adjusted dynamically to avoid peaking of the most full cell. If limited to zero or few A, the charge current of several 10A continues to flow, the battery is charged more then set up and then is discharged by large current, the system oscillates. I tried to downgrade Venus 3.0 to 2.94, no change. Have you an idea?

could it be that this is the current between different battery packs? The Multiplus, MPPTs and Venus OS would then be out of play

Dr-Gigavolt commented 1 year ago

During experiments yesterday and today I observe something strange what I haven't seen before. The setting of CVL is slow at Multis, it is known. But the CCL does not work at all when the CVL is adjusted dynamically to avoid peaking of the most full cell. If limited to zero or few A, the charge current of several 10A continues to flow, the battery is charged more then set up and then is discharged by large current, the system oscillates. I tried to downgrade Venus 3.0 to 2.94, no change. Have you an idea?

I found something, it is bad and you should consider it as well: https://community.victronenergy.com/questions/106290/bug-in-ess-dc-feed-in-enabled-charge-current-limit.html

I wrote the code in winter with few 100W from DC-coupled modules, therefore no troubles at that time. And after balancing there was no dynamic CVL change to trigger the issue. Just last days when experimenting and increasing the voltage.

Dr-Gigavolt commented 1 year ago

During experiments yesterday and today I observe something strange what I haven't seen before. The setting of CVL is slow at Multis, it is known. But the CCL does not work at all when the CVL is adjusted dynamically to avoid peaking of the most full cell. If limited to zero or few A, the charge current of several 10A continues to flow, the battery is charged more then set up and then is discharged by large current, the system oscillates. I tried to downgrade Venus 3.0 to 2.94, no change. Have you an idea?

could it be that this is the current between different battery packs? The Multiplus, MPPTs and Venus OS would then be out of play

The pack are fully identical and cells assembled in order to make identical Rin for both. http://gigavolt.eu/projects/PV2/PV2.html

Dr-Gigavolt commented 1 year ago

Hi @mr-manuel you could consider adding the following safety feature for the time of absorption and if cell peaking detected:

ogurevich commented 1 year ago

Hi @mr-manuel you could consider adding the following safety feature for the time of absorption and if cell peaking detected:

  • switch the DC-feed off by setting com.victronenergy.settings: '/Settings/CGwacs/OvervoltageFeedIn' to 0
  • and re-activate the DC-feed by writing 1 when the cell voltage difference falls under certain threshold, e.g. 30...50mV It works well.

sorry, i am pretty sure that is not a task of battery driver. The main task is to provide infos to databus what for the battery better is. (imho)

seidler2547 commented 1 year ago

Coming back to the original topic, of course I miscalculated the time, since it's for the whole pack, not the cell voltage. I think something like 5-10 Minutes is a good time for a 0.1V/Cell voltage drop. To make it easy we could say 500 seconds for the whole transition?

ogurevich commented 1 year ago

the tests show me that 180 sec. seem to be ok. We could also drag this out. Here ist example with full length (180 sec)

https://github.com/Louisvdw/dbus-serialbattery/assets/50322596/d27ccb9f-6da4-4698-a049-70c7f2dc72bb

mr-manuel commented 1 year ago

Coming back to the original topic, of course I miscalculated the time, since it's for the whole pack, not the cell voltage. I think something like 5-10 Minutes is a good time for a 0.1V/Cell voltage drop. To make it easy we could say 500 seconds for the whole transition?

I would not specify the time for the whole transition but for the voltage change (e.g. 0.01 V/10 seconds). Else it's a huge difference if someone is using a 4S system versus a 18S system.

ogurevich commented 1 year ago

I would not specify the time for the whole transition but for the voltage change (e.g. 0.01 V/10 seconds). Else it's a huge difference if someone is using a 4S system versus a 18S system.

indeed, we have to take that into account. Or some thing like this ? FLOAT_MODE_TRANSITION_DURATION = self.cell_count * 12

ogurevich commented 1 year ago

the variant (0.01 V/10 seconds) is also elegant and good

ogurevich commented 1 year ago

The different voltage drop per second is a little scary. If the user sets the float voltage via absorption, the algorithm will fail. It should probably be validated at init time

(pushed in to "voltagedroppersecond" branch)

                chargeMode = "Float"
                if self.control_voltage:
                    if not self.charge_mode.startswith("Float"):
                        self.transition_start_time = int(time())
                        self.initial_control_voltage = self.control_voltage
                        chargeMode = "Float Transition"
                    elif self.charge_mode.startswith("Float Transition"):
                        elapsed_time = int(time()) - self.transition_start_time
                        # Voltage drop per second
                        VOLTAGE_DROP_PER_SECOND = 0.01 / 10
                        voltage_drop = min(
                            VOLTAGE_DROP_PER_SECOND * elapsed_time,
                            self.initial_control_voltage - floatVoltage,
                        )
                        self.control_voltage = (
                            self.initial_control_voltage - voltage_drop
                        )
                        if self.control_voltage <= floatVoltage:
                            self.control_voltage = floatVoltage
                            chargeMode = "Float"
                        else:
                            chargeMode = "Float Transition"
                else:
                    self.control_voltage = floatVoltage
                self.charge_mode = chargeMode
mr-manuel commented 1 year ago

Somehow one step is taking 10 second, the next 20 seconds, then 10 seconds, 20 seconds and so on. Can you check that?

grafik

ogurevich commented 1 year ago

roger, wilco

ogurevich commented 1 year ago

how often is this function called?

mr-manuel commented 1 year ago

It should be every second

ogurevich commented 1 year ago

thank you, there is a bug, i check it and try to fix. (not good)

ogurevich commented 1 year ago

https://github.com/Louisvdw/dbus-serialbattery/assets/50322596/a92813cd-5e36-44d0-a4b2-6236a89c0519 hm, probably graph interpolation ?

mr-manuel commented 1 year ago

Theoretically it should get and display every change. The reduction seems a bit to steep for me comaring with the measured voltage. How does your graphics look like? Is the measured voltage following the voltage reduction?

grafik

ogurevich commented 1 year ago

it looks not bad in my setup. There is a table view possible, let's check the values please Screenshot 2023-06-16 at 13 41 50 Screenshot 2023-06-16 at 13 41 36

ogurevich commented 1 year ago

the reduction of maxChargeVoltage seems to be correct. Agreed ? Screenshot 2023-06-16 at 13 47 42

ogurevich commented 1 year ago

sorry, now with a timeline Screenshot 2023-06-16 at 14 15 32 maybe the difference is due to the loads in our system. (ESS and DC feed in excess)

PS: The SmartShunt displays the voltage much more evenly than the BMS

mr-manuel commented 1 year ago

All good the timespan matches exactly the code.

I was only thinking about to increase it, but I looked again at the code on the top of this issue, so this is fine.

ogurevich commented 1 year ago

… please set a bigger value there.