# Classes, methods and properties

class pyenphase.Envoy(host, client=None, timeout=None)

  Bases: `object`

  Class for communicating with an envoy.

  Collects solar production data for all Envoy models as of firmware 3.9. Depending on model and installed components can collect power/energy consumption, battery charge, discharge and settings. Supports communication with both pre- and post V7 Envoy firmware.

      envoy = Envoy(host_ip_or_name)
      await envoy.setup()
      await envoy.authenticate(
          username=username,
          password=password,
          token=token
      )
      await envoy.update()
      # ...
      await envoy.close()

  Parameters:

    - host (`str`) – Envoy DNS name or IP address

    - client (`ClientSession` | `None`) – aiohttp ClientSession not verifying SSL certificates, if not specified one will be created. In that case call `Envoy.close()` before application exit.

    - timeout (`float` | `ClientTimeout` | `None`) – aiohttp ClientTimeout to use, if not specified 10 sec connection and 45 sec read timeouts will be used.

  property acb_count: int

    Return the number of reported ACB batteries in Production storage report section.

  property active_phase_count: int

    Return the number of actual reported phases in Envoy production/consumption report.

  async authenticate(username=None, password=None, token=None)

    Authenticate to the Envoy based on firmware version.

    If firmware version retrieved in Envoy.setup is < 7 then create DigestAuth using passed username and password. Use ‘envoy’ or ‘installer’ username and blank password.

    If Firmware is >= 7 create JWT Token based authorization. If token is passed, use it for authorization. If no token is passed, username and password should be Enlighten Cloud credentials to obtain a token. Validate the token with the local Envoy.

    Parameters:

      - username (`str` | `None`) – Enligthen Cloud username or local Envoy username, defaults to None

      - password (`str` | `None`) – Enligthen Cloud password or local Envoy password, defaults to None

      - token (`str` | `None`) – Token to use with authentication, defaults to None

    Raises:

      EnvoyAuthenticationRequired – Authentication failed with the local Envoy, provided token is expired or no token could be obtained from Enlighten cloud due to error or missing parameters.

    Return type:

      `None`

  async close()

    Close or clean anything opened or created on behalf of the caller.

    Should be called when ending application, if:

    - no aiohttp ClientSession was specified for the Envoy:

      - the pyenphase-created ClientSession will be closed.

    - an aiohttp ClientSession was provided by the caller:

      - Envoy will not close the provided session; the caller remains responsible.

    Return type:

      `None`

    Returns:

      None

  async close_dry_contact(id)

    Close a dry contact relay.

    POST {“dry_contacts”: {“id”: id, “status”: “closed”}} to Envoy to close dry contact with specified id. Upon successful POST, update dry contact status in internal data as Envoy needs some time to implement the change and have status updated.

    Parameters:

      id (`str`) – relay id of dry contact relay to open

    Raises:

      - EnvoyFeatureNotAvailable – If ENPOWER feature is not available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  property consumption_meter_type: CtType | None

    Return the type of consumption ct meter installed (total or net-consumption or None) as read from the Envoy.

  property ct_meter_count: int

    Return the number of configured current transformers (CT) as read from the Envoy

  property ct_meter_list: list[CtType | str]

    Return the list of configured current transformers (CT) as read from the Envoy

  async disable_charge_from_grid()

    Disable charge from grid for Encharge batteries.

    Set charge_from_grid false in internal stored tariff data and send updated tariff data to Envoy using PUT. This will update the charge from grid setting to false in the Envoy.

    Raises:

      - EnvoyFeatureNotAvailable – If no Encharge or IQ batteries are available

      - EnvoyFeatureNotAvailable – If no TARIFF data is available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

      - ValueError – If update was attempted before first data was requested from Envoy

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  async enable_charge_from_grid()

    Enable charge from grid for Encharge batteries.

    Set charge_from_grid true in internal stored tariff data and send updated tariff data to Envoy using PUT. This will update the charge from grid setting to true in the Envoy.

    Raises:

      - EnvoyFeatureNotAvailable – If no Encharge or IQ batteries are available

      - EnvoyFeatureNotAvailable – If no TARIFF data is available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

      - ValueError – If update was attempted before first data was requested from Envoy

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  property envoy_model: str

    Return Envoy model description.

    Describes the Envoy model based on properties found.

    - if 2 or more phases found or at least 1 ct is found:

    - - phase count

    - - phase mode

    - if CT found, type of CTs

    Example: “Envoy, phases: 2, phase mode: split, net-consumption CT, production CT”

    Returns:

      String describing the Envoy model and features.

  property firmware: AwesomeVersion

    Return the Envoy firmware version as read from the Envoy.

  async go_off_grid()

    Make a request to the Envoy to go off grid.

    POST {“mains_admin_state”: “open”} to /ivp/ensemble/relay directing to disconnect from the grid. Requires ENPOWER installed.

    Raises:

      - EnvoyFeatureNotAvailable – If ENPOWER feature is not available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON returned by Envoy

  async go_on_grid()

    Make a request to the Envoy to go on grid.

    POST {“mains_admin_state”: “closed”} to /ivp/ensemble/relay directing to connect to the grid. Requires ENPOWER installed.

    Raises:

      - EnvoyFeatureNotAvailable – If ENPOWER feature is not available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON returned by Envoy

  property host: str

    Return the Envoy host specified at initialization.

  async interface_settings()

    Returns Envoy active interface information.

    Returned data includes interface mac, interface type, software build date, configured timezone and DHCP settings

    This data is sourced from the /home endpoint which is a slower responding endpoint with some potential overhead on the Envoy. For this reason, as well as the fact that the data is static, it will only be fetched one time when called first time and cached internally. Subsequent calls will be fulfilled from the cache. A call to envoy.setup() will invalidate the cached data and result in a one-time read from Envoy upon next call.

    Return type:

      `EnvoyInterfaceInformation` | `None`

    Returns:

      Interface details or None if error

  property is_metered: bool

    Return the Envoy imetered info as read from the Envoy.

  meter_type(meter_type)

    Return the type of ct meter installed as read from the Envoy.

    Return type:

      `CtType` | `str` | `None`

  async open_dry_contact(id)

    Open a dry contact relay.

    POST {“dry_contacts”: {“id”: id, “status”: “open”}} to Envoy to open dry contact with specified id. Upon successful POST, update dry contact status in internal data as Envoy needs some time to implement the change and have status updated.

    Parameters:

      id (`str`) – relay id of dry contact relay to open

    Raises:

      - EnvoyFeatureNotAvailable – If ENPOWER feature is not available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  property part_number: str | None

    Return the Envoy part number as read from the Envoy.

  property phase_count: int

    Return the number of configured phases for CT meters as read from the Envoy.

  property phase_mode: EnvoyPhaseMode | None

    Return the phase mode configured for the CT meters (single, split or three) as read from the Envoy.

  async probe()

    Probe for Envoy model and supported features.

    For each updater in the list of updaters returned by get_updaters, execute the probe() method. Build and store a list of updaters to use, containing updaters for which the probe() method does return at least 1 supported feature. Store the map of all returned supported features.

    An updaters probe method should determine if the data for the specific updater scope is available or not. If so, the updaters update() method will be used during data collection.

    Probe should be used only once, after setup and authorization at the start of the communication. The update() method will call probe if not done prior.

    Raises:

      EnvoyProbeFailed – if no solar production data can be found on the Envoy. Solar production data is available in all Envoy models.

    Return type:

      `None`

  async probe_request(endpoint)

    Make a probe request to the Envoy.

    Probe requests are intended for use by updates during initial search of available features in the Envoy. They are not retried on connection errors, timeouts or bad JSON responses. For regular data retrieval, use the request method. Sends GET request to endpoint on Envoy and returns the response.

    Probe retries on client connection issues or timeouts. Will retry up to `MAX_REQUEST_ATTEMPTS` times or `MAX_PROBE_REQUEST_DELAY` sec elapsed at next try, which ever comes first.

    Parameters:

      endpoint (`str`) – Envoy Endpoint to access, start with leading /.

    Raises:

      EnvoyAuthenticationRequired – if no prior authentication was completed or HTTP status 401 or 404 is returned.

    Return type:

      `ClientResponse`

    Returns:

      request response.

  property production_meter_type: CtType | None

    Return the type of production ct meter installed (Production or None) as read from the Envoy.

  async request(endpoint, data=None, method=None)

    Make a request to the Envoy.

    Send GET or POST request to Envoy. Defaults to GET, specify data dictionary to perform a POST. Only specify the endpoint path in the Envoy, HTTP type and Envoy address is prepended to form full URL based on authentication method.

    Request retries on client connection issues or timeouts. Will retry up to `MAX_REQUEST_ATTEMPTS` times or `MAX_REQUEST_DELAY` sec elapsed at next try, which ever comes first.

    Parameters:

      - endpoint (`str`) – Envoy Endpoint to access, start with leading /

      - data (`dict`[`str`, `Any`] | `None`) – optional data dictionary to send to the Envoy Defaults to none, if none a GET request is issued.

      - method (`str` | `None`) – HTTP method to use when sending data dictionary, if none and data is specified POST is default

    Raises:

      EnvoyAuthenticationRequired – if no prior authentication was completed or HTTP status 401 or 404 is returned.

    Raises:

      Any communication errors when retries are exceeded

    Return type:

      `ClientResponse`

    Returns:

      request response.

  property serial_number: str | None

    Return the Envoy serial number as read from the Envoy.

  async set_reserve_soc(value)

    Set the Encharge reserve state of charge.

    Set reserved_soc in internal stored tariff data to specified value and send updated tariff data to /admin/lib/tariff in Envoy using PUT. This will update the reserve soc setting in the Envoy.

    Parameters:

      value (`int`) – reserve soc to set

    Raises:

      - EnvoyFeatureNotAvailable – If no Encharge or IQ batteries are available

      - EnvoyFeatureNotAvailable – If no TARIFF data is available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

      - ValueError – If update was attempted before first data was requested from Envoy

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  async set_storage_mode(mode)

    Set the Encharge storage mode.

    Set storage_mode in internal stored tariff data to specified mode and send updated tariff data to /admin/lib/tariff in Envoy using PUT. This will update the storage mode setting in the Envoy.

    Parameters:

      mode (`EnvoyStorageMode`) – storage mode to set

    Raises:

      - EnvoyFeatureNotAvailable – If no Encharge or IQ batteries are available

      - EnvoyFeatureNotAvailable – If no TARIFF data is available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

      - ValueError – If update was attempted before first data was requested from Envoy

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      JSON response of Envoy

  async setup()

    Initiate Envoy communication by obtaining firmware version.

    Read /info on Envoy, accessible without authentication. Instantiates EnvoyFirmware class object. Required to decide what authentication to use for sub-sequent Envoy communication. Use this method as first step after class instantiation

    Will retry up to `MAX_REQUEST_ATTEMPTS` times or `MAX_PROBE_REQUEST_DELAY` elapsed at next try, which ever comes first.

    Raises:

      - EnvoyFirmwareFatalCheckError – if connection or timeout failure occurs

      - EnvoyFirmwareCheckError – on http errors or any HTTP status other then 200

    Return type:

      `None`

  property storage_meter_type: CtType | None

    Return the type of storage ct meter installed (Storage or None) as read from the Envoy.

  property supported_features: SupportedFeatures

    Return the mask of Envoy supported features as established during Probe.

  async update()

    Read data from Envoy.

    For each updater in the list of established updaters during probe(), execute the update() method to collect current data from the Envoy. If probe was never executed, use probe method first.

    An updaters update() method should obtain the data for the specific updater scope and save to the Envoy data set.

    Raises:

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

    Return type:

      `EnvoyData`

    Returns:

      Collected Envoy data

  async update_dry_contact(new_data)

    Update settings for an Enpower dry contact relay.

    POST updated dry contact settings to /ivp/ss/dry_contact_settings in the Envoy. New_data dict can contain one or more of below items to set. The key/value for “id” is required to identify the relay. Only include key/values to change.

        {
            "id": "<relay-id>",
            "grid_action": "value",
            "micro_grid_action": "value",
            "gen_action": "value",
            "override": "value",
            "load_name": "value",
            "mode": "value",
            "soc_low": "value",
            "soc_high": "value",
        },

    Settings specified in the data dict are updated in the internally stored dry_contact_settings and send as a whole to update the Envoy.

    Parameters:

      new_data (`dict`[`str`, `Any`]) – dict of settings to change, “id” key/value required

    Raises:

      - EnvoyFeatureNotAvailable – If ENPOWER feature is not available in Envoy

      - EnvoyCommunicationError – when aiohttp network or communication error occurs.

      - EnvoyHTTPStatusError – when HTTP status is not 2xx.

      - ValueError – If update was attempted before first data was requested from Envoy

      - ValueError – If no “id” key is present in data dict to send.

    Return type:

      `dict`[`str`, `Any`]

    Returns:

      dry_contact_settings JSON returned by Envoy

