Пример #1
0
    def test_inactive_when_no_ess(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 1 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/State', 4)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp + 60)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        # No ESS installed
        self._monitor.set_value(self.vebus, '/Hub4/AssistantId', None)

        # Travel 1 minute ahead, Charging should remain inactive because no ESS
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
Пример #2
0
    def test_scheduled_for_tomorrow(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds
        today = (now.date().weekday() + 1) % 7
        tomorrow = (today + 1) % 7

        # Set a schedule to start in 2 minutes and stop in another 10.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          today)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp + 60)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 600)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        # Travel 1 minute ahead
        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # But if it was set for tomorrow it wouldn't match
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          tomorrow)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
Пример #3
0
    def test_run_from_yesterday(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds
        yesterday = now.date().weekday()

        # Set a schedule that started a minute before midnight yesterday
        # and will expire a minute from now.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          yesterday)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', 86340)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration',
            stamp + 120)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        timer_manager.run(60000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
    def test_run_from_yesterday(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds
        yesterday = now.date().weekday()

        # Set a schedule that started a minute before midnight yesterday
        # and will expire a minute from now.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', yesterday)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', 86340)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', stamp + 120)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)

        timer_manager.run(5000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        timer_manager.run(60000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
    def test_scheduled_for_tomorrow(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds
        today = (now.date().weekday() + 1) % 7
        tomorrow = (today + 1) % 7

        # Set a schedule to start in 2 minutes and stop in another 10.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', today)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 600)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)

        # Travel 1 minute ahead
        timer_manager.run(65000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        # But if it was set for tomorrow it wouldn't match
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', tomorrow)
        timer_manager.run(5000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
    def test_flag_reset(self):
        self._set_setting('/Settings/CGwacs/BatteryLife/Flags',
                          Flags.Discharged | Flags.Float | Flags.Absorption)
        self._update_values()
        self._check_settings(
            {'flags': Flags.Discharged | Flags.Float | Flags.Absorption})

        # It was day and it was night, the second day.
        timer_manager.run(86400000)

        self._check_settings({
            'flags': 0,
        })
    def test_flag_reset(self):
        self._set_setting('/Settings/CGwacs/BatteryLife/Flags',
            Flags.Discharged | Flags.Float | Flags.Absorption)
        self._update_values()
        self._check_settings({
            'flags': Flags.Discharged | Flags.Float | Flags.Absorption
        })

        # It was day and it was night, the second day.
        timer_manager.run(86400000)

        self._check_settings({
            'flags': 0,
        })
Пример #8
0
    def test_slow_charge(self):
        self._set_setting('/Settings/CGwacs/BatteryLife/SocLimit', 55)
        self._set_setting('/Settings/CGwacs/BatteryLife/State', State.BLSustain) # Sustain
        self._set_setting('/Settings/CGwacs/BatteryLife/Flags', Flags.Discharged) # Discharged
        self._set_setting('/Settings/CGwacs/BatteryLife/DischargedTime', 1)

        timer_manager.run(900000)
        self._check_settings({
            'state': State.BLForceCharge, # Slow charge
            'flags': Flags.Discharged,
        })

        self._monitor.set_value(self.vebus, '/Soc', 60.01)
        self._update_values()

        self._check_settings({
            'state': State.BLDischarged, # Back into Discharged state
            'flags': Flags.Discharged,
        })
    def test_inactive_when_keepcharged(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds

        # Set a schedule to start in 1 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/State', 9)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)

        # Travel 1 minute ahead, but it should remain out of charge mode
        # because we're in KeepBatteriesCharged.
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
Пример #10
0
    def test_scheduled_charge_multiple_windows(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 1 minutes and stop in 2, then another
        # to start at 3 and stop at 4.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp + 60)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Start',
            stamp + 180)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Soc',
                          100)

        # Another minute or so, it should pop unto scheduled charge
        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})

        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
    def test_inactive_when_no_ess(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds

        # Set a schedule to start in 1 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/State', 4)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)

        # No ESS installed
        self._monitor.set_value(self.vebus, '/Hub4/AssistantId', None)

        # Travel 1 minute ahead, Charging should remain inactive because no ESS
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
Пример #12
0
    def test_scheduled_charge(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 2 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start',
            stamp + 120)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
        self._check_values({'/Control/ScheduledCharge': 0})

        # Another minute or so, it should pop unto scheduled charge
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # SystemState should indicate what happened. state only updates
        # when something changes, and our async update fools the unit tests,
        # so fake a change by moving the SoC.
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(1000)
        self._check_values({
            '/SystemState/State': 0x103,
            '/Control/ScheduledCharge': 1
        })

        # Another minute and scheduled charging will end.
        timer_manager.run(65000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
Пример #13
0
    def test_scheduled_charge(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 2 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start',
            stamp + 120)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
        self._check_values({'/Control/ScheduledCharge': 0})

        # Another minute or so, it should pop unto scheduled charge
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # SystemState should indicate what happened
        self._check_values({
            '/SystemState/State': 0x103,
            '/Control/ScheduledCharge': 1
        })

        # Another minute or so, increase Soc as well, it should pop out again
        timer_manager.run(33000)
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(33000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
Пример #14
0
    def test_inactive_when_keepcharged(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 1 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/State', 9)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp + 60)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          100)

        # Travel 1 minute ahead, but it should remain out of charge mode
        # because we're in KeepBatteriesCharged.
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
    def test_scheduled_charge_multiple_windows(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds

        # Set a schedule to start in 1 minutes and stop in 2, then another
        # to start at 3 and stop at 4.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Start', stamp+180)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/1/Soc', 100)

        # Another minute or so, it should pop unto scheduled charge
        timer_manager.run(65000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        timer_manager.run(65000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})

        timer_manager.run(65000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        timer_manager.run(65000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
    def test_scheduled_charge(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds

        # Set a schedule to start in 2 minutes and stop in another 1.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+120)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 60)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 100)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
        self._check_values({'/Control/ScheduledCharge': 0})

        # Another minute or so, it should pop unto scheduled charge
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        # SystemState should indicate what happened
        self._check_values({
            '/SystemState/State': 0x103,
            '/Control/ScheduledCharge': 1})

        # Another minute or so, increase Soc as well, it should pop out again
        timer_manager.run(33000)
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(33000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})
Пример #17
0
    def test_scheduled_charge_stop_on_soc(self):
        # Add solar charger
        self._add_device('com.victronenergy.solarcharger.ttyO1', {
            '/State': 252,
            '/Link/NetworkMode': 5,
            '/Link/ChargeVoltage': 26,
            '/Link/VoltageSense': None,
            '/Dc/0/Voltage': 24,
            '/Dc/0/Current': 10,
            '/FirmwareVersion': 0x129
        },
                         connection='VE.Direct')

        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 2 minutes and stop in 4.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start',
            stamp + 120)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 180)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          70)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})

        # Another minute or so, it should pop into scheduled charge
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Another minute or so, Soc increases but not enough
        timer_manager.run(33000)
        self._monitor.set_value(self.vebus, '/Soc', 68)
        timer_manager.run(33000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Another minute or so, Soc increases to right level. Discharge
        # is disabled while we are inside the window
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(66000)
        self._check_external_values({
            'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': 192,  # 80% of available PV
            }
        })

        # When we emerge from the charge window, discharge is allowed again.
        timer_manager.run(66000)
        self._check_external_values({
            'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': -1,
            }
        })
Пример #18
0
    def test_hysteresis(self):
        """ Test that battery is allowed to drop 5% before re-acivating
		    recharge, to avoid pulse-charging in a large window if target SOC
		    is reached early. """
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start now and stop in 5 minutes
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 300)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          70)

        # Travel just far enough ahead to trigger the 5-second task in the delegate
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Increase the SOC to match the target, check that charging stopped.
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})

        # Reduce the SOC a little and check that hysteresis is applied
        self._monitor.set_value(self.vebus, '/Soc', 65)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})

        # Reduce SOC below the lower limit and check that charging reactivates
        self._monitor.set_value(self.vebus, '/Soc', 64.9)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Check again that it stops once the target is reached.
        self._monitor.set_value(self.vebus, '/Soc', 69.9)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(5000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})
    def test_scheduled_charge_stop_on_soc(self):
        # Add solar charger
        self._add_device('com.victronenergy.solarcharger.ttyO1', {
            '/State': 252,
            '/Link/NetworkMode': 5,
            '/Link/ChargeVoltage': 26,
            '/Link/VoltageSense': None,
            '/Dc/0/Voltage': 24,
            '/Dc/0/Current': 10,
            '/FirmwareVersion': 0x129}, connection='VE.Direct')

        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now-midnight).seconds

        # Set a schedule to start in 2 minutes and stop in 4.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day', 7)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start', stamp+120)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 180)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc', 70)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
        }})

        # Another minute or so, it should pop into scheduled charge
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        # Another minute or so, Soc increases but not enough
        timer_manager.run(33000)
        self._monitor.set_value(self.vebus, '/Soc', 68)
        timer_manager.run(33000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
        }})

        # Another minute or so, Soc increases to right level. Discharge
        # is disabled while we are inside the window
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': 192, # 80% of available PV
        }})

        # When we emerge from the charge window, discharge is allowed again.
        timer_manager.run(66000)
        self._check_external_values({
                'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': -1,
        }})
