dlmcpaul / enphasecollector Goto Github PK
View Code? Open in Web Editor NEWEnphase Solar Metrics Collector
License: Mozilla Public License 2.0
Enphase Solar Metrics Collector
License: Mozilla Public License 2.0
It would be good to auto select HTTPS for enphase devices running the V7 firmware but allow downgrade if required.
Might be difficult since we don't know the version until we fetch the info.xml file.
Maybe try with passed in values and if failure retry with HTTPS?
Hi all,
Been a user of the project for years so very appreciative of the team here!
My envoy got upgraded and I finally got the authentication via token working. I am now getting the following I/O error on GET request. Help anyone?
Thanks in advance.
Richard
2023-07-10T07:03:17.808Z INFO 8 --- [ scheduling-1] com.hz.services.EnvoyConnectionProxy : Preparing Realm Authentication Provider with user envoy
2023-07-10T07:03:17.813Z INFO 8 --- [ main] com.hz.EnphaseCollectorApplication : Started EnphaseCollectorApplication in 19.629 seconds (process
running for 20.706)
2023-07-10T07:03:17.826Z INFO 8 --- [ scheduling-1] com.hz.services.EnvoyConnectionProxy : Reading from protected Envoy controller endpoint http://envoy.l
ocal/api/v1/production/inverters
2023-07-10T07:03:18.427Z INFO 8 --- [ scheduling-1] o.a.h.c.h.i.c.HttpRequestRetryExec : Recoverable I/O exception (java.net.UnknownHostException) caugh
t when processing request to {}->http://envoy.local:80
2023-07-10T07:03:18.429Z INFO 8 --- [ scheduling-1] o.a.h.c.h.i.c.HttpRequestRetryExec : Recoverable I/O exception (java.net.UnknownHostException) caugh
t when processing request to {}->http://envoy.local:80
**_**2023-07-10T07:03:18.432Z ERROR 8 --- [ scheduling-1] com.hz.services.EnvoyService : Failed to retrieve Solar stats. Exception was I/O error on GET
request for "http://envoy.local/home.json": envoy.local
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://envoy.local/home.json": envoy.local**_**
at org.springframework.web.client.RestTemplate.createResourceAccessException(RestTemplate.java:888) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:868) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:764) ~[spring-web-6.0.8.jar:6.0.8]
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:405) ~[spring-web-6.0.8.jar:6.0.8]
at com.hz.services.EnvoyService.getSystemData(EnvoyService.java:46) ~[app/:na]
at com.hz.services.EnvoyService.collectEnphaseData(EnvoyService.java:57) ~[app/:na]
at com.hz.services.OutputManager.gather(OutputManager.java:47) ~[app/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-6.0.8.jar:6.0.8]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-6.0.8.jar:6.0.8]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.net.UnknownHostException: envoy.local
at java.base/java.net.InetAddress$CachedAddresses.get(InetAddress.java:801) ~[na:na]
at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1533) ~[na:na]
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1385) ~[na:na]
The codebase has code to get the battery info, for instance: https://github.com/dlmcpaul/EnphaseCollector/blob/master/src/main/java/com/hz/models/envoy/json/Production.java#L42
However, none of it shows up in the database.
Is this an incomplete feature or a bug?
Thanks David for such a great app.
I would like to run EnphaseCollector on an android device but am unsure if this is possible? Any tips would be much appreciated.
Not an issue, just a question.
great tool. Thanks for sharing. Quick question regarding the data streams /stream/meter. This needs the installer username and the password (to access via digest/browser). How does EnphaseCollector access this stream without the password? I dug through the code but i could not find anything obvious how this is achieved and I cannot see a good place to provide this information (e.g. main/resources/application.properties).
Thanks,
Pete.
Would be good to publish PV generation, consumption, grid import, grid export to MQTT so other smart devices like openevse can adjust the car charge current to only use the excess generation to charge the car.
Example code:
https://github.com/vk2him/Enphase-Envoy-mqtt-json/blob/main/envoy_to_mqtt_json.py
https://github.com/OpenEVSE/Solar_MQTT/blob/main/Tesla%20Energy%20Gateway/Tesla_Energy_Gateway_mqtt.py
This looks like a great project and I'd like to use it with my enphase system.
But no docker on my device.
Any hints on how to run on a native JRE? mvn install doesn't work.
You can see my setup here: https://dev1.eriklentz.com/solar/
I'm running the Java version of the collector on Debian Linux.
I stopped the collector, added this flag to my run command to change from the default polling interval: --envoy.refreshseconds=15000
Then started the collector again. As far as what I intended to accomplish, it works, it now polls more often.
However, the graph still displays the collected data, but most of the text fields on the right are empty and all historical data cannot be displayed.
Reverting to the default polling interval does not appear to correct the issue. Has the internal database become corrupted? How can I restore functionality?
I'd love to get this connected to my MQTT setup but I'm having a hard time locating the syntax for passing mqtt configuration parameters (mqtt host, username, pass, topic, etc).
Can anyone please point me in the right direction?
Would you consider adding an endpoint to expose the data in Prometheus format?
Thanks!
I set up using local database only, and the GUI looks to work just fine on live view, but when I click 'history' it doesn't switch to that tab.
There are different libraries needed to support Influx DB <= 1.8 and Influx DB >= 2
Can we support both?
❯ docker build -f Dockerfile-build .
[+] Building 0.1s (2/2) FINISHED
=> [internal] load build definition from Dockerfile-build 0.0s
=> => transferring dockerfile: 1.98kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
failed to solve with frontend dockerfile.v0: failed to create LLB definition: dockerfile parse error line 27: unknown instruction: IF
I have two systems in my house: an older style system and a newer style. With the newer style this seems to work fine. With the older style I get multiple failures on startup.
The older style system has the oval shaped powerline communication box "Envoy".
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type int
from String "0.36": not a valid Integer value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type int
from String "0.36": not a valid Integer value
The app requirements for database is simple and hibernate just seems to keep doing things I don't want it to.
Hi thanks for publishing. The tool looks like it could be very useful. I downloaded enphasecollector-0.22.jar & latest Java 11 from adoptopenjdk.net. Launch gets as far as this message:
ERROR 38852 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
-and then a long stack dump - the 1st few lines are pasted below. (full trace enclosed). I’m able to reach the envoy locally & see stats. I tried running both with & without explicitly setting address/password. The 6-digit password works fine manually. I wondered if the new Java engine is battling with previous installation? I have this variable set:
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
Any suggestions are much appreciated.
org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: null. Possible solutions: close all other connection(s); use the server mode [90020-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) ~[h2-1.4.200.jar!/:na]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar!/:na]
at org.h2.message.DbException.get(DbException.java:194) ~[h2-1.4.200.jar!/:na]
at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:206) ~[h2-1.4.200.jar!/:na]
Reviewing some of the codebase in EnphaseCollector enabled me to build this.... https://github.com/LelandSindt/analoguEnvoy
on latest version of influx i get:
enphaseCollector | 2022-08-30 00:21:34.814 INFO 1 --- [ main] com.hz.configuration.InfluxDBConfig : Writing solar stats to influx database at http://db:8086
enphaseCollector | 2022-08-30 00:21:35.093 WARN 1 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'influxService' defined in file [/app/com/hz/services/InfluxService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'destinationInfluxDB' defined in class path resource [com/hz/configuration/InfluxDBConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.influxdb.InfluxDB]: Factory method 'destinationInfluxDB' threw exception; nested exception is org.influxdb.InfluxDBException: {"code":"unauthorized","message":"unauthorized access"}
enphaseCollector | 2022-08-30 00:21:35.096 INFO 1 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
enphaseCollector | 2022-08-30 00:21:35.103 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
enphaseCollector | 2022-08-30 00:21:35.143 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
enphaseCollector | 2022-08-30 00:21:35.212 ERROR 1 --- [ main] i.micrometer.influx.InfluxMeterRegistry : unable to create database 'collectorStats': {"code":"unauthorized","message":"unauthorized access"}
enphaseCollector | 2022-08-30 00:21:35.293 ERROR 1 --- [ main] i.micrometer.influx.InfluxMeterRegistry : failed to send metrics to influx: {"code":"unauthorized","message":"unauthorized access"}
enphaseCollector | 2022-08-30 00:21:35.310 ERROR 1 --- [ main] i.micrometer.influx.InfluxMeterRegistry : unable to create database 'collectorStats': {"code":"unauthorized","message":"unauthorized access"}
enphaseCollector | 2022-08-30 00:21:35.337 ERROR 1 --- [ main] i.micrometer.influx.InfluxMeterRegistry : failed to send metrics to influx: {"code":"unauthorized","message":"unauthorized access"}
enphaseCollector | 2022-08-30 00:21:35.340 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
enphaseCollector | 2022-08-30 00:21:35.385 INFO 1 --- [ main] ConditionEvaluationReportLoggingListener :
Trying to use influx 1.8, Error i'm receiving is:
enphaseCollector | 2022-08-30 00:30:21.515 WARN 1 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23505, SQLState: 23505 enphaseCollector | 2022-08-30 00:30:21.516 ERROR 1 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "PUBLIC.UK_ESIJSR1QSXCG3GCQ4AF42OF09_INDEX_5 ON PUBLIC.EVENT_PANELS(PANELS_ID) VALUES 41"; SQL statement: enphaseCollector | insert into event_panels (event_id, panels_id) values (?, ?) [23505-200] enphaseCollector | 2022-08-30 00:30:21.517 INFO 1 --- [nio-8080-exec-9] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements enphaseCollector | 2022-08-30 00:30:21.525 ERROR 1 --- [nio-8080-exec-9] com.hz.controllers.EnphaseController : populateMultiStatsStatusList Exception: could not execute statement; SQL [n/a]; constraint ["PUBLIC.UK_ESIJSR1QSXCG3GCQ4AF42OF09_INDEX_5 ON PUBLIC.EVENT_PANELS(PANELS_ID) VALUES 41"; SQL statement: enphaseCollector | insert into event_panels (event_id, panels_id) values (?, ?) [23505-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement enphaseCollector | enphaseCollector | org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["PUBLIC.UK_ESIJSR1QSXCG3GCQ4AF42OF09_INDEX_5 ON PUBLIC.EVENT_PANELS(PANELS_ID) VALUES 41"; SQL statement: enphaseCollector | insert into event_panels (event_id, panels_id) values (?, ?) [23505-200]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement enphaseCollector | at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276) ~[spring-orm-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233) ~[spring-orm-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566) ~[spring-orm-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.21.jar:5.3.21] enphaseCollector | at com.hz.services.LocalDBService$$EnhancerBySpringCGLIB$$be5d2602.getMaxPanelProduction(<generated>) ~[app/:na] enphaseCollector | at com.hz.controllers.EnphaseController.populateMultiStatsStatusList(EnphaseController.java:80) ~[app/:na] enphaseCollector | at com.hz.controllers.EnphaseController.populateStatusList(EnphaseController.java:100) ~[app/:na] enphaseCollector | at com.hz.controllers.EnphaseController.status(EnphaseController.java:149) ~[app/:na] enphaseCollector | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] enphaseCollector | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] enphaseCollector | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] enphaseCollector | at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] enphaseCollector | at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.64.jar:4.0.FR] enphaseCollector | at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.64.jar:4.0.FR] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at com.hz.controllers.filters.SecurityHeaderFilter.doFilter(SecurityHeaderFilter.java:25) ~[app/:na] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:67) ~[spring-webmvc-5.3.21.jar:5.3.21] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.6.9.jar:2.6.9] enphaseCollector | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1787) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.64.jar:9.0.64] enphaseCollector | at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] enphaseCollector | Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement enphaseCollector | at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:37) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1352) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:84) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] enphaseCollector | at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:489) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3290) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2425) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.21.jar:5.3.21] enphaseCollector | ... 72 common frames omitted enphaseCollector | Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_ESIJSR1QSXCG3GCQ4AF42OF09_INDEX_5 ON PUBLIC.EVENT_PANELS(PANELS_ID) VALUES 41"; SQL statement: enphaseCollector | insert into event_panels (event_id, panels_id) values (?, ?) [23505-200] enphaseCollector | at org.h2.message.DbException.getJdbcSQLException(DbException.java:459) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.message.DbException.get(DbException.java:205) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.message.DbException.get(DbException.java:181) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:103) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.mvstore.db.MVSecondaryIndex.checkUnique(MVSecondaryIndex.java:221) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:196) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.mvstore.db.MVTable.addRow(MVTable.java:531) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.command.dml.Insert.insertRows(Insert.java:195) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.command.dml.Insert.update(Insert.java:151) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.command.CommandContainer.update(CommandContainer.java:198) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.command.Command.executeUpdate(Command.java:251) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:191) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:152) ~[h2-1.4.200.jar:1.4.200] enphaseCollector | at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-4.0.3.jar:na] enphaseCollector | at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na] enphaseCollector | at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.6.9.Final.jar:5.6.9.Final] enphaseCollector | ... 92 common frames omitted enphaseCollector |
Kia ora,
I had to restart my Raspberry Pi after a power cut, and despite using an InfluxDB the stats are missing. So are some of the stats on the right-hand side.
This is the command I am using to kick it off:
docker run -it
-e TZ=Pacific/Auckland
-e ENVOY_CONTROLLER_PASSWORD=passwordishere
-e ENVOY_CONTROLLER_HOST=envoy.ip.is.here
-e ENVOY_INFLUXDBRESOURCE_HOST=host.ip.is.here
-e ENVOY_INFLUXDBRESOURCE_PORT=8086
-e SPRING_PROFILES_ACTIVE=influxdb
-e ENVOY_REFRESHSECONDS=5000
-e ENVOY_PAYMENTPERKILOWATT=0.05
-e ENVOY_CHARGEPERKILOWATT=0.16
-e ENVOY_DAILYSUPPLYCHARGE=2.30
dlmcpaul/enphasecollector:arm
Is there something I am missing? I can see the InfluxDBs have some data in them, but it looks like it didn't read it back in.
Up until now it's been running sweet as a nut!
Thanks heaps
Looks like you've made a lot of improvement lately. It would be great if you push a new release and update the dockerhub image so we could get all the new goodies :)
It would be super helpful if you could update the README.md
with the instructions on how to build/test/run this locally.
Some people, like me, have never used springboot or maven, so it would be very helpful if you could give quick step by step instructions on how I can build and run this locally.
Thank you!
I downloaded Docker Desktop 4.12.0 on PC just to run this collector, did docker build, it goes through quite a way but then gets an error:
[builder 4/4] RUN "/usr/lib/jvm/zulu17-ca/bin/jar" -xf app.jar:
#10 0.770 java.io.FileNotFoundException: app.jar (Is a directory)
Anyone know how to get past this?
I'm not sure if some math is being preformed but when there is another inverter in the system and enphase is only part of the PV production, when I am exporting power back to grid, the consumption is the total of the export + enphase PV generation which makes consumption way too high. I don't know how to work around this but maybe an option just to show Net Grid import/export instead of trying to show consumption.
Kia ora,
I love your visualiser software. We have it proudly displayed in the kitchen and it's much remarked upon by visitors to our house! It frequently prompts us to ask "why are we using so much power?" and go looking for the offending appliance. It also prompts us to do something with the power once the hot water has finished heating. Awsome stuff!
Our power company is offering us on-peak and off-peak rates for our power at very set times of the day. I wondered how easy it would be add some background colour to the production/consumption graph to show these times (and prompt us to avoid them for high power use appliances). Is this a couple of lines or a complete re-write?
Thanks again for your awesome software, and please ignore this if it's a cheeky thing to ask :-)
Karl
This is the best plug-and-play program to gather data from Envoy. I'm using the docker container and it works like a champ!
Do you think you could share your Grafana dashboard? I saw it on whitpool.net.au and it looks wonderfully.
Thank you so much!
I get this error suddenly from the docker container running Enphasecollector. The container still answers with prometheus data the "important to me" solar data is missing. i.e. "solar_meter_production_watts" is not in the collector output then this error is happening.
`2023-09-05T08:51:45.053-07:00 ERROR 7 --- [ scheduling-1] com.hz.services.EnvoyService : Failed to retrieve Solar stats. Exception was Unrecognized field "system_id" (class com.hz.models.envoy.LogInResponse), not marked as ignorable (4 known properties: "is_consumer", "session_id", "message", "manager_token"])
at [Source: (String)"{"message":"success","session_id":"3086e4bae322887a5a1efdc613c20270","manager_token":"eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InNlc3Npb25faWQiOiIzMDg2ZTRiYWUzMjI4ODdhNWExZWZkYzYxM2MyMDI3MCIsImNvbXBhbnlfaWQiOm51bGwsImVtYWlsX2lkIjoibWlzY0ByZXRsYXcubmV0IiwidXNlcl9pZCI6MjM5MjQ5MCwiY2xpZW50X2FwcCI6Iml0azMiLCJmaXJzdF9uYW1lIjoiSmFtZXMiLCJsYXN0X25hbWUiOiJTdXRoZXJsYW5kIiwibG9naW5fdXNlciI6bnVsbCwiaXNfZGlzdHJpYnV0b3IiOmZhbHNlfSwiZXhwIjoxNjk0NTMzOTA0LCJzdWIiOiJtaXNjQHJldGxhdy5uZXQifQ.aU_flbzO9FodCzfLr8xXcUwVY30r8K"[truncated 54 chars]; line: 1, column: 554] (through reference chain: com.hz.models.envoy.LogInResponse["system_id"])
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "system_id" (class com.hz.models.envoy.LogInResponse), not marked as ignorable (4 known properties: "is_consumer", "session_id", "message", "manager_token"])
at [Source: (String)"{"message":"success","session_id":"3086e4bae322887a5a1efdc613c20270","manager_token":"eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InNlc3Npb25faWQiOiIzMDg2ZTRiYWUzMjI4ODdhNWExZWZkYzYxM2MyMDI3MCIsImNvbXBhbnlfaWQiOm51bGwsImVtYWlsX2lkIjoibWlzY0ByZXRsYXcubmV0IiwidXNlcl9pZCI6MjM5MjQ5MCwiY2xpZW50X2FwcCI6Iml0azMiLCJmaXJzdF9uYW1lIjoiSmFtZXMiLCJsYXN0X25hbWUiOiJTdXRoZXJsYW5kIiwibG9naW5fdXNlciI6bnVsbCwiaXNfZGlzdHJpYnV0b3IiOmZhbHNlfSwiZXhwIjoxNjk0NTMzOTA0LCJzdWIiOiJtaXNjQHJldGxhdy5uZXQifQ.aU_flbzO9FodCzfLr8xXcUwVY30r8K"[truncated 54 chars]; line: 1, column: 554] (through reference chain: com.hz.models.envoy.LogInResponse["system_id"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1132) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2202) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1705) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1683) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:320) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4730) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3677) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3645) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.hz.utils.EnphaseJWTExtractor.postLogin(EnphaseJWTExtractor.java:79) ~[app/:na]
at com.hz.utils.EnphaseJWTExtractor.fetchJWTV2(EnphaseJWTExtractor.java:165) ~[app/:na]
at com.hz.services.EnvoyConnectionProxy.getSecureTemplate(EnvoyConnectionProxy.java:145) ~[app/:na]
at com.hz.services.EnvoyService.getSystemData(EnvoyService.java:46) ~[app/:na]
at com.hz.services.EnvoyService.collectEnphaseData(EnvoyService.java:57) ~[app/:na]
at com.hz.services.OutputManager.gather(OutputManager.java:47) ~[app/:na]
at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-6.0.8.jar:6.0.8]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-6.0.8.jar:6.0.8]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]`
The internal web site uses a single electricity.jpg image for several info lines.
I welcome contributions of images so each info has it's own graphic.
Hi David,
Firstly: thanks for providing this on github! this is very good and well done.
Now, I'm creating this issue because when viewing the resulting page on a mobile, the graph just does not work.
I gave a try at fixing it, but I'm really bad at frontend and got nowhere ...
If you have time for this, I'd really appreciate help ;)
Hello! We've just installed our solar setup and I'd love to have a permanent display running in our kitchen. Your app would be utterly perfect (it's is way better than what comes with the envoy!)
I got it working on my laptop but have been unsuccessful getting it to run on a Pi 4. I installed docker and docker-compose, but when I use docker-compose up
I just get exec user process caused "exec format error"
Is it possible to run this on a Pi?
Thanks heaps
H2 database used is V1.
To upgrade to later Spring boot versions then H2 needs to migrate to V2
There is no auto-upgrade. Database requires an export using V1 library and import using V2 library
i've tried the docker commandline and add parameters for connection to a MQTT server, unfortunately in my MQTT server i don't see a new topic appearing ?
docker run --rm -e TZ=Europe/Amsterdam
-e ENVOY_BEARER_TOKEN=xxx
-e ENVOY_CONTROLLER_HOST=192.168.110.80
-e ENVOY_MQTTRESOURCE_HOST=192.168.110.250
-e ENVOY_MQTTRESOURCE_PORT=1883
-e ENVOY_MQTTRESOURCE_TOPIC=enphase
-p 8080:8080
dlmcpaul/enphasecollector:latest
API Documentation can be found here
I noticed this project imports log4j. Would it be impacted by CVE-2021-44228?
I believe because of #55 the database might be little incomplete.
Does the solar.excess
measurement track the amount of power I'm sending back to the grid? Or does it measure a combination of what I give back to the grid and charge the battery with?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.