class pyenphase.auth.EnvoyAuth(host)

  Bases: `object`

  Base class for local Envoy authentication.

  Parameters:

    host (`str`) – local Envoy DNS name or IP Address

  abstract property auth: DigestAuthMiddleware | None

    Setup Digest authentication for local Envoy.

    Required for Envoy firmware < 7.0

  abstract property cookies: dict[str, str]

    Return the Envoy cookie.

  abstractmethod get_endpoint_url(endpoint)

    Return the URL for the endpoint.

    Parameters:

      endpoint (`str`) – Envoy Endpoint to access, start with leading /

    Return type:

      `str`

    Returns:

      formatted full URL string

  abstract property headers: dict[str, str]

    Return the auth headers for Envoy communication.

  abstractmethod async setup(client)

    Setup token based authentication with the local Envoy.

    Required for Envoy firmware >= 7.0

    Parameters:

      client (`ClientSession`) – an aiohttp ClientSession to communicate with the local Envoy,

    Return type:

      `None`

class pyenphase.auth.EnvoyTokenAuth(host, cloud_username=None, cloud_password=None, envoy_serial=None, token=None)

  Bases: `EnvoyAuth`

  Class to authenticate with Envoy using Tokens.

  Use with Envoy firmware 7.x and newer

  Parameters:

    - host (`str`) – local Envoy DNS name or IP Address

    - cloud_username (`str` | `None`) – Enligthen Cloud username, required to obtain new token when token is not specified or expired, defaults to None

    - cloud_password (`str` | `None`) – Enligthen Cloud password, required to obtain new token when token is not specified or expired, defaults to None

    - envoy_serial (`str` | `None`) – Envoy serial number, required to obtain new token when token is not specified or expired, defaults to None

    - token (`str` | `None`) – Token to use with authentication, if not specified, one will be obtained from Enlighten cloud if username, password and serial are specified, defaults to None

  JSON_LOGIN_URL = 'https://enlighten.enphaseenergy.com/login/login.json?'
  TOKEN_URL = 'https://entrez.enphaseenergy.com/tokens'
  property auth: None

    Digest authentication for local Envoy.

    Not used with token authentication. Placeholder for EnvoyAuth abstractproperty

    Returns:

      None

  property cookies: dict[str, str]

    Return cookies returned during setup of the envoy.

    Cookies received from the local Envoy during setup and local jwt check are stored in the class, this method returns these.

    Returns:

      cookies dict

  property expire_timestamp: int

    Return the expiration time for the token.

    Owner useraccount type tokens are valid for a year while installer tokens are only valid for 12 hours.

    Returns:

      epoch expiration time

  get_endpoint_url(endpoint)

    Return the URL for the endpoint.

    Parameters:

      endpoint (`str`) – Envoy Endpoint to access, start with leading /

    Return type:

      `str`

    Returns:

      formatted https URL string

  property headers: dict[str, str]

    Return the authentication headers for Envoy communication.

    Token authorization with Envoy requires an Authorization header in Bearer format with token.

    Returns:

      token authorization header

  property is_consumer: bool

    Return is_consumer state returned in enligthen login json

    This property is only available if a token has been requested from the Enlighten cloud. This is only the case if no token was specified, or a token refresh was requested. If a valid token with a future expiration time was specified no login was attempted and this method will return the default false. If an installer account was used it will return false as well.

    Returns:

      true if enlighten login was performed and used credentials are for consumer account, otherwise false

  property manager_token: str

    Return manager token returned in enligthen login json.

    This property is only available if a token has been requested from the Enlighten cloud. This is only the case if no token was specified, or a token refresh was requested. If a valid token with a future expiration time was specified this method will return an empty string.

    Returns:

      token string

  async refresh()

    Refresh the token for Envoy authentication.

    Retrieves a new token from the Enlighten cloud using specified username, password and Envoy serial number of the class object. Updated token can be accessed using the token property. Token is not stored persistent, caller should store it after refresh and specify token over restarts.

    Return type:

      `None`

  async setup(client)

    Setup token based authentication with the local Envoy

    If no token is specified, a token is obtained from Enlighten Cloud using specified username, password and serialnumber. With the specified or obtained token, validates the token with the local Envoy. New or updated token can be accessed using the token property. Token is not stored persistent, caller should store and specify token over restarts.

    Parameters:

      client (`ClientSession`) – an aiohttp ClientSession to communicate with the local Envoy,

    Raises:

      EnvoyAuthenticationError – Authentication failed with the local Envoy or no token could be obtained from Enlighten cloud due to error, missing parameters or Enlighten account issue.

    Return type:

      `None`

  property token: str

    Return token used with the Envoy.

    Returns the current token, either the original specified token, or the token obtained from the Enlighten cloud if not specified or the refreshed token at expiration.

    Will assert if no token was ever specified or obtained.

    Returns:

      jwt token string

  property token_type: str

    Return the enphase user type for the token.

    Enlighten user accounts can be type ‘owner’ or ‘installer’. Both have access to the envoy base data. Installer has access to more data and configuration setup.

    Raises:

      EnvoyAuthenticationRequired if no prior authentication was done

    Returns:

      ‘owner’ or ‘installer’

