id obj envoy_username envoy_password envoy_serial_no log_flag 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 TRUE Add your Enphase Enlighten Cloud credentials below (not needed if bearer token is provided below) *** USER INPUT *** envoy_username envoy_password Add serial no (12 digit) and IP of local Envoy (mandatory) *** USER INPUT *** envoy_serial_no envoy_ip 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 */10 * * * * log test envoy_ip /ivp/livedata/stream bearer_token POST sc_stream. data: log_flag 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 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. 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. PostEnvoyData Y29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpOw0KDQphc3luYyBmdW5jdGlvbiBwb3N0UFZEYXRhKCkgew0KICBjb25zdCBvcHRpb25zID0gew0KICAgIGhvc3RuYW1lOiBlbnZveV9pcCwNCiAgICBwb3J0OiA0NDMsDQogICAgcGF0aDogZW52b3lfcGF0aCwNCiAgICBtZXRob2Q6ICdQT1NUJywNCiAgICByZWplY3RVbmF1dGhvcml6ZWQ6IGZhbHNlLCAvLyBJZ25vcmUgaW52YWxpZCBjZXJ0aWZpY2F0ZQ0KICAgIGhlYWRlcnM6IHsnQXV0aG9yaXphdGlvbic6ICdCZWFyZXIgJysgYmVhcmVyX3Rva2VuICsgJyd9DQogIH07DQoNCiAgdHJ5IHsNCiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsNCiAgICAgIGNvbnN0IHJlcSA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgKHJlcykgPT4gew0KICAgICAgICBsZXQgZGF0YSA9ICcnOw0KDQogICAgICAgIHJlcy5vbignZGF0YScsIChjaHVuaykgPT4gew0KICAgICAgICAgIGRhdGEgKz0gY2h1bms7DQogICAgICAgIH0pOw0KDQogICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4gew0KICAgICAgICAgIHJlc29sdmUoZGF0YSk7DQogICAgICAgIH0pOw0KICAgICAgfSk7DQoNCiAgICAgIHJlcS53cml0ZShKU09OLnN0cmluZ2lmeSh7J2VuYWJsZSc6MX0pKTsNCiAgICAgIA0KICAgICAgcmVxLm9uKCdlcnJvcicsIChlcnJvcikgPT4gew0KICAgICAgICByZWplY3QoZXJyb3IpOw0KICAgICAgfSk7DQoNCiAgICAgIHJlcS5lbmQoKTsNCiAgICB9KTsNCiAgICBpZihsb2dfZmxhZyl7Y29uc29sZS5sb2coJ1F1ZXJ5IGxvY2FsIEVudm95IElQOiAnICsgZW52b3lfaXApfQ0KICAgIGNvbnN0IGpzb25EYXRhID0gSlNPTi5wYXJzZShyZXNwb25zZSk7DQogICAgcmV0dXJuIGpzb25EYXRhOw0KICB9IGNhdGNoIChlcnJvcikgew0KICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgbG9jYWwgRW52b3kgSVA6ICcgKyBlbnZveV9pcCArICcuIEVycm9yOiAnICsgZXJyb3IubWVzc2FnZSk7DQogIH0NCn0NCg0KdHJ5IHsNCiAgY29uc3QganNvbkRhdGEgPSBhd2FpdCBwb3N0UFZEYXRhKCk7DQogIC8vbG9nKCdQaG90b3ZvbHRhaWtkYXRlbiBlcmZvbGdyZWljaCBhYmdlcnVmZW46JywganNvbkRhdGEpOw0KICAgIGh0dHBfcmVzcF9qc29uID0gSlNPTi5zdHJpbmdpZnkoanNvbkRhdGEsIG51bGwsIDIpOw0KICBlcnJfY250IC09IDE7DQogIGlmKGxvZ19mbGFnKXtjb25zb2xlLmxvZyhsb2dfbXNnICsgJzogT0snKTt9DQogIHJldHVybih0cnVlKQ0KfSBjYXRjaCAoZXJyb3IpIHsNCiAgZXJyX2NudCArPSAxOw0KICBjb25zb2xlLmxvZyhsb2dfbXNnICsgJzogJyArIGVycm9yLm1lc3NhZ2UgKyAnIHwgRXJyb3IgY250OiAnICsgU3RyaW5nKGVycl9jbnQpKTsNCiAgcmV0dXJuKGZhbHNlKTsNCn0= 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)