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 (LOCAL_TIMEOUT).

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:
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:
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:
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:
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:
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.

property last_request_statistics: dict[str, str | int | float | None]

Return statistics of last request call.

Returns retry information on last executed pyenphase.Envoy.request() method. Provides information on retry endpoint, attempts and elapsed time.

Returns:

{“endpoint”: str,”attempt_number”: int,”delay_since_first_attempt”: float}.

meter_type(meter_type)
Overloads:
  • self, meter_type (CtType) → CtType | None

  • self, meter_type (str) → str | None

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

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:
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 during initial search of available features in the Envoy. For regular data retrieval, use the pyenphase.Envoy.request() or pyenphase.Envoy.update() methods. Sends GET request to endpoint on Envoy and returns the response.

Probe retries on client connection issues or timeouts. Will retry up to MAX_PROBE_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. By default will retry up to DEFAULT_MAX_REQUEST_ATTEMPTS times or DEFAULT_MAX_REQUEST_DELAY sec elapsed at next try, which ever comes first. Adjust these settings using pyenphase.Envoy.set_retry_policy()

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:
Return type:

dict[str, Any]

Returns:

JSON response of Envoy

set_retry_policy(*, max_delay=None, max_attempts=None, wait_multiplier=None)

Set request retry parameters for request retries. Retry attempts will continue until either max_attempts have been tried or maximum elapsed time in seconds since first try has passed at next attempt. Applies to pyenphase.Envoy.update() and pyenphase.Envoy.request() methods.

Parameters:
  • max_delay (int | None) – maximum time elapsed allowed in seconds since first try. Optional, if not specified, setting is not changed. Default setting for each instantiated Envoy is DEFAULT_MAX_REQUEST_DELAY.

  • max_attempts (int | None) – maximum retry attempts. Optional, if not specified, setting is not changed. Default setting for each instantiated Envoy is DEFAULT_MAX_REQUEST_ATTEMPTS.

  • wait_multiplier (float | None) – multiplier to increase wait time between retry attempts. Optional, if not specified, setting is not changed. Default setting for each instantiated Envoy is 2. Set to zero to disable waits between retries

Return type:

None

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:
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_PROBE_REQUEST_ATTEMPTS times or MAX_PROBE_REQUEST_DELAY elapsed at next try, which ever comes first.

Raises:
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:
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_PROBE_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:
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.DEFAULT_MAX_REQUEST_ATTEMPTS = 6

default maximum request retry attempts

pyenphase.const.DEFAULT_MAX_REQUEST_DELAY = 150

default maximum request retry time in seconds

pyenphase.const.LOCAL_TIMEOUT = ClientTimeout(total=45.0, connect=10.0, sock_read=45.0, sock_connect=None, ceil_threshold=5)

default timeout used for requests

pyenphase.const.MAX_PROBE_REQUEST_ATTEMPTS = 4

maximum request probe retry attempts

pyenphase.const.MAX_PROBE_REQUEST_DELAY = 50

maximum elapsed probe retry time in seconds

pyenphase.const.MAX_REQUEST_ATTEMPTS = 6

deprecated alias

pyenphase.const.MAX_REQUEST_DELAY = 150

deprecated alias

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.