class pyenphase.auth.EnvoyLegacyAuth(host, username, password)

  Bases: `EnvoyAuth`

  Class to authenticate with legacy Envoy using digest.

  Use with Envoy firmware before 7.0

  Parameters:

    - host (`str`) – local Envoy DNS name or IP Address

    - local_username – Username to access Envoy

    - local_password – Password to access Envoy

  property auth: DigestAuthMiddleware | None

    Digest authentication for local Envoy.

    Creates DigestAuthMiddleware based on username and password.

    Returns:

      DigestAuthMiddleware for local Envoy or None if username and/or password are not specified

  property cookies: dict[str, str]

    Return cookies returned during setup of the envoy.

    DigestAuth does not use cookies. Placeholder for EnvoyAuth abstractproperty.

    Returns:

      empty dict

  get_endpoint_url(endpoint)

    Return the URL for the endpoint.

    Parameters:

      endpoint (`str`) – Envoy Endpoint to access, start with leading /

    Return type:

      `str`

    Returns:

      formatted http URL string

  property headers: dict[str, str]

    Return the headers needed for Envoy authentication.

    DigestAuth does not use authorization header. Placeholder for EnvoyAuth abstractproperty.

    Returns:

      empty dict

  async setup(client)

    Setup authentication with the local Envoy

    DigestAuth does not use additional setup, placeholder for EnvoyAuth abstractpropery.

    Parameters:

      client (`ClientSession`) – ClientSession to communicate with local Envoy

    Return type:

      `None`

class pyenphase.firmware.EnvoyFirmware(_client, host)

  Bases: `object`

  Class for querying and determining the Envoy firmware version.

  Parameters:

    - client – aiohttp ClientSession not verifying SSL certificates, see `pyenphase.ssl`.

    - host (`str`) – Envoy DNS name or IP address

  property is_metered: bool

    Return imetered setting as read from Envoy.

    Returns:

      Envoy info imetered setting. Only True if read and set in info

  property part_number: str | None

    Return part number as read from Envoy.

    Returns:

      Envoy part number or None if `pyenphase.firmware.EnvoyFirmware.setup` was not used

  property serial: str | None

    Return serial number as read from Envoy.

    Returns:

      Envoy serial number or None if `pyenphase.firmware.EnvoyFirmware.setup` was not used

  async setup()

    Obtain the firmware version, serial-number and part-number from Envoy.

    Read /info on Envoy, accessible without authentication. Store firmware version, serial-number and part-number properties from xml response.

    Reads first on HTTPS, if that fails on HTTP for firmware < 7. Will retry up to `MAX_REQUEST_ATTEMPTS` times or `MAX_PROBE_REQUEST_DELAY` elapsed at next try, which ever comes first on network or remote protocol errors.

        connector = aiohttp.TCPConnector(ssl=create_no_verify_ssl_context())
        client = aiohttp.ClientSession(connector=connector)
        firmware = EnvoyFirmware(client,host)
        await firmware.setup()
        print(firmware.version)

    Raises:

      - EnvoyFirmwareFatalCheckError – if connection or timeout failure occurs

      - EnvoyFirmwareCheckError – on http errors or any HTTP status other then 200

    Return type:

      `None`

  property version: AwesomeVersion

    Return firmware version as read from Envoy.

    Returns:

      Envoy firmware version or None if `pyenphase.firmware.EnvoyFirmware.setup` was not used

class pyenphase.EnvoyData(encharge_inventory=None, encharge_power=None, encharge_aggregate=None, enpower=None, acb_power=None, battery_aggregate=None, collar=None, c6cc=None, system_consumption=None, system_production=None, system_consumption_phases=None, system_production_phases=None, system_net_consumption=None, system_net_consumption_phases=None, ctmeters=<factory>, ctmeters_phases=<factory>, ctmeter_production=None, ctmeter_consumption=None, ctmeter_storage=None, ctmeter_production_phases=None, ctmeter_consumption_phases=None, ctmeter_storage_phases=None, dry_contact_status=<factory>, dry_contact_settings=<factory>, inverters=<factory>, tariff=None, raw=<factory>)

  Bases: `object`

  Data Model for an envoy.

  Data is extract from raw data requested from Envoy. All raw data is also available as-received in `raw`. For details on data models refer to the individual model descriptions.

  acb_power: `EnvoyACBPower` | `None`

    Power and soc for aggregated ACB batteries

  battery_aggregate: `EnvoyBatteryAggregate` | `None`

    aggregated Enphase and ACB battery SOC and total capacity

  c6cc: `EnvoyC6CC` | `None`

    Envoy C6 Combiner controller

  collar: `EnvoyCollar` | `None`

    IQ Meter collar, only for Envoy with IQ Meter Collar integrated consumption metering installed

  ctmeter_consumption: `EnvoyMeterData` | `None`

    Consumption CT power & energy values, only for Envoy metered with consumption CT installed

    May be deprecated in a future version, use `ctmeters` [`CtType.TOTAL_CONSUMPTION`] or `ctmeters` [`CtType.NET_CONSUMPTION`] instead

  ctmeter_consumption_phases: `dict`[`str`, `EnvoyMeterData`] | `None`

    Individual phase consumption CT power & energy values, keyed by `PhaseNames`, only for Envoy metered with consumption installed

    May be deprecated in a future version, use `ctmeters_phases` [`CtType.TOTAL_CONSUMPTION`] or `ctmeters_phases` [`CtType.NET_CONSUMPTION`] instead

  ctmeter_production: `EnvoyMeterData` | `None`

    Production CT power & energy values, only for Envoy metered with production CT installed

    May be deprecated in a future version, use `ctmeters` [`CtType.PRODUCTION`] instead

  ctmeter_production_phases: `dict`[`str`, `EnvoyMeterData`] | `None`

    Individual phase production CT power & energy values, keyed by `PhaseNames`, only for Envoy metered with production CT installed

    May be deprecated in a future version, use `ctmeters_phases` [`CtType.PRODUCTION`] instead

  ctmeter_storage: `EnvoyMeterData` | `None`

    Storage CT power & energy values, only for Envoy metered with storage CT installed

    May be deprecated in a future version, use `ctmeters` [`CtType.STORAGE`] instead

  ctmeter_storage_phases: `dict`[`str`, `EnvoyMeterData`] | `None`

    Individual phase storage CT power & energy values, keyed by `PhaseNames`, only for Envoy metered with storage CT installed

    May be deprecated in a future version, use `ctmeters_phases` [`CtType.STORAGE`] instead

  ctmeters: `dict`[`str`, `EnvoyMeterData`]

    CT power & energy values, only for Envoy metered with CT installed. Keyed by `CtType`

  ctmeters_phases: `dict`[`str`, `dict`[`str`, `EnvoyMeterData`]]

    CT power & energy phase values, only for Envoy metered with CT installed. Keyed by `CtType` and `PhaseNames`

  dry_contact_settings: `dict`[`str`, `EnvoyDryContactSettings`]

    dict of Dry contact relay settings, keyed by relay ID

  dry_contact_status: `dict`[`str`, `EnvoyDryContactStatus`]

    dict of Dry contact relay status, keyed by relay ID

  encharge_aggregate: `EnvoyEnchargeAggregate` | `None`

    Aggregated data for all Encharge devices

  encharge_inventory: `dict`[`str`, `EnvoyEncharge`] | `None`

    dict of found Encharge device information, keyed by Encharge serial number.

  encharge_power: `dict`[`str`, `EnvoyEnchargePower`] | `None`

    dict of Enpower device power and charge state, keyed by Enpower serial number.

  enpower: `EnvoyEnpower` | `None`

    EnchargePower device information

  inverters: `dict`[`str`, `EnvoyInverter`]

    dict of Solar inverter data, keyed by inverter serial-number

  raw: `dict`[`str`, `Any`]

    All request responses received from Envoy in last `Envoy.update`, keyed by endpoint

  system_consumption: `EnvoySystemConsumption` | `None`

    Consumption power & energy values, only for Envoy metered with CT installed

  system_consumption_phases: `dict`[`str`, `EnvoySystemConsumption` | `None`] | `None`

    Individual phase consumption power & energy values, keyed by `PhaseNames`, only for Envoy metered with CT installed

  system_net_consumption: `EnvoySystemConsumption` | `None`

    Net consumption power & energy values, a.k.a. grid import/export, only for Envoy metered with CT installed

  system_net_consumption_phases: `dict`[`str`, `EnvoySystemConsumption` | `None`] | `None`

    Individual phase Net consumption power & energy values, keyed by `PhaseNames`, only for Envoy metered with CT installed

  system_production: `EnvoySystemProduction` | `None`

    Solar Production power & energy values

  system_production_phases: `dict`[`str`, `EnvoySystemProduction` | `None`] | `None`

    Individual phase solar production power & energy values, keyed by `PhaseNames`, only for Envoy metered with CT installed

  tariff: `EnvoyTariff` | `None`

    Tariff information from Envoy

