envoy_username envoy_password envoy_serial_no log_flag id obj envoy_ip envoy_path bearer_token log_msg err_cnt result http_resp_json ENPHASE ENVOY/IQ GATEWAY LOADER Requires >=v7 of Envoy API (i.e. current token authentication method) *** INIT *** err_cnt 0 http_resp_json Toggle logging of "info events" (debugging). Errors will always be logged. *** USER INPUT *** log_flag FALSE Add your Enphase Enlighten Cloud credentials below (not needed if bearer token is provided below) *** USER INPUT *** envoy_username your_envoy_cloud_email@domain.tld envoy_password your_envoy_cloud_password Add serial no (12 digit) and IP of local Envoy (mandatory) *** USER INPUT *** envoy_serial_no your_envoy_serial_no envoy_ip your_local_envoy_IP v4 (e.g. 192.168.1.178) OPTIONAL: Add your existing Envoy token below (e.g. for testing purposes) (Note: If you fill in your token here then automatic token renewal with envoy username/password is disabled) *** USER INPUT *** bearer_token Check if initial Envoy bearer token needs to be requested from Enphase server (Info logging of token renewal is always enabled) EQ bearer_token result envoy_username envoy_password envoy_serial_no TRUE *** CYCLIC PROGRAM LOOP *** Set timer (default every minute) for cyclic fetching of PV data from local Envoy * * * * * LTE err_cnt 0 Variable 'err_cnt' counts Envoy errors to slow down polling in case of errors err_cnt 0 Get PV data from local Envoy. Call GetEnvoyData and IObSetState to fetch PV data from Envoy and to update or create corresponding states in ioBroker You can add/remove/modify the following (5) blocks below with your specific needs With "id" you can define the particular path in the ioBroker tree structure to insert/update the envoy information 1. Get PV METER PRODUCTION envoy_ip /ivp/meters/reports/production bearer_token Get Prod. data: log_flag 0_userdata.0.enphase.production http_resp_json 2. Get PV METER CONSUMPTION envoy_ip /ivp/meters/reports/consumption bearer_token Get Cons. data: log_flag 0_userdata.0.enphase.consumption http_resp_json 3. Get PV METER READINGS envoy_ip /ivp/meters/readings bearer_token Get Meter data: log_flag 0_userdata.0.enphase.meters http_resp_json 4. Get PV PRODUCTION.JSON (old URL, but includes "day" counter "whToday") envoy_ip /production.json bearer_token Get production.json data: log_flag 0_userdata.0.enphase.prod_stat http_resp_json 5. Get PV MICRO INVERTER envoy_ip /api/v1/production/inverters bearer_token Get Inv. data : log_flag 0_userdata.0.enphase.inverter http_resp_json err_cnt -1 Periodic token renewal Default: Daily {"time":{"start":"00:00","end":"24:00","mode":"hours","interval":24},"period":{"days":1},"valid":{"from":"05.06.2023","to":""}} result envoy_username envoy_password envoy_serial_no TRUE Support functions renew_EnvoyToken Y29uc3QgZmV0Y2ggPSByZXF1aXJlKCdub2RlLWZldGNoJyk7DQpjb25zdCBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7DQoNCi8vIExvZ2luLUFuZnJhZ2UNCmNvbnN0IGxvZ2luRGF0YSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh7DQogICd1c2VyW2VtYWlsXSc6IGVudm95X3VzZXJuYW1lLA0KICAndXNlcltwYXNzd29yZF0nOiBlbnZveV9wYXNzd29yZA0KfSk7DQoNCmlmKGxvZ19mbGFnKXtjb25zb2xlLmxvZygnUmVuZXcgdG9rZW4uIDEuIExvZ2luIHRvIGVubGlnaHRlbi5lbnBoYXNlZW5lcmd5LmNvbSB0byBnZXQgc2Vzc2lvbl9pZC4uLicpO30NCg0KZmV0Y2goJ2h0dHBzOi8vZW5saWdodGVuLmVucGhhc2VlbmVyZ3kuY29tL2xvZ2luL2xvZ2luLmpzb24nLCB7DQogIG1ldGhvZDogJ1BPU1QnLA0KICBib2R5OiBsb2dpbkRhdGEsDQogIGhlYWRlcnM6IHsNCiAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcNCiAgfQ0KfSkNCiAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UuanNvbigpKQ0KICAudGhlbihyZXNwb25zZURhdGEgPT4gew0KICAgIGlmKGxvZ19mbGFnKXtjb25zb2xlLmxvZygnUmVzcG9uc2UgZnJvbSBsb2dpbjogJyArIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlRGF0YSkpO30NCg0KICAgIC8vIFRva2VuLUFuZnJhZ2UNCiAgICBjb25zdCB0b2tlbkRhdGEgPSB7DQogICAgICBzZXNzaW9uX2lkOiByZXNwb25zZURhdGEuc2Vzc2lvbl9pZCwNCiAgICAgIHNlcmlhbF9udW06IGVudm95X3NlcmlhbF9ubywNCiAgICAgIHVzZXJuYW1lOiBlbnZveV91c2VybmFtZQ0KICAgIH07DQoNCiAgICBpZihsb2dfZmxhZyl7Y29uc29sZS5sb2coJzIuIExvZ2luIHRvIGVudHJlei5lbnBoYXNlZW5lcmd5LmNvbSB0byBnZXQgbmV3IHRva2VuLi4uJyk7fQ0KICAgIHJldHVybiBmZXRjaCgnaHR0cHM6Ly9lbnRyZXouZW5waGFzZWVuZXJneS5jb20vdG9rZW5zJywgew0KICAgICAgbWV0aG9kOiAnUE9TVCcsDQogICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh0b2tlbkRhdGEpLA0KICAgICAgaGVhZGVyczogew0KICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nDQogICAgICB9DQogICAgfSk7DQogIH0pDQogIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLnRleHQoKSkNCiAgLnRoZW4odG9rZW5SYXcgPT4gew0KICAgIGlmKGxvZ19mbGFnKXtjb25zb2xlLmxvZygnTmV3IHRva2VuOiAnICsgdG9rZW5SYXcpO30NCiAgICBiZWFyZXJfdG9rZW4gPSB0b2tlblJhdzsNCiAgfSkNCiAgLmNhdGNoKGVycm9yID0+IHsNCiAgICBjb25zb2xlLmxvZygnRXJyb3IgdG9rZW4gcmVuZXdhbDogJyArIGVycm9yLm1lc3NhZ2UpOw0KICB9KTs= Function to request a new Enphase bearer token. Your Enphase cloud username, password and serial number of your local Envoy are needed. IObSetState Zm9yKGxldCBpIGluIG9iaikgew0KICAgaWYodHlwZW9mIG9ialtpXSA9PSAnb2JqZWN0JykgSU9iU2V0U3RhdGUoaWQgKyAnLicgKyBpLCBvYmpbaV0pOw0KICAgZWxzZSB7DQogICAgICBpZihleGlzdHNTdGF0ZShpZCArICcuJyArIGkpKSAvLyBFeGlzdGluZyBvYmplY3QvIFVwZGF0ZQ0KICAgICAgICAgeyAgICAgICAgIA0KICAgICAgICAgaWYodHlwZW9mIG9ialtpXSA9PT0gJ3N0cmluZycgfHwgb2JqW2ldIGluc3RhbmNlb2YgU3RyaW5nKQ0KICAgICAgICAgICAgey8vIFN0cmluZw0KICAgICAgICAgICAgc2V0U3RhdGUoaWQgKyAnLicgKyBpLCBvYmpbaV0sIHRydWUpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgey8vIEl0IGlzIGEgbnVtYmVyIG9yIGRhdGUNCiAgICAgICAgICAgIC8vaWYoKG5ldyBEYXRlKG9ialtpXSkpLmdldFRpbWUoKSA+IDAgJiYgb2JqW2ldLnRvU3RyaW5nKCkubGVuZ3RoID09IDEwICYmIG9ialtpXS50b1N0cmluZygpLmNoYXJBdCgwKSA9PSAnMScpDQogICAgICAgICAgICBpZigobmV3IERhdGUob2JqW2ldKSkuZ2V0VGltZSgpID4gMCAmJiBOdW1iZXIob2JqW2ldKSA+IDE2ODUwMDAwMDAgJiYgTnVtYmVyKG9ialtpXSkgPCA0MTAwMDAwMDAwKQ0KICAgICAgICAgICAgICAgey8vIERhdGUNCiAgICAgICAgICAgICAgIHNldFN0YXRlKGlkICsgJy4nICsgaSwgb2JqW2ldLCB0cnVlKTsNCiAgICAgICAgICAgICAgIHNldFN0YXRlKGlkICsgJy4nICsgaSArICdfc3RyJywgZm9ybWF0RGF0ZShvYmpbaV0sICJUVC5NTS5KSkpKIFNTOm1tOnNzIiksIHRydWUpOyANCiAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAgIHsvLyBOdW1iZXINCiAgICAgICAgICAgICAgIHNldFN0YXRlKGlkICsgJy4nICsgaSwgTnVtYmVyKG9ialtpXSksIHRydWUpOw0KICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgfQ0KICAgICAgZWxzZSB7IC8vIE5ldyBvYmplY3QgLyBDcmVhdGUNCiAgICAgICAgIGlmKHR5cGVvZiBvYmpbaV0gPT09ICdzdHJpbmcnIHx8IG9ialtpXSBpbnN0YW5jZW9mIFN0cmluZykNCiAgICAgICAgICAgIHsvLyBTdHJpbmcNCiAgICAgICAgICAgIGNyZWF0ZVN0YXRlKGlkICsgJy4nICsgaSwgb2JqW2ldLCBmYWxzZSwge3R5cGU6ICJzdHJpbmciLCByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZX0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgey8vIEl0IGlzIGEgbnVtYmVyIG9yIGRhdGUNCiAgICAgICAgICAgIC8vaWYoKG5ldyBEYXRlKG9ialtpXSkpLmdldFRpbWUoKSA+IDAgJiYgb2JqW2ldLnRvU3RyaW5nKCkubGVuZ3RoID09IDEwICYmIG9ialtpXS50b1N0cmluZygpLmNoYXJBdCgwKSA9PSAnMScpDQogICAgICAgICAgICBpZigobmV3IERhdGUob2JqW2ldKSkuZ2V0VGltZSgpID4gMCAmJiBOdW1iZXIob2JqW2ldKSA+IDE2ODUwMDAwMDAgJiYgTnVtYmVyKG9ialtpXSkgPCA0MTAwMDAwMDAwKQ0KICAgICAgICAgICAgICAgey8vIERhdGUNCiAgICAgICAgICAgICAgIGNyZWF0ZVN0YXRlKGlkICsgJy4nICsgaSwgb2JqW2ldLCBmYWxzZSwge3R5cGU6ICJudW1iZXIiLCByZWFkOiB0cnVlLCB3cml0ZTogdHJ1ZX0pOw0KICAgICAgICAgICAgICAgY3JlYXRlU3RhdGUoaWQgKyAnLicgKyBpICsgJ19zdHInLCBmb3JtYXREYXRlKG9ialtpXSwgIlRULk1NLkpKSkogU1M6bW06c3MiKSwgZmFsc2UsIHt0eXBlOiAic3RyaW5nIiwgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWV9KTsgDQogICAgICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICB7Ly8gTnVtYmVyDQogICAgICAgICAgICAgICBjcmVhdGVTdGF0ZShpZCArICcuJyArIGksIG9ialtpXSwgZmFsc2UsIHt0eXBlOiAibnVtYmVyIiwgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWV9KTsgLy8gb3IgdHlwZTogIm1peGVkIj8NCiAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICAvL2NvbnNvbGUubG9nKGlkICsgJy4nICsgaSArICc6ICcgKyBvYmpbaV0pOw0KICAgfQ0KfQ== Create new or update existing states in IOBroker according to the JSON structure received from local Envoy URL (function 'GetEnvoyData). In case of a unix timestamp field this function will create an additional IOBroker state to show the unix time in human readable format. The field name of this additional field is built from 'fieldname' followed by '_str' (e.g. 'fieldname_str'). The 'id' parameter specifies the tree hierarchy in IOBroker e.g. '0_userdata.0.enphase.consumption' in which PV data will be populated. GetEnvoyData Y29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpOw0KDQphc3luYyBmdW5jdGlvbiBnZXRQVkRhdGEoKSB7DQogIGNvbnN0IG9wdGlvbnMgPSB7DQogICAgaG9zdG5hbWU6IGVudm95X2lwLA0KICAgIHBvcnQ6IDQ0MywNCiAgICBwYXRoOiBlbnZveV9wYXRoLA0KICAgIG1ldGhvZDogJ0dFVCcsDQogICAgcmVqZWN0VW5hdXRob3JpemVkOiBmYWxzZSwgLy8gSWdub3JlIGludmFsaWQgY2VydGlmaWNhdGUNCiAgICBoZWFkZXJzOiB7J0F1dGhvcml6YXRpb24nOiAnQmVhcmVyICcrIGJlYXJlcl90b2tlbiArICcnfQ0KICB9Ow0KDQogIHRyeSB7DQogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7DQogICAgICBjb25zdCByZXEgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIChyZXMpID0+IHsNCiAgICAgICAgbGV0IGRhdGEgPSAnJzsNCg0KICAgICAgICByZXMub24oJ2RhdGEnLCAoY2h1bmspID0+IHsNCiAgICAgICAgICBkYXRhICs9IGNodW5rOw0KICAgICAgICB9KTsNCg0KICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHsNCiAgICAgICAgICByZXNvbHZlKGRhdGEpOw0KICAgICAgICB9KTsNCiAgICAgIH0pOw0KDQogICAgICByZXEub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7DQogICAgICAgIHJlamVjdChlcnJvcik7DQogICAgICB9KTsNCg0KICAgICAgcmVxLmVuZCgpOw0KICAgIH0pOw0KICAgIGlmKGxvZ19mbGFnKXtjb25zb2xlLmxvZygnUXVlcnkgbG9jYWwgRW52b3kgSVA6ICcgKyBlbnZveV9pcCl9DQogICAgY29uc3QganNvbkRhdGEgPSBKU09OLnBhcnNlKHJlc3BvbnNlKTsNCiAgICByZXR1cm4ganNvbkRhdGE7DQogIH0gY2F0Y2ggKGVycm9yKSB7DQogICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciBsb2NhbCBFbnZveSBJUDogJyArIGVudm95X2lwICsgJy4gRXJyb3I6ICcgKyBlcnJvci5tZXNzYWdlKTsNCiAgfQ0KfQ0KDQp0cnkgew0KICBjb25zdCBqc29uRGF0YSA9IGF3YWl0IGdldFBWRGF0YSgpOw0KICAvL2xvZygnUGhvdG92b2x0YWlrZGF0ZW4gZXJmb2xncmVpY2ggYWJnZXJ1ZmVuOicsIGpzb25EYXRhKTsNCiAgICBodHRwX3Jlc3BfanNvbiA9IEpTT04uc3RyaW5naWZ5KGpzb25EYXRhLCBudWxsLCAyKTsNCiAgZXJyX2NudCAtPSAxOw0KICBpZihsb2dfZmxhZyl7Y29uc29sZS5sb2cobG9nX21zZyArICc6IE9LJyk7fQ0KICByZXR1cm4odHJ1ZSkNCn0gY2F0Y2ggKGVycm9yKSB7DQogIGVycl9jbnQgKz0gMTsNCiAgY29uc29sZS5sb2cobG9nX21zZyArICc6ICcgKyBlcnJvci5tZXNzYWdlICsgJyB8IEVycm9yIGNudDogJyArIFN0cmluZyhlcnJfY250KSk7DQogIHJldHVybihmYWxzZSk7DQp9 Function to fetch PV data from your local Envoy. The JSON response of the given URL will then update (or create if nor existing) the corresponding states in IOBroker (via function IObSetState)