Пример #20
0
    def test_scheduled_charge_stop_on_soc(self):
        # Determine seconds since midnight on timer right now.
        now = timer_manager.datetime
        midnight = datetime.combine(now.date(), time.min)
        stamp = (now - midnight).seconds

        # Set a schedule to start in 2 minutes and stop in 4.
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Day',
                          7)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Start',
            stamp + 120)
        self._set_setting(
            '/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Duration', 180)
        self._set_setting('/Settings/CGwacs/BatteryLife/Schedule/Charge/0/Soc',
                          70)

        # Travel 1 minute ahead, state should remain unchanged.
        timer_manager.run(60000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
            }})

        # Another minute or so, it should pop into scheduled charge
        timer_manager.run(66000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Another minute or so, Soc increases but not enough
        timer_manager.run(33000)
        self._monitor.set_value(self.vebus, '/Soc', 68)
        timer_manager.run(33000)
        self._check_external_values(
            {'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 1,
            }})

        # Another minute or so, Soc increases to right level. Discharge
        # is disabled while we are inside the window
        self._monitor.set_value(self.vebus, '/Soc', 70)
        timer_manager.run(66000)
        self._check_external_values({
            'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': 1,
            }
        })

        # When we emerge from the charge window, discharge is allowed again.
        timer_manager.run(66000)
        self._check_external_values({
            'com.victronenergy.hub4': {
                '/Overrides/ForceCharge': 0,
                '/Overrides/MaxDischargePower': -1,
            }
        })