private static PowerMovements SolarIdleBatteryCharge(MomentEnergy moment)
 {
     var gridToBattery = moment.BatteryCharge;
     var gridToHome = Math.Max(0, moment.GridImportWatts - gridToBattery);
     return new PowerMovements(
         gridToHome: gridToHome,
         gridToBattery: gridToBattery);
 }
 private static PowerMovements SolarBatteryCharge(decimal solarPower, MomentEnergy moment)
 {
     if (moment.GridExportWatts >= 0 && moment.GridImportWatts == 0)
     {
         //var gridToBattery = 0;
         //var gridToHome = 0;
         var solarToBattery = Math.Min(solarPower, moment.BatteryCharge);
         var solarToGrid = moment.GridExportWatts;
         var solarToHome = solarPower - solarToBattery - solarToGrid;
         var powerState = solarToHome < 0 ? PowerMovements.PowerStateEnum.SolarBatteryChargeUnderpowered : PowerMovements.PowerStateEnum.SolarBatteryCharge;
         return new PowerMovements(
             solarToBattery: solarToBattery,
             solarToGrid: solarToGrid,
             solarToHome: solarToHome,
             gridToHome: 0,
             powerState: powerState,
             solarPower: solarPower);
     }
     else // grid import > 0
     {
         PowerMovements? result = null;
         if (solarPower > moment.BatteryCharge)
         {
             var solarToBattery = moment.BatteryCharge;
             var solarToHome = solarPower - solarToBattery;
             var solarToGrid = 0;
             var gridToHome = moment.GridImportWatts;
             result = new PowerMovements(
                 solarToBattery: solarToBattery,
                 solarToGrid: solarToGrid,
                 solarToHome: solarToHome,
                 gridToHome: gridToHome,
                 powerState: PowerMovements.PowerStateEnum.SolarBatteryCharge,
                 solarPower: solarPower
                 );
         }
         else // solar <= battery charge
         {
             var solarToBattery = solarPower;
             var solarToHome = 0;
             var solarToGrid = 0;
             var gridToBattery = moment.BatteryCharge - solarToBattery;
             var gridToHome = moment.GridImportWatts - gridToBattery;
             result = new PowerMovements(
                 solarToBattery: solarToBattery,
                 solarToHome: solarToHome,
                 solarToGrid: solarToGrid,
                 gridToBattery: gridToBattery,
                 gridToHome: gridToHome,
                 powerState: PowerMovements.PowerStateEnum.SolarBatteryCharge,
                 solarPower: solarPower
                 );
         }
         CheckIfBatteryCausedGridImport(result);
         return result;
     }
 }
 private static PowerMovements SolarBatteryDischarge(decimal solarPower, MomentEnergy moment)
 {
     if (moment.GridExportWatts > 0)
     {
         if (solarPower > moment.GridExportWatts)
         {
             // solar to grid
             var solarToGrid = moment.GridExportWatts;
             var solarToHome = solarPower - solarToGrid;
             var batteryToHome = moment.BatteryDischarge;
             return new PowerMovements(
                 solarToHome: solarToHome,
                 solarToGrid: solarToGrid,
                 powerState: PowerMovements.PowerStateEnum.SolarBatteryDischarge,
                 batteryToHome: batteryToHome,
                 solarPower: solarPower
                 );
         }
         else
         {
             var solarToGrid = solarPower;
             var batteryToGrid = moment.GridExportWatts - solarToGrid;
             var batteryToHome = moment.BatteryDischarge - batteryToGrid;
             if (batteryToHome < 0)
             {
                 return new PowerMovements(
                     powerState: PowerMovements.PowerStateEnum.SolarBatteryDischargeUnderpowered,
                     solarToGrid: solarToGrid,
                     batteryToGrid: batteryToGrid,
                     batteryToHome: batteryToHome,
                     solarPower: solarPower);
             }
             else
             {
                 return new PowerMovements(
                     powerState: PowerMovements.PowerStateEnum.SolarBatteryDischarge,
                     solarToGrid: solarToGrid,
                     batteryToGrid: batteryToGrid,
                     batteryToHome: batteryToHome,
                     solarPower: solarPower);
             }
         }
     }
     else 
     {
         var solarToHome = solarPower;
         var batteryToHome = moment.BatteryDischarge;
         var gridToHome = moment.GridImportWatts; // can be 0
         return new PowerMovements(
             solarToHome: solarToHome,
             batteryToHome: batteryToHome,
             gridToHome: gridToHome,
             powerState: PowerMovements.PowerStateEnum.SolarBatteryDischarge,
             solarPower: solarPower);
     }
 }
 private static PowerMovements SolarIdleBatteryDischarge(MomentEnergy moment)
 {
     var batteryToGrid = moment.GridExportWatts;
     var batteryToHome = Math.Max(0, moment.BatteryDischarge - batteryToGrid);
     var gridToHome = moment.GridImportWatts;
     return new PowerMovements(
         batteryToGrid: batteryToGrid,
         batteryToHome: batteryToHome,
         gridToHome: gridToHome);
 }
        private static PowerMovements GridOnly(MomentEnergy moment)
        {
            // seen on 28-sept-2020 when the battery first became full. solar value was 0 :( consumption was zero
            // no accurate home consumption value (fronius)
            // no battery charge or discharge
            // battery reports 100%
            // grid export 2750.07
            // grid imports 0
            // home instant power consupmtion 0
            // system state
            // solar inverters power generation 0
            // solar power generation 0

            return new PowerMovements(gridToHome: moment.GridImportWatts, what: 5,
                solarToGrid: moment.GridExportWatts);
        }
 public static PowerMovements Build(MomentEnergy moment)
 {
     var solarPower = moment.SolarInvertorsPowerGeneration ?? moment.SolarPowerGeneration ?? 0;
     var isSolarPower = solarPower > 0;
     if (isSolarPower) {
         if (moment.IsBatteryCharging)
             return SolarBatteryCharge(solarPower, moment);
         else if (moment.IsBatteryDischarging)
             return SolarBatteryDischarge(solarPower, moment);
         else
             return SolarBatteryIdle(solarPower, moment);
     }
     else { 
         if (moment.IsBatteryCharging)
             return SolarIdleBatteryCharge(moment);
         else if (moment.IsBatteryDischarging)
             return SolarIdleBatteryDischarge(moment);
         else
             return GridOnly(moment);
     }
 }
 private static PowerMovements SolarBatteryIdle(decimal solarPower, MomentEnergy moment)
 {
     if (moment.GridExportWatts > 0)
     {
         var solarToGrid = moment.GridExportWatts;
         var solarToHome = Math.Max(0, solarPower - solarToGrid);
         return new PowerMovements(
             powerState: PowerMovements.PowerStateEnum.SolarBatteryIdle,
             solarToHome: solarToHome,
             solarToGrid: solarToGrid,
             solarPower: solarPower);
     }
     else
     {
         var solarToHome = solarPower;
         return new PowerMovements(
             gridToHome: moment.GridImportWatts,
             powerState: PowerMovements.PowerStateEnum.SolarBatteryIdle,
             solarToHome: solarToHome,
             isSolarPowerSame: true
             );
     }
 }