{"id":14988600,"url":"https://github.com/dlmcpaul/enphasecollector","last_synced_at":"2025-05-07T08:41:24.269Z","repository":{"id":30983173,"uuid":"124719670","full_name":"dlmcpaul/EnphaseCollector","owner":"dlmcpaul","description":"Enphase Solar Metrics Collector","archived":false,"fork":false,"pushed_at":"2024-09-27T12:06:08.000Z","size":3473,"stargazers_count":73,"open_issues_count":6,"forks_count":19,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-31T08:12:21.437Z","etag":null,"topics":["bulma","enphase","enphase-api","enphase-envoy","enphase-gateway","enphase-iq-envoy","influxdb","java","prometheus","pvoutput","solar","solar-panel-monitor","solar-panels","thymeleaf"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dlmcpaul.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-11T03:25:06.000Z","updated_at":"2025-02-25T17:55:43.000Z","dependencies_parsed_at":"2023-12-20T08:45:47.296Z","dependency_job_id":"0d0926ce-5617-435d-92ea-f31738f1c741","html_url":"https://github.com/dlmcpaul/EnphaseCollector","commit_stats":{"total_commits":603,"total_committers":4,"mean_commits":150.75,"dds":0.08457711442786064,"last_synced_commit":"c623597120569080d2516c5467610fbc624b63e8"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlmcpaul%2FEnphaseCollector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlmcpaul%2FEnphaseCollector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlmcpaul%2FEnphaseCollector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlmcpaul%2FEnphaseCollector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dlmcpaul","download_url":"https://codeload.github.com/dlmcpaul/EnphaseCollector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252844744,"owners_count":21813112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bulma","enphase","enphase-api","enphase-envoy","enphase-gateway","enphase-iq-envoy","influxdb","java","prometheus","pvoutput","solar","solar-panel-monitor","solar-panels","thymeleaf"],"created_at":"2024-09-24T14:17:00.975Z","updated_at":"2025-05-07T08:41:24.245Z","avatar_url":"https://github.com/dlmcpaul.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EnphaseCollector\n\n\u003ca href=\"https://www.mozilla.org/en-US/MPL/2.0/\"\u003e\u003cimg alt=\"mpl2\" src=\"https://img.shields.io/github/license/dlmcpaul/EnphaseCollector\"\u003e\u003c/a\u003e\n\u003ca href=\"https://bulma.io\"\u003e\u003cimg src=\"https://img.shields.io/badge/Made_with-Bulma-brightgreen\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.thymeleaf.org/\"\u003e\u003cimg alt=\"Thymeleaf\" src=\"https://img.shields.io/badge/Rendered_using-Thymeleaf-brightgreen\"\u003e\u003c/a\u003e\n\n\u003e ## Support for envoy firmware \u003e= D7.0.88\n\u003e From around V7 of the envoy firmware the security model for API access was changed.  This is obviously problematic for software such as mine that relies on local access to the API's\n\u003e \n\u003e While it is entirely up to Enphase as to how they develop their software I see a number of issues with their new security model\n\u003e\n\u003e- It links your enphase community account to the token needed to access the API (**If you don't want an account or enphase suspends your account you will lose access**)\n\u003e- It does not look to be based on a standard authentication mechanism such as OAuth (**You should never write your own authentication protocol**)\n\u003e- It is currently broken in a number of ways and will reduce the security of your envoy device (**I will not list the issues here**)\n\u003e  \n\u003e The current release does support V7 firmware, but you will either need to manage the token generation yourself or supply your enphase web user \u0026 password details.\n\u003e SSL over HTTP is also a requirement so the port will need to be set to 443\n\nEnphaseCollector uses the **undocumented API** in the Envoy device to collect individual solar panel data and upload to an influx db, pvoutput site or just as an internal view\n\nCan be run as a java application or using the docker image\n\n| Main Page                                    | Weekly History Tab                           | Questions and Answers Tab                    |\n|----------------------------------------------|----------------------------------------------|----------------------------------------------|\n| ![Screenshot](/docs/images/LocalDisplay.png) | ![Screenshot](/docs/images/LocalWeekly.png)  | ![Screenshot](/docs/images/LocalQnA.png)     |\n\nIf using the jar file you will need a Java 21 that you can get from https://adoptium.net/\n\nExample #1 with default internal website (assuming jar is named enphasecollector-development-SNAPSHOT.jar which is the default build artifact)\n```\njava -jar enphasecollector-development-SNAPSHOT.jar\n```\nwhere the application will attempt to guess the envoy location and password.\n\nExample #2 when envoy.local is not resolved, and you need to specify the ip address and the password cannot be guessed.\n```\njava -jar enphasecollector-DEV.jar --envoy.controller.host=envoy-ip --envoy.controller.password=envoy-password\n```\nwhere envoy-ip is the ip address of your envoy controller\nand envoy-password is likely to be the last 6 characters of your envoy controller serial number\n\nExample #3 run spring boot locally with debugger support connecting to enphase to pull down a token\n```\nmvn spring-boot:run -Dspring-boot.run.arguments=\"--envoy.controller.host=\u003cPRIVATE IP OF ENVOY\u003e --envoy.controller.port=443 --envoy.enphaseWebUser=\u003cUSER\u003e --envoy.enphaseWebPassword=\u003cPASSWORD\u003e\" -Dspring-boot.run.jvmArguments=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005\"\n```\n\nIf using the docker image\n\nExample #1 using influxDB for storage\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-e ENVOY_INFLUXDBRESOURCE_HOST=influxdb-ip \\\n-e ENVOY_INFLUXDBRESOURCE_PORT=influxdb-port \\\n-e SPRING_PROFILES_ACTIVE=influxdb \\\ndlmcpaul/enphasecollector\n```\nwhere envoy-password is likely to be the last 6 characters of your envoy controller serial number\n\nExample #2 in standalone mode with internal database storage\n\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-p 8080:8080 \\\ndlmcpaul/enphasecollector\n```\nand a web page available at http://localhost:8080/solar and looks like [this](https://dlmcpaul.github.io/EnphaseCollector \"this\")\n\nYou can also link the internal database to an external file system, so the database kept on upgrade of the image using the mount point /internal_db\n\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-p 8080:8080 \\\n--mount target=/internal_db,source=host_path\ndlmcpaul/enphasecollector\n```\nand replace host_path with the path on your host machine where you want to store the data.\n\nExample #3 sending data to pvoutput.\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-e ENVOY_PVOUTPUTRESOURCE_SYSTEMID=your-system-id \\\n-e ENVOY_PVOUTPUTRESOURCE_KEY=your-key \\\n-e SPRING_PROFILES_ACTIVE=pvoutput \\\ndlmcpaul/enphasecollector\n```\nYour timezone is something like Australia/Sydney or similar\n\nExample #4 sending data to mqtt.\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-e ENVOY_MQQTRESOURCE_HOST=mqqt-ip \\\n-e ENVOY_MQQTRESOURCE_PORT=mqqt-port \\\n-e ENVOY_MQQTRESOURCE_TOPIC=topic-name \\\n-e ENVOY_MQQTRESOURCE_PUBLISHERID=publisher-id \\\n-e SPRING_PROFILES_ACTIVE=mqtt \\\ndlmcpaul/enphasecollector\n```\n\nif ENVOY_MQQTRESOURCE_PUBLISHERID is not provided a random value will be chosen\n\nNote the spelling mistake in the environment variables (MQQT instead of MQTT) This will likely be fixed in a later release\n\nAvailable environment variables descriptions:\n\n- ENVOY_CONTROLLER_HOST           Set to your Envoy Controller IP Address if envoy.local cannot be found (usually if run in Docker)\n- ENVOY_CONTROLLER_USER           Set if the default user is not \"envoy\"\n- ENVOY_CONTROLLER_PASSWORD       Set to your Envoy Controller password if you have changed it from the default\n- ENVOY_INFLUXDBRESOURCE_HOST     Set to your Influx Database IP Address\n- ENVOY_INFLUXDBRESOURCE_PORT     Set to your Influx Database Port No\n- ENVOY_INFLUXDBRESOURCE_USER     Set if your Influx Database needs a user/password\n- ENVOY_INFLUXDBRESOURCE_PASSWORD Set if your Influx Database needs a user/password\n- ENVOY_PVOUTPUTRESOURCE_SYSTEMID Set to your pvoutput systemid\n- ENVOY_PVOUTPUTRESOURCE_KEY      Set to your pvoutput key\n- ENVOY_MQQTRESOURCE_HOST         Set to your MQTT Server IP Address\n- ENVOY_MQQTRESOURCE_PORT         Set to your MQTT Server Port No\n- ENVOY_MQQTRESOURCE_TOPIC        Set to the MQTT topic you want to write to \n- ENVOY_MQQTRESOURCE_PUBLISHERID  Set to the MQTT publisher id you want to use\n- SPRING_PROFILES_ACTIVE          Determines destination for stats.  If not set only an internal database gets the stats.  Values can be influxdb, pvoutput, mqtt\n- ENVOY_REFRESHSECONDS            How often to poll the Envoy Controller.  Default 60s\n- ENVOY_PAYMENTPERKILOWATT        How much you get paid to export power to grid (FIT) eg 0.125 is 12.5c/Kw\n- ENVOY_CHARGEPERKILOWATT         How much it costs to buy from the grid eg 0.32285 is 32.285c/Kw\n- ENVOY_DAILYSUPPLYCHARGE         How much it costs to access the grid every day eg 0.93 is 93c/day\n- SERVER_SERVLET_CONTEXT-PATH     Context path for local view if you want it on something other than /solar\n\n### V7 support\nEither supply\n- ENVOY_BEARERTOKEN               Set this if you want to control the token refresh process and not supply your website user/password\n\nOr if you want auto refresh\n\n- ENVOY_ENPHASEWEBUSER            Set this to your enphase website user id\n- ENVOY_ENPHASEWEBPASSWORD        Set this to your enphase website password\n\n### New configuration\n\n- ENVOY_EXPORT-LIMIT              If you have a limit on your export this will display a upper boundary on the main graph and display a new excess production line\n- ENVOY_BANDS[].FROM              The bands array configuration will add a shaded band to the main graph that you can use to highlight changes to import costs and the like (See example below)\n- ENVOY_BANDS[].TO                From and To are start and end times in 24hr format (must include a leading 0 eg 0700)\n- ENVOY_BANDS[].COLOUR            The Colour field can be formatted like #55BF3B or rgba(200, 60, 60, .2)\n\n### External Configuration file\nThe easiest way to configure the bands is with an external configuration file\n\n- Create a file called application.properties containing values like the following (defining 2 bands 8am-12pm \u0026 4pm-6pm)\n```\nenvoy.bands[0].from = 0800\nenvoy.bands[0].to = 1200\nenvoy.bands[0].colour = #55BF3B\nenvoy.bands[1].from = 1600\nenvoy.bands[1].to = 1800\nenvoy.bands[1].colour = rgba(200, 60, 60, .2)\n```\n- Pass the file to the jar using the spring.config.additional-location parameter\n\n```\njava -jar enphasecollector.jar --spring.config.additional-location=file:application.properties\n```\n\nAll properties can be configured this way and will override any defaults set in the jar.  Check the application.properties file for more properties that can be set\n\nFor Docker you will need a local directory to hold the file\n\n```\ndocker run \\\n-e TZ=your-timezone \\\n-e ENVOY_CONTROLLER_PASSWORD=envoy-password \\\n-e ENVOY_CONTROLLER_HOST=envoy-ip \\\n-p 8080:8080 \\\n--mount target=/internal_db,source=host_path\n--mount target=/properties,source=host_path\ndlmcpaul/enphasecollector\n```\n\n## Exposing this application to the web\nWhile I make every effort to make this application secure I cannot make any guarantees.  The application should be hosted behind a firewall and only exposed through a reverse proxy which includes an authentication mechanism and utilises https.\n\n## Dependencies\n- Docker (or Java 21)\n\n- If profile set to influxdb then an \nInflux DB is needed for storage of the statistics (Will autocreate 2 databases called 'solardb' and 'collectorStats')\n\n- If profile set to pvoutput then every 5m the stats will be uploaded to your account at https://pvoutput.org (you will need to create an account to to get the systemid and key)\n\n- You can set multiple profiles separated by a comma eg influxdb,pvoutput\n\n- The internal database is always populated so the local view is always available at /solar\n- Stats can be pulled to Prometheus by using the Actuator endpoint configured at /solar/actuator/prometheus\n- Stats can be pushed to a mqtt server with the mqtt profile (requires mqtt server)\n\n## Building for yourself\nThis is a fairly standard maven project using spring boot so ```mvn package -Dmaven.test.skip``` should get your started and can build a working jar located in the target directory\n\nYou will need the following tools installed to develop and build this code.\n- Git to clone the code and commit changes\n- Java 21 to compile the code\n- Maven to manage the build process\n- Docker to support the testing\n\nThere are also modules built in if you want to store the data somewhere other than the internal database.  To use them you will need an installation or authentication for the specific system:\n- InfluxDB 1.8\n- PvOutput system id and key\n- Prometheus\n- Mqtt Server\n\n**There are some caveats**\n- The build will generate a jar with a default version of unreleased\n\n### Docker Images\n- You can use the spring boot plugin build-image to generate a docker image that works but does not export a properties file location you can use\n- I also have a number of dockerfiles I use for my releases and experimentation.  I have documented them under [DOCKER.md](https://github.com/dlmcpaul/EnphaseCollector/blob/master/DOCKER.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlmcpaul%2Fenphasecollector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdlmcpaul%2Fenphasecollector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlmcpaul%2Fenphasecollector/lists"}