Skip to content

Commit 1a1d7f4

Browse files
Merge pull request #277 from vincentwolsink/option_alternative_login
Add option for alternative DIY login method
2 parents c1ed8b1 + 9c2162f commit 1a1d7f4

6 files changed

Lines changed: 49 additions & 3 deletions

File tree

custom_components/enphase_envoy/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
NAME,
4242
PLATFORMS,
4343
CONF_SERIAL,
44+
CONF_TOKEN_ENVOY,
4445
READER,
4546
DEFAULT_SCAN_INTERVAL,
4647
DEFAULT_REALTIME_UPDATE_THROTTLE,
@@ -79,6 +80,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
7980
enlighten_pass=config[CONF_PASSWORD],
8081
inverters=True,
8182
enlighten_serial_num=config[CONF_SERIAL],
83+
token_method_envoy=config.get(CONF_TOKEN_ENVOY, False),
8284
store=store,
8385
disable_negative_production=options.get("disable_negative_production", False),
8486
disabled_endpoints=disabled_endpoints,

custom_components/enphase_envoy/config_flow.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .const import (
2828
DOMAIN,
2929
CONF_SERIAL,
30+
CONF_TOKEN_ENVOY,
3031
DEFAULT_SCAN_INTERVAL,
3132
DEFAULT_REALTIME_UPDATE_THROTTLE,
3233
ENABLE_ADDITIONAL_METRICS,
@@ -48,6 +49,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> EnvoyRead
4849
enlighten_pass=data[CONF_PASSWORD],
4950
inverters=False,
5051
enlighten_serial_num=data[CONF_SERIAL],
52+
token_method_envoy=data.get(CONF_TOKEN_ENVOY, False),
5153
)
5254

5355
try:
@@ -86,6 +88,7 @@ def _async_generate_schema(self):
8688
schema[vol.Required(CONF_SERIAL, default=self.unique_id)] = str
8789
schema[vol.Required(CONF_USERNAME, default=self.username)] = str
8890
schema[vol.Required(CONF_PASSWORD, default="")] = str
91+
schema[vol.Optional(CONF_TOKEN_ENVOY, default=False)] = bool
8992

9093
return vol.Schema(schema)
9194

custom_components/enphase_envoy/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
DEFAULT_GETDATA_TIMEOUT = 60
4848

4949
CONF_SERIAL = "serial"
50+
CONF_TOKEN_ENVOY = "token_method_envoy"
5051

5152
LIVE_UPDATEABLE_ENTITIES = "live-update-entities"
5253
ENABLE_ADDITIONAL_METRICS = "enable_additional_metrics"

custom_components/enphase_envoy/envoy_reader.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
ENVOY_MODEL_M = "Metered"
2929
ENVOY_MODEL_S = "Standard"
3030

31+
ENLIGHTEN_AUTH_URL = "https://enlighten.enphaseenergy.com/login/login.json?"
32+
ENLIGHTEN_TOKEN_URL = "https://entrez.enphaseenergy.com/tokens"
33+
3134
# paths used for fetching enlighten token through envoy
3235
ENLIGHTEN_LOGIN_URL = "https://entrez.enphaseenergy.com/login"
3336
ENDPOINT_URL_GET_JWT = "https://{}/auth/get_jwt"
@@ -784,6 +787,7 @@ def __init__(
784787
disabled_endpoints=[],
785788
lifetime_production_correction=0,
786789
device_data_endpoint="endpoint_device_data",
790+
token_method_envoy=False,
787791
):
788792
"""Init the EnvoyReader."""
789793
self.host = host.lower()
@@ -809,6 +813,7 @@ def __init__(
809813
self.disabled_endpoints = disabled_endpoints
810814
self.lifetime_production_correction = lifetime_production_correction
811815
self.device_data_endpoint = device_data_endpoint
816+
self.token_method_envoy = token_method_envoy
812817

813818
self.uri_registry = {}
814819
for key, endpoint in ENVOY_ENDPOINTS.items():
@@ -970,6 +975,36 @@ async def _async_put(self, url, data, **kwargs):
970975
_LOGGER.debug("TransportError: %s", e)
971976
raise e
972977

978+
async def _fetch_enlighten_token_json(self):
979+
"""
980+
Try to fetch the token json from Enlighten API
981+
:return:
982+
"""
983+
_LOGGER.debug("Fetching enlighten token")
984+
async with self.async_client as client:
985+
# login to Enlighten
986+
payload_login = {
987+
"user[email]": self.enlighten_user,
988+
"user[password]": self.enlighten_pass,
989+
}
990+
resp = await client.post(ENLIGHTEN_AUTH_URL, data=payload_login, timeout=30)
991+
if resp.status_code >= 400:
992+
raise EnlightenError("Could not Authenticate via Enlighten")
993+
994+
# now that we're in a logged in session, we can request the installer token
995+
login_data = resp.json()
996+
payload_token = {
997+
"session_id": login_data["session_id"],
998+
"serial_num": self.enlighten_serial_num,
999+
"username": self.enlighten_user,
1000+
}
1001+
resp = await client.post(
1002+
ENLIGHTEN_TOKEN_URL, json=payload_token, timeout=30
1003+
)
1004+
if resp.status_code != 200:
1005+
raise EnlightenError("Could not get enlighten token")
1006+
return resp.text
1007+
9731008
async def _fetch_envoy_token_json(self):
9741009
"""
9751010
Fetch a token, using the same procedure envoy uses in the webUI
@@ -1039,7 +1074,10 @@ async def _fetch_envoy_token_json(self):
10391074
return resp.json()["access_token"]
10401075

10411076
async def _get_enphase_token(self):
1042-
self._token = await self._fetch_envoy_token_json()
1077+
if self.token_method_envoy:
1078+
self._token = await self._fetch_envoy_token_json()
1079+
else:
1080+
self._token = await self._fetch_enlighten_token_json()
10431081

10441082
_LOGGER.debug("Envoy Token")
10451083
if self._is_enphase_token_expired(self._token):

custom_components/enphase_envoy/translations/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"host": "Host",
1717
"password": "Enlighten Password",
1818
"username": "Enlighten Username",
19-
"serial": "Envoy Serial Number"
19+
"serial": "Envoy Serial Number",
20+
"token_method_envoy": "Simulate local Web UI login (required for DIY account)"
2021
},
2122
"description": "Enter the hostname/ip and serial of your Envoy. Use your Enlighten (installer) account credentials."
2223
}

custom_components/enphase_envoy/translations/nl.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"host": "Host",
1717
"password": "Enlighten Wachtwoord",
1818
"username": "Enlighten Gebruikersnaam",
19-
"serial": "Envoy Serienummer"
19+
"serial": "Envoy Serienummer",
20+
"token_method_envoy": "Simuleer lokale Web UI login (vereist voor DHZ account)"
2021
},
2122
"description": "Voer de hostname/ip en serienummer van je Envoy in. Gebruik je Enlighten (installer) account gegevens."
2223
}

0 commit comments

Comments
 (0)