pyenphase constant definitions

pyenphase.const.MAX_PROBE_REQUEST_DELAY = 50

  no more probe request retries after this elapsed time

pyenphase.const.MAX_REQUEST_ATTEMPTS = 4

  maximum retry attempts

pyenphase.const.MAX_REQUEST_DELAY = 120

  no more request retries after this elapsed time

pyenphase.const.PHASENAMES: list[str] = [PhaseNames.PHASE_1, PhaseNames.PHASE_2, PhaseNames.PHASE_3]

  list to access `PhaseNames` by numerical index.

      phase_count = 2
      for phase in range(phase_count):
          print(production[PHASENAMES[phase]])

class pyenphase.const.PhaseNames(*values)

  Bases: `StrEnum`

  Electricity grid phase names.

  PHASE_1 = 'L1'

    first phase (1, A, ..)

  PHASE_2 = 'L2'

    second phase (2, B, ..)

  PHASE_3 = 'L3'

    third phase (3, C, ..)

Model for common properties of an envoy.

# Updaters

## Introduction

Available data from the Envoy depends on the actual model, firmware, and installed components. The pyenphase library internally implements Updaters to obtain the data. Each updater is specialized for one or more members of `pyenphase.EnvoyData`, and its Probe method is called by `pyenphase.Envoy.probe()` to detect whether the Envoy offers a specific dataset. If supported, the method returns the relevant feature mask. If any features are returned, the updater’s update() method is then used by `pyenphase.Envoy.update()` to collect the actual data.

The various datasets relate to one or more `pyenphase.const.SupportedFeatures` feature flags. For example, the `pyenphase.const.SupportedFeatures.PRODUCTION` supported feature flag relates to the `pyenphase.models.system_production.EnvoySystemProduction` data class which reports Solar production values. This flag can be set by either `pyenphase.updaters.production.EnvoyProductionUpdater` or `pyenphase.updaters.api_v1_production.EnvoyApiV1ProductionUpdater` updaters.

Multiple updaters may exist to provide data for a single dataset/feature. For example, Solar production data which is provided by all models may come from different sources. In the most basic Envoy model this data comes from a different endpoint compared to an Envoy equipped with Current Transformers. In both cases the updaters must be able to provide the same data for the `pyenphase.models.system_production.EnvoySystemProduction` data class. This can be implemented in the same updater or in multiple updaters.

An updater is passed the previously identified features to its probe method. If its feature is already included in the passed list, the updater should back off and not report it again. As a result, only the first updater reporting the feature will be used for data collection.

An updater provides data for one or more features, typically (but not exclusively) sourced from a single endpoint on the Envoy. Multiple updaters may source from the same endpoint, as responses are locally cached during a single collection cycle to avoid duplicate requests.

Although each updater has its specific scope, some may need to share information with other updaters or make operational information available for common use in the `pyenphase.envoy.Envoy` class. The probe methods can store this information in `pyenphase.models.common.CommonProperties`. This information is reset by `pyenphase.models.common.CommonProperties.reset_probe_properties()` at each probe start to avoid sticking values.

The base class `pyenphase.updaters.base.EnvoyUpdater` defines the abstract methods `pyenphase.updaters.base.EnvoyUpdater.probe()` and `pyenphase.updaters.base.EnvoyUpdater.update()`, which updaters must implement. Probe initializes the updater and is called during `pyenphase.Envoy.probe()` (once per probe cycle); it must return a `pyenphase.const.SupportedFeatures` mask indicating the data it can provide. Update is then invoked repeatedly to collect the data.

## Supported Features

class pyenphase.const.SupportedFeatures(*values)

  Bases: `IntFlag`

  Features available from Envoy

  Each supported feature maps to a specific data set or information that can be provided by an Envoy. Depending on actual make, firmware and installed components an Envoy may provide 1 or more features. All Envoy should at least report solar production, marked as PRODUCTION.

  Class `EnvoyUpdater` updaters will set these features flags during the `Envoy.probe` phase. During data collection by `Envoy.update` each updater with set features will be used to collect the specific data.

      from pyenphase.const import SupportedFeatures

      # set METERING flag
      features |= SupportedFeatures.METERING

      # test features
      if features.PRODUCTION in supported_features:
          pass

      if features & SupportedFeatures.DUALPHASE:
          pass

  ACB = 4096

    Envoy reports ACB Battery data

  C6CC = 32768

    Envoy reports a C6 Combiner controller

  COLLAR = 16384

    Envoy reports a Collar

  CTMETERS = 1024

    Envoy has enabled CT meter(s)

  DETAILED_INVERTERS = 8192

    Detailed inverter data is reported

  DUALPHASE = 256

    Envoy metered is configured in split phase mode

  ENCHARGE = 16

    Envoy reports encharge data

  ENPOWER = 32

    Envoy reports Enpower data

  GENERATOR = 2048

    Envoy reports generator data

  INVERTERS = 1

    Envoy reports solar panel inverters

  METERING = 2

    Envoy reports active production meter

  NET_CONSUMPTION = 8

    Envoy reports net consumption

  PRODUCTION = 64

    Envoy reports solar production data

  TARIFF = 128

    Envoy reports tariff information

  THREEPHASE = 512

    Envoy metered is configured in three phase mode

  TOTAL_CONSUMPTION = 4

    Envoy reports total consumption

## Common Properties

class pyenphase.models.common.CommonProperties(production_fallback_list=<factory>, acb_batteries_reported=0, imeter_info=False, phase_count=0, ct_meter_count=0, phase_mode=None, meter_types=<factory>, active_phase_count=0)

  Bases: `object`

  Model for common properties for EnvoyUpdater class updaters.

  Class `EnvoyUpdater` implementations each collect a specific data set or information that can be provided by an Envoy. Depending on the actual model, firmware, and installed an Envoy may need one or more updaters to provide all data components, for `pyenphase.Envoy.update`.

  Although each updater has its specific scope, some may need to share information or make operational information available. One set of properties are used during probe to share amongst updaters and with client applications. These should be reset at each probe run. A second set of properties are specific for an updater during its runtime. The updater is in control of resetting the property as needed.

  acb_batteries_reported: `int`

    ACB batteries report current power in production and in the Ensemble SECCTRL endpoint The Ensemble updater should only report combined ACB and Encharge if production reported data

  active_phase_count: `int`

    production updater, number of phases actually reporting phase data

  ct_meter_count: `int`

    meters updater, number of active ct meters

  imeter_info: `bool`

    imeter flag from /info. If true envoy is metered type used to detect metered without actual CT installed to enable picking correct data

  meter_types: `list`[`str`]

    meters updater, list of installed meter types, if installed

  phase_count: `int`

    meters updater, number of phases configured in envoy

  phase_mode: `EnvoyPhaseMode` | `None`

    meters updater, phase mode configured in the CT meters

  production_fallback_list: `list`[`str`]

    Fallback production endpoints for Metered without CT

  reset_probe_properties(is_metered=False)

    Reset common properties at start of probe.

    Probe common properties are reset at each probe by `Envoy.probe` to avoid sticking values. This should only be done for common properties shared among updaters. Any common properties set outside of probe or controlled by a specific updater, should be reset at different moments by the owner of the property.

    Shared common properties to reset:

    > - production_fallback_list shared amongst production updaters

    > - ACB_batteries_reported shared between production and Ensemble

    > - imeter_info setting from /info indicating envoy is metered type

    Return type:

      `None`

    Returns:

      None

## Base class

