"""
HEATING DEMAND EXAMPLE
"""


import datetime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# comment it if you dowloaded demod from GitHub
import demod

from demod.simulators.base_simulators import SimLogger
from demod.datasets.GermanTOU.loader import GTOU
from demod.datasets.OpenPowerSystems.loader import OpenPowerSystemClimate
from demod.datasets.Germany.loader import GermanDataHerus

from demod.simulators.sparse_simulators import SparseTransitStatesSimulator
from demod.simulators.weather_simulators import RealClimate
from demod.simulators.lighting_simulators import CrestLightingSimulator
from demod.simulators.heating_simulators import  FiveModulesHeatingSimulator
from demod.simulators.appliance_simulators import SubgroupApplianceSimulator
from demod.simulators.weather_simulators import RealInterpolatedClimate


#%% INITIALIZATION

def heat_demand(seed, date):
    np.random.seed(seed)
    data = GermanDataHerus(version='v0.1')
#    time_ = datetime.datetime(2018, 1, 1, 0, 0, 0) # starting time of simulation
    time_ = date
    days = 1 # number of days to be simulated
    n_households = 1 # number of households to be simulated
    subgroup = {
        'n_residents': 2,
        'household_type': 2, 
    } # n° residents should be consisten with the household type
    # Here the available household types:
    # 1 = One person household
    # 2 = Couple without kids
    # 3 = Single Parent with at least one kid under 18 and the other under 27
    # 4 = Couple with at least one kid under 18 and the other under 27
    # 5 = Others
    
    # Occupancy
    occ_sim = SparseTransitStatesSimulator(
        n_households, subgroup, data,
        logger=SimLogger('get_active_occupancy', 'get_occupancy'),
        start_datetime=time_
    )
    
    
    # Climate
    climate_sim = RealInterpolatedClimate(
        data,
        start_datetime=time_,
        logger=SimLogger(
            'get_irradiance', 'get_outside_temperature'
        ),
        # choose the one minute step size
        step_size = datetime.timedelta(minutes=1),
    )
    
    
    # Heating system 
    # It integrates (1) heating demand, (2) thermostat, (3) building thermal 
    # dynamics, (4) heating system control and (5) operation
    heating_sim = FiveModulesHeatingSimulator(
        n_households=n_households,
        initial_outside_temperature=climate_sim.get_outside_temperature(),
        # The algo that computes the heat demand like in CREST
        heatdemand_algo='heat_max_emmiters',
        logger=SimLogger(
            'get_temperatures',
            'get_dhw_heat_demand',
            'get_sh_heat_demand',
            'get_heat_outputs',
            'get_power_demand',
        )
    )
    
    # Appliances, water fixtures 
    app_sim = SubgroupApplianceSimulator(
        [subgroup], [n_households], data=data,
        initial_active_occupancy=occ_sim.get_active_occupancy(),
        start_datetime=time_,
        logger=SimLogger(
            'get_power_demand', 'get_dhw_heating_demand',
            'get_current_power_consumptions', aggregated=False )
    )
    
    # Lighting
    lighting_sim = CrestLightingSimulator(
        n_households=n_households,
        data=data,
        logger=SimLogger('get_power_demand'),
        bulbs_sampling_algo='randn'
    )
    
    #%% SIMULATION
    
    appliance_usage = []
    
    for _ in range(24*days*6):
        # every 10 minutes
        occ_sim.step()
        
        for __ in range(10):
            # every 1 minute
            climate_sim.step()
            
            app_sim.step(
                occ_sim.get_active_occupancy()
            )
            lighting_sim.step(
                occ_sim.get_active_occupancy(),
                climate_sim.get_irradiance()
            )
            heating_sim.step(
                climate_sim.get_outside_temperature(),
                climate_sim.get_irradiance(),
                app_sim.get_dhw_heating_demand(),
                occ_sim.get_thermal_gains(),
                lighting_sim.get_thermal_gains(),
                app_sim.get_thermal_gains(),
                external_target_temperature={'space_heating':20},
            )
            # you can pass different target temperature profiles
            # here it is considered a constant temperature of 20°C 
        
            # store appliance usage
            appliance_usage.append(app_sim.get_current_usage())
    # Wattzahlen in 1 Minuten Schritten: Summe in kWh
    power_demand_1_minute_steps = heating_sim.logger.get('get_power_demand')
    return power_demand_1_minute_steps

# Returns power demand in kWh as array where each element represents demand of 10 minutes
def heat_demand_per_minute_in_kW(power_demand_1_minute_steps):
    # Maps array of elements to function, that divides each element by 1000 
    # By dividing by 1000, W is transformed to kW
    return np.array(power_demand_1_minute_steps) / 1000

# date = datetime.datetime(2018,4,13)
# seed =100005
# bedarf = heat_requirement_daily(heat_requirement(seed, date))
# print(f"Der Tageswärmebedarf am {date.day}. {date.month}. ist {bedarf:.2f} kWh")