public void HandlesChargingSessionWithBreak()
        {
            var fakeDate = new DateTime(2021, 4, 1, 13, 14, 00);
            var tariff   = new Tariff(fakeDate, 0.23d, 0.08d);

            using (new DateTimeProviderContext(fakeDate))
            {
                var t  = new ChargingSession();
                var sm = new SocketMeasurement
                {
                    Mode3State             = Mode3State.E,
                    RealEnergyDeliveredSum = 1000
                };

                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 0, Mode3State.E, tariff);    // 30 seconden op E  (disconnected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 0, Mode3State.B1, tariff);   // 30 seconden op B1 (connected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 0, Mode3State.B2, tariff);   // 30 seconden op B2 (connected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.C2, tariff);  // 30 seconden op C2 (charging)
                Assert.False(t.ChargeSessionInfo.SessionEnded);
                Assert.Equal <double>(11.5d, t.ChargeSessionInfo.Cost);
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 0, Mode3State.C1, tariff);   // 30 seconden op C1 (connected)
                Assert.False(t.ChargeSessionInfo.SessionEnded);
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.C2, tariff);  // 30 seconden op C2 (charging)
                Assert.False(t.ChargeSessionInfo.SessionEnded);
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 0, Mode3State.E, tariff);    // 30 seconden op E  (disconnected)
                Assert.True(t.ChargeSessionInfo.SessionEnded);

                // session has ended, let's see the result of this simple charging session
                Assert.Equal <uint>(60, t.ChargeSessionInfo.ChargingTime);
                Assert.Equal <double>(100, t.ChargeSessionInfo.EnergyDelivered);
                Assert.Equal <double>(23.0d, t.ChargeSessionInfo.Cost);
            }
        }
        public void ReadSocketMeasurement(byte[] piBytes_300, byte[] piBytes_1200, SocketMeasurement expectedSocketMeasurement)
        {
            ushort[] piRegisters_300  = ConvertBytesToRegisters(piBytes_300);
            ushort[] piRegisters_1200 = ConvertBytesToRegisters(piBytes_1200);

            var mock = new Mock <Alfen>(new Config()
            {
                Host = "192.168.1.9", Port = 502, Type = "LAN"
            }, new TestPriceProvider());

            mock.Protected()
            .Setup <ushort[]>("ReadHoldingRegisters", ItExpr.IsAny <byte>(), ItExpr.IsAny <ushort>(), ItExpr.IsAny <ushort>())
            .Returns <byte, ushort, ushort>((slave, address, count) =>
            {
                return((address == 300) ? piRegisters_300 : piRegisters_1200);
            });

            var ss = mock.Object.ReadSocketMeasurement(1);

            Assert.Equal(expectedSocketMeasurement.MeterState, ss.MeterState);
            Assert.Equal(expectedSocketMeasurement.MeterTimestamp, ss.MeterTimestamp);
            Assert.Equal(expectedSocketMeasurement.MeterType, ss.MeterType);
            Assert.Equal(expectedSocketMeasurement.Availability, ss.Availability);
            Assert.Equal(expectedSocketMeasurement.Mode3State, ss.Mode3State);
            Assert.Equal(expectedSocketMeasurement.RealEnergyDeliveredL1, ss.RealEnergyDeliveredL1);
            Assert.Equal(expectedSocketMeasurement.RealEnergyDeliveredL2, ss.RealEnergyDeliveredL2);
            Assert.Equal(expectedSocketMeasurement.RealEnergyDeliveredL3, ss.RealEnergyDeliveredL3);
            Assert.Equal(expectedSocketMeasurement.RealEnergyDeliveredSum, ss.RealEnergyDeliveredSum);

            Assert.Equal(expectedSocketMeasurement.AppliedMaxCurrent, ss.AppliedMaxCurrent);
            Assert.Equal(expectedSocketMeasurement.MaxCurrentValidTime, ss.MaxCurrentValidTime);
            Assert.Equal(expectedSocketMeasurement.MaxCurrent, ss.MaxCurrent);
            Assert.Equal(expectedSocketMeasurement.ActiveLBSafeCurrent, ss.ActiveLBSafeCurrent);
            Assert.Equal(expectedSocketMeasurement.Phases, ss.Phases);
        }
        public void SessionResetWhenStandby()
        {
            var fakeDate = new DateTime(2021, 4, 1, 13, 14, 00);

            using (new DateTimeProviderContext(fakeDate))
            {
                var t  = new ChargingSession();
                var sm = new SocketMeasurement
                {
                    Mode3State             = Mode3State.E,
                    RealEnergyDeliveredSum = 1000
                };

                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.E);       // 30 seconden op E  (disconnected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 10, Mode3State.B1);      // 30 seconden op B1 (connected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 10, Mode3State.B2);      // 30 seconden op B2 (connected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 3600, 5000, Mode3State.B2);  // 1uur        op B2 (connected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.E);       // 30 seconden op E  (disconnected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.A);       // 30 seconden op A  (standby)
                Assert.Null(t.ChargeSessionInfo.Start);
                Assert.Null(t.ChargeSessionInfo.End);
                Assert.Equal(0, t.ChargeSessionInfo.EnergyDelivered);
                Assert.Equal((uint)0, t.ChargeSessionInfo.ChargingTime);
                Assert.False(t.ChargeSessionInfo.SessionEnded);
            }
        }
        public void HandlesSimpleChargingSession()
        {
            var fakeDate = new DateTime(2021, 4, 1, 13, 14, 30);
            var tariff   = new Tariff(fakeDate, 0.23d, 0.08d);

            using (new DateTimeProviderContext(fakeDate))
            {
                var t  = new ChargingSession();
                var sm = new SocketMeasurement
                {
                    Mode3State             = Mode3State.E,
                    RealEnergyDeliveredSum = 1000
                };

                t.UpdateSession(sm, tariff);

                fakeDate = fakeDate.AddSeconds(30);
                using (new DateTimeProviderContext(fakeDate))
                {
                    sm.Mode3State = Mode3State.A;
                    t.UpdateSession(sm, tariff);

                    sm.Mode3State = Mode3State.B1;
                    t.UpdateSession(sm, tariff);

                    sm.Mode3State = Mode3State.B2;
                    t.UpdateSession(sm, tariff);

                    sm.Mode3State = Mode3State.C1;
                    t.UpdateSession(sm, tariff);

                    sm.Mode3State = Mode3State.C2;
                    t.UpdateSession(sm, tariff);

                    Assert.False(t.ChargeSessionInfo.SessionEnded);

                    fakeDate = fakeDate.AddSeconds(65);
                    using (new DateTimeProviderContext(fakeDate))
                    {
                        sm.Mode3State              = Mode3State.E;
                        sm.RealEnergyDeliveredSum += 50;
                        t.UpdateSession(sm, tariff);

                        // session has ended, let's see the result of this simple charging session
                        Assert.Equal <uint>(65, t.ChargeSessionInfo.ChargingTime);
                        Assert.Equal <double>(50, t.ChargeSessionInfo.EnergyDelivered);
                        Assert.True(t.ChargeSessionInfo.SessionEnded);
                        Assert.Equal <double>(11.5d, t.ChargeSessionInfo.Cost);
                    }
                }
            }
        }
        public void EnergyDeliveredNotWhenDisconnected()
        {
            var fakeDate = new DateTime(2021, 4, 1, 13, 14, 00);
            var tariff   = new Tariff(fakeDate, 0.23d, 0.08d);

            using (new DateTimeProviderContext(fakeDate))
            {
                var t  = new ChargingSession();
                var sm = new SocketMeasurement
                {
                    Mode3State             = Mode3State.E,
                    RealEnergyDeliveredSum = 1000
                };

                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.E, tariff);  // 30 seconden op E  (disconnected)
                fakeDate = NextMeasurement(fakeDate, t, sm, 30, 50, Mode3State.E, tariff);  // 30 seconden op E  (disconnected)
                Assert.Equal(0, t.ChargeSessionInfo.EnergyDelivered);
            }
        }
        private static DateTime NextMeasurement(DateTime fakeDate, ChargingSession t, SocketMeasurement sm, int duration, double energy, Mode3State state, Tariff tariff = null)
        {
            using (new DateTimeProviderContext(fakeDate))
            {
                sm.Mode3State = state;
                t.UpdateSession(sm, tariff);
            }
            fakeDate = fakeDate.AddSeconds(duration);
            using (new DateTimeProviderContext(fakeDate))
            {
                sm.RealEnergyDeliveredSum += energy;
                t.UpdateSession(sm, tariff);
            }

            return(fakeDate);
        }