class pyenphase.updaters.base.EnvoyUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `object`

  Base class for Envoy updaters.

  Updaters should implement a subclass of EnvoyUpdater.

      class EnvoyXyzUpdater(EnvoyUpdater):

  Parameters:

    - envoy_version (`AwesomeVersion`) – firmware version Envoy is running

    - probe_request (`Callable`[[`str`], `Awaitable`[`ClientResponse`]]) – callable specified by `Envoy` to send probe request to the Envoy during `Envoy.probe`

    - request (`Callable`[[`str`], `Awaitable`[`ClientResponse`]]) – callable specified by `Envoy` to send request to the Envoy during `Envoy.update`

    - common_properties (`CommonProperties`) – properties to share between probe and update or between updaters

  async _json_probe_request(end_point)

    Make a probe request to the Envoy and return the JSON response.

    Updaters should use this to collect data during `probe` method.

        xyz_json: dict[str, Any] = await self._json_probe_request(
            "/xyz/endpoint"
        )

    Parameters:

      end_point (`str`) – Envoy endpoint to request. See `Envoy.probe`

    Raises:

      EnvoyHTTPStatusError – If http status not in 2xx range

    Return type:

      `Any`

    Returns:

      JSON content from response

    Seealso:

      `Envoy.probe_request`

  async _json_request(end_point)

    Make a request to the Envoy and return the JSON response.

    Updaters should use this to collect data during `update` method.

        xyz_json: dict[str, Any] = await self._json_request(
            "/xyz/endpoint"
        )

    Parameters:

      end_point (`str`) – Envoy endpoint to request. See `Envoy.request`

    Raises:

      EnvoyHTTPStatusError – If http status not in 2xx range

    Return type:

      `Any`

    Returns:

      JSON content from response

    Seealso:

      `Envoy.request`

  abstractmethod async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Updater must implement a probe method to report which features it supports. Probe method of each registered updater is called by `Envoy.probe`. Intent of probe is to determine if this updater should be used to obtain the data in its scope from the Envoy. If the Envoy model does not provide the data the method should return None.

    If the Envoy model does provide the data in scope, the method should return a supported features mask for which it can provide data. Any supported feature that is already included in the passed discovered_features parameter should NOT be included in the result as these are already provided by another updater and this updater should back off from providing that feature data.

        async def probe(
                self, discovered_features: SupportedFeatures
            ) -> SupportedFeatures | None:
            """Probe the Envoy for this endpoint and return SupportedFeatures."""
            if SupportedFeatures.MY_FEATURE in discovered_features:
                # Already discovered from another updater
                return None
            try:
                json_data: dict[str, Any] = await self._json_probe_request(MY_ENDPOINT)
            except ENDPOINT_PROBE_EXCEPTIONS as e:
                _LOGGER.debug("Endpoint not found at %s: %s", MY_ENDPOINT, e)
                return None
            # process data
            return SupportedFeatures.MY_FEATURE

    Parameters:

      discovered_features (`SupportedFeatures`) – Mask of already discovered SupportedFeatures

    Return type:

      `SupportedFeatures` | `None`

    Returns:

      Mask of SupportedFeatures to be added to already discovered features (and not yet in discovered_features).

  abstractmethod async update(envoy_data)

    Get data from the Envoy and store in EnvoyData.

    Updater must implement an update method to add/update data in `EnvoyData`. Update method of each registered updater is called by `Envoy.update`.

    The update method is expected to obtain the required data from the envoy, map it to the internal data model and store the data. It should also store retrieved raw data in `EnvoyData.raw`

        async def update(self, envoy_data: EnvoyData) -> None:
            """Get data from the Envoy and store in EnvoyData."""
            json_data = await self._json_request(self.end_point)
            envoy_data.raw[self.end_point] = json_data
            # store applicable data in envoy_data

    Parameters:

      envoy_data (`EnvoyData`) – Envoy data model to store collected data in

    Return type:

      `None`

## production

Envoy production data updater

class pyenphase.updaters.production.EnvoyProductionJsonFallbackUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyProductionJsonUpdater`

  Class to handle updates for production data from the production.json endpoint.

  This class will accept the production endpoint even if activeCount is 0

  allow_inverters_fallback = True

class pyenphase.updaters.production.EnvoyProductionJsonUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyProductionUpdater`

  Class to handle updates for production data from the production.json endpoint.

  end_point = '/production.json?details=1'

class pyenphase.updaters.production.EnvoyProductionUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for production data.

  allow_inverters_fallback = False
  end_point = '/production'
  async probe(discovered_features)

    Probe the Envoy for this endpoint and return SupportedFeatures.

    Return type:

      `SupportedFeatures` | `None`

  async update(envoy_data)

    Update the Envoy for this endpoint.

    Return type:

      `None`

class pyenphase.updaters.api_v1_production.EnvoyApiV1ProductionUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for production data.

  async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Return type:

      `SupportedFeatures` | `None`

  async update(envoy_data)

    Update the Envoy for this updater.

    Return type:

      `None`

## Inverters

class pyenphase.updaters.device_data_inverters.EnvoyDeviceDataInvertersUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for inverter device data.

  async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Return type:

      `SupportedFeatures` | `None`

  async update(envoy_data)

    Update the Envoy for this updater.

    Return type:

      `None`

class pyenphase.updaters.api_v1_production_inverters.EnvoyApiV1ProductionInvertersUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for inverter production data.

  async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Return type:

      `SupportedFeatures` | `None`

  async update(envoy_data)

    Update the Envoy for this updater.

    Return type:

      `None`

## EnvoyEnsemble

Pyenphase Ensemble updater class.

class pyenphase.updaters.ensemble.EnvoyEnembleUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for Ensemble devices.

  async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Return type:

      `SupportedFeatures` | `None`

  async update(envoy_data)

    Update the Envoy for this updater.

    Return type:

      `None`

## EnvoyTariff

class pyenphase.updaters.tariff.EnvoyTariffUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for the Envoy tariff data.

  async probe(discovered_features)

    Probe the Envoy for this updater and return SupportedFeatures.

    Updater must implement a probe method to report which features it supports. Probe method of each registered updater is called by `Envoy.probe`. Intent of probe is to determine if this updater should be used to obtain the data in its scope from the Envoy. If the Envoy model does not provide the data the method should return None.

    If the Envoy model does provide the data in scope, the method should return a supported features mask for which it can provide data. Any supported feature that is already included in the passed discovered_features parameter should NOT be included in the result as these are already provided by another updater and this updater should back off from providing that feature data.

        async def probe(
                self, discovered_features: SupportedFeatures
            ) -> SupportedFeatures | None:
            """Probe the Envoy for this endpoint and return SupportedFeatures."""
            if SupportedFeatures.MY_FEATURE in discovered_features:
                # Already discovered from another updater
                return None
            try:
                json_data: dict[str, Any] = await self._json_probe_request(MY_ENDPOINT)
            except ENDPOINT_PROBE_EXCEPTIONS as e:
                _LOGGER.debug("Endpoint not found at %s: %s", MY_ENDPOINT, e)
                return None
            # process data
            return SupportedFeatures.MY_FEATURE

    Parameters:

      discovered_features (`SupportedFeatures`) – Mask of already discovered SupportedFeatures

    Return type:

      `SupportedFeatures` | `None`

    Returns:

      Mask of SupportedFeatures to be added to already discovered features (and not yet in discovered_features).

  async update(envoy_data)

    Get data from the Envoy and store in EnvoyData.

    Updater must implement an update method to add/update data in `EnvoyData`. Update method of each registered updater is called by `Envoy.update`.

    The update method is expected to obtain the required data from the envoy, map it to the internal data model and store the data. It should also store retrieved raw data in `EnvoyData.raw`

        async def update(self, envoy_data: EnvoyData) -> None:
            """Get data from the Envoy and store in EnvoyData."""
            json_data = await self._json_request(self.end_point)
            envoy_data.raw[self.end_point] = json_data
            # store applicable data in envoy_data

    Parameters:

      envoy_data (`EnvoyData`) – Envoy data model to store collected data in

    Return type:

      `None`

## Current Transformers

Envoy CT Meter updater

