DOMAIN = "easee_solar_charging" CONF_CHARGER_ID = "charger_id" CONF_DEVICE_ID = "device_id" CONF_SITE_ID = "site_id" CONF_SOLAR_PRODUCTION_SENSOR = "solar_production_sensor" CONF_HOUSE_LOAD_SENSOR = "house_load_sensor" CONF_EV_CHARGING_SENSOR = "ev_charging_sensor" ROLLING_AVERAGE_SECONDS = 30 EASEE_DOMAIN = "easee" EASEE_SERVICE_SET_DYNAMIC_LIMIT = "set_charger_dynamic_limit" EASEE_CONTROLLABLE_STATES = {"awaiting_start", "ready_to_charge", "charging"} # States where the session is finished/sleeping: set current to 0 once, then idle. EASEE_SLEEPING_STATES = {"completed", "awaiting_authorization", "awaiting_schedule"} DEFAULT_SCAN_INTERVAL = 30 # seconds # Charging current constraints VOLTAGE_V = 230 PHASES = 3 MIN_CHARGER_CURRENT_A = 6 MAX_CHARGER_CURRENT_A = 16 # Hysteresis HYSTERESIS_A = 2 # dead-band within the charging range (fixed) CONF_STOP_GRACE_MINUTES = "stop_grace_minutes" DEFAULT_STOP_GRACE_MINUTES = 5 CONF_CHARGING_PROFILE = "charging_profile" CHARGING_PROFILE_CONSERVATIVE = "conservative" CHARGING_PROFILE_ALL_SURPLUS = "all_surplus" DEFAULT_CHARGING_PROFILE = CHARGING_PROFILE_CONSERVATIVE CONF_DEAD_BAND_RESYNC_MINUTES = "dead_band_resync_minutes" DEFAULT_DEAD_BAND_RESYNC_MINUTES = 1 CONF_NOTIFY_TARGET = "notify_target" # Watts available at each valid current step on a 3-phase 230V system (P = 3 × V × I) AMPS_TO_POWER_W: dict[int, int] = { a: PHASES * VOLTAGE_V * a for a in range(MIN_CHARGER_CURRENT_A, MAX_CHARGER_CURRENT_A + 1) } def solar_excess_to_charger_current(excess_w: float) -> int: """Return the highest valid charger current (A) that fits within excess_w. Returns 0 if excess is below the minimum charging threshold (6 A). Steps are 1 A increments between 6 A and 16 A on a 3-phase 230 V system. """ amps = int(excess_w / (PHASES * VOLTAGE_V)) if amps < MIN_CHARGER_CURRENT_A: return 0 return min(amps, MAX_CHARGER_CURRENT_A)