Example #7
0
        public void UpdateSession(SocketMeasurement newMeasurement, Tariff newTariff)
        {
            if (newMeasurement == null)
            {
                return;
            }

            // as long as the car is not connected, there is no session
            if (!_isConnected && !newMeasurement.VehicleConnected && newMeasurement.Mode3State == Mode3State.A)
            {
                ChargeSessionInfo = DefaultSessionInfo();
            }

            // start session as soon as the car is connected
            if (!_isConnected && newMeasurement.VehicleConnected)
            {
                _isConnected            = true;
                _meterReadingStart      = newMeasurement.RealEnergyDeliveredSum;
                ChargeSessionInfo       = DefaultSessionInfo();
                ChargeSessionInfo.Start = DateTimeProvider.Now;

                // reset cost calculation
                _cost                    = 0.0d;
                _currentTariff           = newTariff;
                _meterReadingStartTariff = newMeasurement.RealEnergyDeliveredSum;
            }

            if (_isConnected)
            {
                ChargeSessionInfo.EnergyDelivered = newMeasurement.RealEnergyDeliveredSum - _meterReadingStart;
            }

            // stop session as soon as the car is no longer connected
            if (_isConnected && !newMeasurement.VehicleConnected)
            {
                _isConnected                   = false;
                ChargeSessionInfo.End          = DateTimeProvider.Now;
                ChargeSessionInfo.SessionEnded = true;
            }

            // we are charging and the tariff did change
            // calculate the costs for the usage in for the last tariff
            if (_isCharging && _currentTariff != null)
            {
                if (_currentTariff.TariffUsage != newTariff.TariffUsage)
                {
                    _cost += (newMeasurement.RealEnergyDeliveredSum - _meterReadingStartTariff) * _currentTariff.TariffUsage;

                    ChargeSessionInfo.Cost   = _cost;
                    _meterReadingStartTariff = newMeasurement.RealEnergyDeliveredSum;
                    _currentTariff           = newTariff;
                }
                else
                {
                    ChargeSessionInfo.Cost = _cost + ((newMeasurement.RealEnergyDeliveredSum - _meterReadingStartTariff) * _currentTariff.TariffUsage);
                }
            }

            // the car is started to charge; track start time, tariff
            if (newMeasurement.VehicleIsCharging && !_isCharging)
            {
                _chargingStart = DateTimeProvider.Now;

                _currentTariff           = newTariff;
                _meterReadingStartTariff = newMeasurement.RealEnergyDeliveredSum;
            }

            // the car has stopped charging; record the time
            if (!newMeasurement.VehicleIsCharging && _isCharging)
            {
                ChargeSessionInfo.ChargingTime += (uint)(DateTimeProvider.Now - _chargingStart).TotalSeconds;

                if (_currentTariff != null)
                {
                    _cost += (newMeasurement.RealEnergyDeliveredSum - _meterReadingStartTariff) * _currentTariff.TariffUsage;
                }
                ChargeSessionInfo.Cost = _cost;
            }


            _isCharging = newMeasurement.VehicleIsCharging;
        }