class pyenphase.updaters.meters.EnvoyMetersUpdater(envoy_version, probe_request, request, common_properties)

  Bases: `EnvoyUpdater`

  Class to handle updates for Envoy CT Meters.

  ct_meters_count: `int` = 0
  data_end_point = '/ivp/meters/readings'
  end_point = '/ivp/meters'

    endpoint in envoy to read CT meter configuration

  meter_eids: `dict`[`int` | `str`, `str`]

    CT identifiers

  meter_types: `list`[`str`]

    CT types found

  phase_count: `int` = 0

    Number of phases configured and measured in the Envoy

  phase_mode: `EnvoyPhaseMode` | `None` = None
  async probe(discovered_features)

    Probe the Envoy meter setup and return CT and multiphase details in SupportedFeatures.

    Get CT configuration info from ivp/meters in the Envoy and determine any multi-phase setup. Set :any:SupportedFeatures.CTMETERS if CT are found and enabled. Set Threephase or Dualphase supported feature if Envoy is in one of these setups.

    Set common properties (phase_count, ct_meter_count, phase_mode, meter_types) to default or discovered values. These are owned by this updater.

    Parameters:

      discovered_features (`SupportedFeatures`) – Features discovered by other updaters for this updater to skip

    Return type:

      `SupportedFeatures` | `None`

    Returns:

      features discovered by this updater

  async update(envoy_data)

    Update the Envoy data from the meters endpoints.

    Get CT configuration from ivp/meters and CT readings from ivp/meters/readings. Store EnvoyMeterData in ctmeters for any meters enabled during probe. If more than one phase is active, store per-phase data in ctmeters_phases. Match data in ivp/meters and ivp/meters/reading using the eid field in both datasets.

    For backward compatibility, ctmeter_production/ctmeter_consumption/ctmeter_storage and their phase equivalents are still set to reference the corresponding entries in ctmeters[CtType] and ctmeters_phases[CtType]. :type envoy_data: `EnvoyData` :param envoy_data: EnvoyData structure to store data to

    Return type:

      `None`

# Models

## EnvoySystemProduction

class pyenphase.models.system_production.EnvoySystemProduction(watt_hours_lifetime, watt_hours_last_7_days, watt_hours_today, watts_now)

  Bases: `object`

  Model for the Envoy’s production data.

  classmethod from_production(data)

    Initialize from the production API.

    Parameters:

      data (`dict`[`str`, `Any`]) – JSON reply from /production endpoint

    Return type:

      `EnvoySystemProduction`

    Returns:

      Lifetime, last seven days, todays energy and current power for solar production

  classmethod from_production_phase(data, phase)

    Initialize from the production API phase data.

    Parameters:

      - data (`dict`[`str`, `Any`]) – JSON reply from /production endpoint

      - phase (`int`) – Index (0-2) in [lines] segment for which to return data

    Return type:

      `EnvoySystemProduction` | `None`

    Returns:

      Lifetime, last seven days, todays energy and current power for production phase

  classmethod from_v1_api(data)

    Initialize from the V1 API.

    Parameters:

      data (`dict`[`str`, `Any`]) – JSON reply from api/v1/production endpoint

    Return type:

      `EnvoySystemProduction`

    Returns:

      Lifetime, last seven days, todays energy and current power for solar production

  watt_hours_last_7_days: `int`

    Energy produced in previous 7 days (not including today)

  watt_hours_lifetime: `int`

    Lifetime Energy produced

  watt_hours_today: `int`

    Energy produced since start of day

  watts_now: `int`

    Current Power production

## EnvoySystemConsumption

class pyenphase.models.system_consumption.EnvoySystemConsumption(watt_hours_lifetime, watt_hours_last_7_days, watt_hours_today, watts_now)

  Bases: `object`

  Model for the Envoy’s (total, house) consumption data.

  classmethod from_production(data, consumption_segment=0)

    Initialize from the production API.

    Parameters:

      data (`dict`[`str`, `Any`]) – JSON reply from /production endpoint

    Return type:

      `EnvoySystemConsumption`

    Returns:

      Lifetime, last 7 days, todays energy and current power for total-consumption

  classmethod from_production_phase(data, phase, consumption_segment=0)

    Initialize from the production API phase data.

    Parameters:

      - data (`dict`[`str`, `Any`]) – JSON reply from /production endpoint

      - phase (`int`) – Index (0-2) in [lines] segment for which to return data

    Return type:

      `EnvoySystemConsumption` | `None`

    Returns:

      Lifetime, last 7 days, todays energy and current power for total-consumption phase

  watt_hours_last_7_days: `int`

    Energy consumed in previous 7 days (not including today)

  watt_hours_lifetime: `int`

    Lifetime Energy consumed (total-consumption, house)

  watt_hours_today: `int`

    Energy consumption since start of day (total-consumption, house)

  watts_now: `int`

    Current Power consumption (total-consumption, house)

## EnvoyInverter

class pyenphase.models.inverter.EnvoyInverter(serial_number, last_report_date, last_report_watts, max_report_watts, dc_voltage=None, dc_current=None, ac_voltage=None, ac_current=None, ac_frequency=None, temperature=None, lifetime_energy=None, energy_produced=None, energy_today=None, last_report_duration=None)

  Bases: `object`

  Model for an Enphase microinverter.

  classmethod from_device_data(data)

    Initialize from device data.

    Return type:

      `EnvoyInverter`

  classmethod from_v1_api(data)

    Initialize from the V1 API.

    Return type:

      `EnvoyInverter`

  ac_current: `float` | `None`
  ac_frequency: `float` | `None`
  ac_voltage: `float` | `None`
  dc_current: `float` | `None`
  dc_voltage: `float` | `None`
  energy_produced: `float` | `None`
  energy_today: `int` | `None`
  last_report_date: `int`
  last_report_duration: `int` | `None`
  last_report_watts: `int`
  lifetime_energy: `int` | `None`
  max_report_watts: `int`
  serial_number: `str`
  temperature: `float` | `None`

## EnvoyEncharge

class pyenphase.models.encharge.EnvoyEncharge(admin_state, admin_state_str, bmu_firmware_version, comm_level_2_4_ghz, comm_level_sub_ghz, communicating, dc_switch_off, encharge_capacity, encharge_revision, firmware_loaded_date, firmware_version, installed_date, last_report_date, led_status, max_cell_temp, operating, part_number, percent_full, serial_number, temperature, temperature_unit, zigbee_dongle_fw_version)

  Bases: `object`

  Model for the Encharge/IQ battery.

  classmethod from_api(inventory)

    Initialize from the API.

    Return type:

      `EnvoyEncharge`

  admin_state: `int`
  admin_state_str: `str`
  bmu_firmware_version: `str`
  comm_level_2_4_ghz: `int`
  comm_level_sub_ghz: `int`
  communicating: `bool`
  dc_switch_off: `bool`
  encharge_capacity: `int`
  encharge_revision: `int`
  firmware_loaded_date: `int`
  firmware_version: `str`
  installed_date: `int`
  last_report_date: `int`
  led_status: `int`
  max_cell_temp: `int`
  operating: `bool` | `None`
  part_number: `str`
  percent_full: `int`
  serial_number: `str`
  temperature: `int`
  temperature_unit: `str`
  zigbee_dongle_fw_version: `str` | `None`

## EnvoyEnchargeAggregate

class pyenphase.models.encharge.EnvoyEnchargeAggregate(available_energy, backup_reserve, state_of_charge, reserve_state_of_charge, configured_reserve_state_of_charge, max_available_capacity)

  Bases: `object`

  Model for Encharge aggregate data.

  classmethod from_api(data)

    Initialize from the API.

    Return type:

      `EnvoyEnchargeAggregate`

  available_energy: `int`
  backup_reserve: `int`
  configured_reserve_state_of_charge: `int`
  max_available_capacity: `int`
  reserve_state_of_charge: `int`
  state_of_charge: `int`

## EnvoyEnchargePower

class pyenphase.models.encharge.EnvoyEnchargePower(apparent_power_mva, real_power_mw, soc)

  Bases: `object`

  Model for the Encharge/IQ battery power.

  classmethod from_api(power)

    Initialize from the API.

    Return type:

      `EnvoyEnchargePower`

  apparent_power_mva: `int`
  real_power_mw: `int`
  soc: `int`

## EnvoyEnpower

class pyenphase.models.enpower.EnvoyEnpower(grid_mode, admin_state, admin_state_str, comm_level_2_4_ghz, comm_level_sub_ghz, communicating, firmware_loaded_date, firmware_version, installed_date, last_report_date, mains_admin_state, mains_oper_state, operating, part_number, serial_number, temperature, temperature_unit, zigbee_dongle_fw_version)

  Bases: `object`

  Model for the Enpower/IQ System Controller.

  classmethod from_api(enpower)

    Initialize from the API.

    Return type:

      `EnvoyEnpower`

  admin_state: `int`
  admin_state_str: `str`
  comm_level_2_4_ghz: `int`
  comm_level_sub_ghz: `int`
  communicating: `bool`
  firmware_loaded_date: `int`
  firmware_version: `str`
  grid_mode: `str`
  installed_date: `int`
  last_report_date: `int`
  mains_admin_state: `str`
  mains_oper_state: `str`
  operating: `bool` | `None`
  part_number: `str`
  serial_number: `str`
  temperature: `int`
  temperature_unit: `str`
  zigbee_dongle_fw_version: `str` | `None`

## EnvoyACBPower

class pyenphase.models.acb.EnvoyACBPower(power, charge_wh, state_of_charge, state, batteries)

  Bases: `object`

  Model for the ACB battery power.

  classmethod from_production(data, acb_segment=0)

    Fill ACB battery power data from Envoy data format.

    Source data URL_PRODUCTION_JSON[“storage”]

          "storage": [{
              "type": "acb",
              "activeCount": 3,
              "readingTime": 1731943992,
              "wNow": 260,
              "whNow": 930,
              "state": "discharging",
              "percentFull": 25
          }]

    Parameters:

      - data (dict[str, Any]) – JSON returned from URL_PRODUCTION_JSON

      - acb_segment (int) – segment to process from storage list, default is 0

    Returns:

      ACB battery current power out/in and energy content and status

    Return type:

      EnvoyACBPower

  batteries: `int`

    Number of reported ACB batteries from activeCount

  charge_wh: `int`

    Current available capacity in Wh for ACB batteries from whNow

  power: `int`

    Current discharge/charge power for ACB batteries from wNow.

  state: `str`

    Current state for ACB batteries (discharging/idle/charging) from state

  state_of_charge: `int`

    Current SOC in percentage for ACB batteries from percentFull

## Envoy Aggregate Battery SOC

class pyenphase.models.acb.EnvoyBatteryAggregate(available_energy, state_of_charge, max_available_capacity)

  Bases: `object`

  Model for combined Encharge and ACB batteries aggregate data.

  classmethod from_api(data)

    Fill Aggregated battery data from Envoy data format.

    Source data parts of URL_ENSEMBLE_SECCTRL

          {

              "agg_soc": 39,
              "Max_energy": 7220,

              "ENC_agg_avail_energy": 350,

              "Enc_max_available_capacity": 3500,
              "ACB_agg_soc": 25,
              "ACB_agg_energy": 930,

          }

    Parameters:

      data (dict[str, Any]) – JSON returned from URL_ENSEMBLE_SECCTRL

    Returns:

      Aggregated Battery data for all Encharge and ACB batteries

    Return type:

      EnvoyBatteryAggregate

  available_energy: `int`

    Sum of Encharge aggregate and ACB aggregate current battery energy content from ENC_agg_avail_energy and ACB_agg_energy.

  max_available_capacity: `int`

    Combined total maximum capacity for all Encharge and ACB batteries from Max_energy.

  state_of_charge: `int`

    Combined State of charge for all Encharge and ACB batteries from agg_soc.

## Envoy Dry Contacts

Model for the Enpower dry contact relays.

class pyenphase.models.dry_contacts.DryContactAction(*values)

  Bases: `StrEnum`

  APPLY = 'apply'
  NONE = 'none'
  SCHEDULE = 'schedule'
  SHED = 'shed'

class pyenphase.models.dry_contacts.DryContactMode(*values)

  Bases: `StrEnum`

  MANUAL = 'manual'
  STATE_OF_CHARGE = 'soc'

class pyenphase.models.dry_contacts.DryContactStatus(*values)

  Bases: `StrEnum`

  CLOSED = 'closed'
  OPEN = 'open'

class pyenphase.models.dry_contacts.DryContactType(*values)

  Bases: `StrEnum`

  LOAD = 'LOAD'
  NONE = 'NONE'
  PV = 'PV'
  THIRD_PARTY_PV = '3RD-PV'

class pyenphase.models.dry_contacts.EnvoyDryContactSettings(id, black_start, essential_end_time, essential_start_time, generator_action, grid_action, load_name, manual_override, micro_grid_action, mode, override, priority, pv_serial_nb, soc_high, soc_low, type)

  Bases: `object`

  Model for the Enpower dry contact relay settings.

  classmethod from_api(relay)

    Initialize from the API.

    Return type:

      `EnvoyDryContactSettings`

  to_api()

    Convert to API format.

    Return type:

      `dict`[`str`, `Any`]

  black_start: `float` | `None`
  essential_end_time: `float` | `None`
  essential_start_time: `float` | `None`
  generator_action: `DryContactAction`
  grid_action: `DryContactAction`
  id: `str`
  load_name: `str`
  manual_override: `bool` | `None`
  micro_grid_action: `DryContactAction`
  mode: `DryContactMode`
  override: `bool`
  priority: `float` | `None`
  pv_serial_nb: `list`[`Any`]
  soc_high: `float`
  soc_low: `float`
  type: `DryContactType`

class pyenphase.models.dry_contacts.EnvoyDryContactStatus(id, status)

  Bases: `object`

  Model for the Enpower dry contact relay status.

  classmethod from_api(relay)

    Initialize from the API.

    Return type:

      `EnvoyDryContactStatus`

  id: `str`
  status: `str`

## EnvoyCollar

Model for the IQ Meter Collar.

class pyenphase.models.collar.EnvoyCollar(admin_state, admin_state_str, firmware_loaded_date, firmware_version, installed_date, last_report_date, communicating, mid_state, grid_state, part_number, serial_number, temperature, temperature_unit, control_error, collar_state)

  Bases: `object`

  Model for the Enphase IQ Meter Collar.

  classmethod from_api(inventory)

    Initialize from the API. Returns None if required keys are missing.

    Return type:

      `EnvoyCollar` | `None`

  admin_state: `int`
  admin_state_str: `str`
  collar_state: `str`
  communicating: `bool`
  control_error: `int`
  firmware_loaded_date: `int`
  firmware_version: `str`
  grid_state: `str`
  installed_date: `int`
  last_report_date: `int`
  mid_state: `str`
  part_number: `str`
  serial_number: `str`
  temperature: `int`
  temperature_unit: `str`

## EnvoyC6CC

Model for the Enphase C6 Combiner.

class pyenphase.models.c6combiner.EnvoyC6CC(admin_state, admin_state_str, firmware_loaded_date, firmware_version, installed_date, last_report_date, communicating, part_number, serial_number, dmir_version)

  Bases: `object`

  Model for the Enphase C6 Combiner.

  classmethod from_api(inventory)

    Initialize from the API. Returns None if required keys are missing.

    Return type:

      `EnvoyC6CC` | `None`

  admin_state: `int`
  admin_state_str: `str`
  communicating: `bool`
  dmir_version: `str`
  firmware_loaded_date: `int`
  firmware_version: `str`
  installed_date: `int`
  last_report_date: `int`
  part_number: `str`
  serial_number: `str`

## CT Meters

Model for the Envoy’s CT Meters.

class pyenphase.models.meters.CtMeterData

  Bases: `TypedDict`

  eid: `str`
  measurementType: `CtType`
  meteringStatus: `CtMeterStatus`
  phaseCount: `int`
  phaseMode: `EnvoyPhaseMode`
  state: `CtState`
  statusFlags: `list`[`CtStatusFlags`]

class pyenphase.models.meters.CtMeterStatus(*values)

  Bases: `StrEnum`

  CHECK_WIRING = 'check-wiring'
  NORMAL = 'normal'
  NOT_METERING = 'not-metering'

class pyenphase.models.meters.CtState(*values)

  Bases: `StrEnum`

  DISABLED = 'disabled'
  ENABLED = 'enabled'

class pyenphase.models.meters.CtStatusFlags(*values)

  Bases: `StrEnum`

  NEGATIVE_PRODUCTION = 'negative-production'
  NEGATIVE_TOTAL_CONSUMPTION = 'negative-total-consumption'
  PODUCTION_IMBALANCE = 'production-imbalance'
  POWER_ON_UNUSED_PHASE = 'power-on-unused-phase'

class pyenphase.models.meters.CtType(*values)

  Bases: `StrEnum`

  BACKFEED = 'backfeed'

    Power and energy backfeed between Combiner/System controller and main panel

  EVSE = 'evse'

    Power and Energy between Combiner/System controller and EV charger

  LOAD = 'load'

    Power and energy assumed between Combiner/System controller and backup load

  NET_CONSUMPTION = 'net-consumption'

    Net consumption between main panel and grid

  PRODUCTION = 'production'

    Solar production to main panel or Combiner/System controller

  PV3P = 'pv3p'

    Power and energy between 3rd-party solar and Combiner/System controller

  STORAGE = 'storage'

    Power and energy between battery and main panel or Combiner/System controller

  TOTAL_CONSUMPTION = 'total-consumption'

    Total consumption between main panel and house load

class pyenphase.models.meters.EnvoyMeterData(eid, timestamp, energy_delivered, energy_received, active_power, power_factor, voltage, current, frequency, state, measurement_type, metering_status, status_flags)

  Bases: `object`

  Model for the Envoy’s CT meter data.

  classmethod from_api(data, meter_status)

    Return CT meter data from /ivp/meters and ivp/meters/reading json.

    Return type:

      `EnvoyMeterData`

  classmethod from_phase(data, meter_status, phase)

    Return CT meter phase data from /ivp/meters and ivp/meters/reading json.

    Return type:

      `EnvoyMeterData` | `None`

  active_power: `int`

    Current power exchange through CT, positive is delivering, negative is receiving

  current: `float`

    Current measured by CT

  eid: `str`

    CT meter identifier

  energy_delivered: `int`

    Lifetime Energy delivered through CT

  energy_received: `int`

    Lifetime Energy received through CT

  frequency: `float`

    frequency measured by CT

  measurement_type: `CtType` | `None`

    Measurement type configured for CT

  metering_status: `CtMeterStatus` | `None`

    CT Measurement status

  power_factor: `float`

    Power factor reported for CT measurement

  state: `CtState` | `None`

    Actual State of CT

  status_flags: `list`[`CtStatusFlags`] | `None`

    CT status flags.

  timestamp: `int`

    Time of measurement

  voltage: `float`

    Voltage on circuit, when multiphase sum of voltage of individual phases

class pyenphase.models.meters.EnvoyPhaseMode(*values)

  Bases: `StrEnum`

  SINGLE = 'single'
  SPLIT = 'split'
  THREE = 'three'

## Interface data

class pyenphase.models.home.EnvoyInterfaceInformation(primary_interface, mac, interface_type, dhcp, software_build_epoch, timezone)

  Bases: `object`

  Envoy Interface information data model.

  classmethod from_api(data)

    Return active interface information configured in Envoy

    Parses the received JSON into EnvoyInterfaceInformation model data Source data must be sourced from URL_HOME.

    software_build_epoch, timezone are returned as is. network.primary_interface is returned as is, and used to find interface data in network.interfaces from which type, mac and dhcp are returned.

    Not all Envoy firmware version may return all data. Defaults for str members is unknown, int 0 and bool False

    Example json returned from /home endpoint:

    >     {
    >         "software_build_epoch": 1719503966,
    >         "timezone": "Europe/Amsterdam",
    >         "current_date": "04/24/2025",
    >         "current_time": "14:53",
    >         "network": {
    >             "web_comm": true,
    >             "ever_reported_to_enlighten": true,
    >             "last_enlighten_report_time": 1745499043,
    >             "primary_interface": "eth0",
    >             "interfaces": [
    >                 {
    >                     "type": "ethernet",
    >                     "interface": "eth0",
    >                     "mac": "00:1D:C0:7F:B6:3B",
    >                     "dhcp": true,
    >                     "ip": "192.168.3.112",
    >                     "signal_strength": 1,
    >                     "signal_strength_max": 1,
    >                     "carrier": true
    >                 },
    >                 {
    >                     "signal_strength": 0,
    >                     "signal_strength_max": 0,
    >                     "type": "wifi",
    >                     "interface": "wlan0",
    >                     "mac": "60:E8:5B:AB:9D:64",
    >                     "dhcp": true,
    >                     "ip": null,
    >                     "carrier": false,
    >                     "supported": true,
    >                     "present": true,
    >                     "configured": false,
    >                     "status": "connecting"
    >                 }
    >             ]
    >         }
    >     }

    Parameters:

      data (`dict`[`str`, `Any`]) – json returned by /home endpoint

    Return type:

      `EnvoyInterfaceInformation` | `None`

    Returns:

      Envoy interface configuration information

  dhcp: `bool`

    interfaces uses DHCP, False if missing

  interface_type: `str`

    primary interface type, “unknown” if missing

  mac: `str`

    mac of primary interface, “unknown” if missing

  primary_interface: `str`

    name of primary (active) interface

  software_build_epoch: `int`

    envoy software build time, 0 if missing

  timezone: `str`

    Timezone set in Envoy, “unknown” if missing

# Utilities

## JSON

Helper functions for JSON.

pyenphase.json.json_loads(end_point, json_source)

  Deserialize a JSON string into a Python object

  Parameters:

    - end_point (`str`) – source for json, used for debug log, typically endpoint on Envoy.

    - json_source (`bytes` | `str`) – json string, typically from request response content to Envoy.

  Return type:

    `Any`

  Returns:

    deserialized JSON

## SSL

Pyenphase SSL helper

pyenphase.ssl.NO_VERIFY_SSL_CONTEXT = <ssl.SSLContext object>

  Alias for `create_no_verify_ssl_context`

      import aiohttp
      from pyenphase.ssl import NO_VERIFY_SSL_CONTEXT

      connector = aiohttp.TCPConnector(ssl=NO_VERIFY_SSL_CONTEXT)
      client = aiohttp.ClientSession(connector=connector)

pyenphase.ssl.SSL_CONTEXT = <ssl.SSLContext object>

  Alias for `create_default_ssl_context`

      import aiohttp
      from pyenphase.ssl import SSL_CONTEXT

      connector = aiohttp.TCPConnector(ssl=SSL_CONTEXT)
      async with aiohttp.ClientSession(connector=connector) as client:
          response = await client.post(url, json=json, data=data)

pyenphase.ssl.create_default_ssl_context()

  Create aiohttp client with default SSL context.

  Return type:

    `SSLContext`

pyenphase.ssl.create_no_verify_ssl_context()

  Return an SSL context that does not verify the server certificate.

  This is a copy of aiohttp’s create_default_context() function, with the ssl verify turned off and old SSL versions enabled.

  https://github.com/aio-libs/aiohttp/blob/33953f110e97eecc707e1402daa8d543f38a189b/aiohttp/connector.py#L911

  Return type:

    `SSLContext`

  Returns:

    SSLcontext with ssl verify turned off.

# Exceptions

Enphase Envoy exceptions.

exception pyenphase.exceptions.EnvoyAuthenticationError(status)

  Bases: `EnvoyError`

  Exception raised when Envoy Authentication fails.

  - When a jwt token authentication failure occurs with the local Envoy.

  - When using token authentication and no cloud credentials or envoy serial are specified

  - When a failure occurs during obtaining a token from the Enlighten cloud

  Parameters:

    status (`str`) – Error status description

exception pyenphase.exceptions.EnvoyAuthenticationRequired(status)

  Bases: `EnvoyError`

  Exception raised when authentication hasn’t been setup.

  - When communication with Envoy was attempted without setting up authentication.

  - When neither token nor username and/or password are specified during authentication.

  Parameters:

    status (`str`) – Error status description

exception pyenphase.exceptions.EnvoyCommunicationError

  Bases: `EnvoyError`

  Exception raised when the Envoy communication fails.

  - aiohttp.ClientError error occurs.

  - asyncio.TimeoutError error occurs

exception pyenphase.exceptions.EnvoyError

  Bases: `Exception`

  Base class for Envoy exceptions.

exception pyenphase.exceptions.EnvoyFeatureNotAvailable

  Bases: `EnvoyError`

  Exception raised when the Envoy feature is not available.

  - When using go on/off grid and ENPOWER feature is not available in Envoy

exception pyenphase.exceptions.EnvoyFirmwareCheckError(status_code, status)

  Bases: `EnvoyError`

  Exception raised when unable to query the Envoy firmware version.

  - http error when sending request to Envoy

  - Any http status code other then 200 received

  Parameters:

    - status_code (`int`) – http status code

    - status (`str`) – Error status description

exception pyenphase.exceptions.EnvoyFirmwareFatalCheckError(status_code, status)

  Bases: `EnvoyError`

  Exception raised when we should not retry getting the Envoy firmware version.

  - aiohttp timeout or connection error when sending request to Envoy

  Parameters:

    - status_code (`int`) – http status code

    - status (`str`) – Error status description

exception pyenphase.exceptions.EnvoyHTTPStatusError(status_code, url)

  Bases: `EnvoyError`

  Exception raised when unable to query the Envoy.

  - HTTP Status of request not in 200 range.

  Parameters:

    - status_code (`int`) – http status code

    - status – Error status description

    - url (`str`) – failing url

exception pyenphase.exceptions.EnvoyPoorDataQuality(status)

  Bases: `EnvoyError`

  Exception raised when data identifies known issues.

  - FW 3.x production values all zero at startup

  Parameters:

    status (`str`) – Error status description

exception pyenphase.exceptions.EnvoyProbeFailed

  Bases: `EnvoyError`

  Exception raised when the Envoy probe fails.