{"id":18098513,"url":"https://github.com/danieloneill/epsolarserver","last_synced_at":"2025-04-13T12:44:27.871Z","repository":{"id":89578017,"uuid":"94060649","full_name":"danieloneill/EpsolarServer","owner":"danieloneill","description":"Epsolar Tracer-series logging/monitoring for Linux (and Raspberry Pi)","archived":false,"fork":false,"pushed_at":"2020-05-11T21:43:53.000Z","size":207,"stargazers_count":31,"open_issues_count":5,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-27T03:51:13.564Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danieloneill.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":"2017-06-12T06:04:32.000Z","updated_at":"2024-01-04T14:59:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"05bed8cb-be2e-4442-801c-ef266c09bdd7","html_url":"https://github.com/danieloneill/EpsolarServer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieloneill%2FEpsolarServer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieloneill%2FEpsolarServer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieloneill%2FEpsolarServer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieloneill%2FEpsolarServer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danieloneill","download_url":"https://codeload.github.com/danieloneill/EpsolarServer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717241,"owners_count":21150387,"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":[],"created_at":"2024-10-31T20:11:34.803Z","updated_at":"2025-04-13T12:44:27.817Z","avatar_url":"https://github.com/danieloneill.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tracer series RS485/MODBUS monitoring software for Linux (and Raspberry Pi I guess)\n\n![Screenshot of EpsolarServer's web view](http://i.imgur.com/LQi7Q6S.png)\n\nYou'll need a few things to build this:\n* Linux\n* Qt 5.5+ (\"qtbase5-dev\", \"qt5-qmake\", \"libqt5sql5\", \"qt5-default\", and probably \"libqt5sql5-mysql\")\n* MySQL/Mariadb (\"mysql-client\", \"mysql-server\")\n\nIf you want to monitor your stats with the integrated websocket server: *(If you skip this, the web interface won't work!)*\n* QtWebsockets (\"libqt5websockets5-dev\")\n\nIf you want to use libmodbus (probably Yes if on a raspberry pi):\n* libmodbus5\n* libmodbus-dev\n\nCredit to: zlib.js, graph.js, qhttpserver, and the listed software above.\n\n## Building\n\nIf you want to use the integrated web server, you must build and install \"qhttpserver\" located in \"3rdparty/\" first. You need the Qt dependencies mentioned above, but otherwise just \"qmake\", \"make\", and \"make install\" this.\n\n    You may experience a problem with qhttpserver where it requires a file called *safequeue.h* to be copied manually to **/usr/local/include/**. It's located at **3rdparty/qhttpserver/src/safequeue.h**.\n\nIf you don't want to use the integrated web server, install the webserver of your choice and copy all the files in \"www/\" to your web server document root.\n\nTo set build options, see the top options in \"EpsolarServer.pro\".\n\nBuild by running \"qmake\", then \"make\".\n\n## Setup\n\nTo setup the database, import the schema using \"mysql -uroot \u003c dist/mysql_schema.sql\"\n\nTo configure, copy \"dist/epsolarServer.conf\" to \"/etc/\" and edit the copy.\n\nThe meanings are as follows:\n\n```\ndatabaseType: Can be QMYSQL, QPGSQL, QSQLITE, and so on, but only QMYSQL is tested or known to work.\ndatabaseName: The database name\ndatabaseHostname: The database hostname\ndatabaseUsername: The database account username\ndatabasePassword: The database account password (if any)\nepsolarDevicePath: The file path to your RS485 adapter character device node (usually /dev/ttyBLAHBLAH0 or something)\nepsolarPollFrequencyMS: How long the should server pause between reading registers in milliseconds. I suggest no less than 20 here.\n```\n\nTo start the software when your system boots up, edit \"epsolar.init\" and copy it to \"/etc/init.d/epsolar\". Then run \"update-rc.d epsolar defaults\".\n\n## Running\n\n### Web Interface\nOnce running, you can see your graph start to populate by pointing your HTML5 compliant web browser to:\n\n*http://(host address):8080/*\n\nThe top graph lays out 5-minute averages. The bottom graph lays out hourly averages.\n\nAny gaps of white in the graph indicate that the EpsolarServer program wasn't running for that period, such as a power outage or battery bank maintenance, or the disk is full and no additional records can be saved.\n\n### Websocket\nIf you aren't interested at all in the web interface, you can interact with the websocket interface as follows:\n\n*ws://(host address):7175/*\n\nThe server expects JSON formatted requests as text frames, and responds with gzipped JSON responses as binary frames or plain-text JSON depending on if compression is enabled on the connection.\n\nSpecifying \"compress\" with either a true or false value will enable or disable GZip compression on ALL subsequent responses, until it is specified in a new request.\n\nValid requests:\n\n* Averages: **5-minute average records** which are compressed into hourly averages once 24-hours old.\n```\n\tRequest:\n\t{\n                'action': 'averages',\n                'from': \u003cint, earliest timestamped record to fetch, in unix epoch milliseconds\u003e,\n                'to': \u003cint, latest timestamped record to fetch, in unix epoch milliseconds\u003e,\n                'count': \u003cint, how many records to fetch\u003e,\n                'register': \u003cint, register ID\u003e,\n\t\t'compress': \u003ctrue/false, for GZip compressed responses\u003e\n        }\n\n\tResponse:\n\t{\n\t\t\"data\": {\n\t\t\t\"Charge watts\": [\n\t\t\t\t{\n\t\t\t\t\t\"avg\": 0,\n\t\t\t\t\t\"end\": 1497160419000,\n\t\t\t\t\t\"max\": 0,\n\t\t\t\t\t\"min\": 0,\n\t\t\t\t\t\"start\": 1497160119000\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"avg\": 0,\n\t\t\t\t\t\"end\": 1497160720000,\n\t\t\t\t\t\"max\": 0,\n\t\t\t\t\t\"min\": 0,\n\t\t\t\t\t\"start\": 1497160419000\n\t\t\t\t},\n\t\t\t\t...\n\t\t\t]\n\t\t},\n\t\t\"type\": \"averages\"\n\t}\n```\n\n* Hourlies: **60-minute average records** which will accrue ad-infinitum.\n```\n\tRequest:\n\t{\n                'action': 'hourly',\n                'from': \u003cint, earliest timestamped record to fetch, in unix epoch milliseconds\u003e,\n                'to': \u003cint, latest timestamped record to fetch, in unix epoch milliseconds\u003e,\n                'count': \u003cint, how many records to fetch\u003e,\n                'register': \u003cint, register ID\u003e,\n\t\t'compress': \u003ctrue/false, for GZip compressed responses\u003e\n        }\n\n\tResponse (example):\n\t{\n\t\t\"data\": {\n\t\t\t\"Load voltage\": [\n\t\t\t\t{\n\t\t\t\t\t\"avg\": 13.859999999999999,\n\t\t\t\t\t\"date\": \"2017-06-05\",\n\t\t\t\t\t\"hour\": 19,\n\t\t\t\t\t\"max\": 13.970000000000001,\n\t\t\t\t\t\"min\": 13.779999999999999\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"avg\": 13.9,\n\t\t\t\t\t\"date\": \"2017-06-05\",\n\t\t\t\t\t\"hour\": 20,\n\t\t\t\t\t\"max\": 14.220000000000001,\n\t\t\t\t\t\"min\": 13.529999999999999\n\t\t\t\t},\n\t\t\t\t...\n\t\t\t]\n \t\t},\n\t\t\"type\": \"hourly\"\n\t}\n```\n\n* Subscribe: **Records sent every (register count x epsolarPollFrequencyMS)ms interval** This is effectively real-time readings.\n```\n\tRequest:\n\t{\n\t\t'action': 'subscribe',\n\t\t'compress': \u003ctrue/false, for GZip compressed responses\u003e,\n\t\t'subscribe': \u003ctrue/false, true to subscribe, false to unsubscribe\u003e\n\t}\n\n\tResponse (example):\n\t{\n\t\t\"type\": \"reading\",\n\t\t\"data\": {\n\t\t\t\"Battery SOC\": 29,\n\t\t\t\"Battery status\": 0,\n\t\t\t\"Battery temperature\": 12,\n\t\t\t\"CO2 reduction\": 400,\n\t\t\t\"Charge controller status\": 1,\n\t\t\t\"Charge current\": 0,\n\t\t\t\"Charge voltage\": 1.4099999999999999,\n\t\t\t\"Charge watts\": 0,\n\t\t\t\"Consumed energy today\": 0,\n\t\t\t\"Generated energy today\": 700,\n\t\t\t\"Generated energy total\": 47,\n\t\t\t\"Load current\": 0,\n\t\t\t\"Load voltage\": 12.83,\n\t\t\t\"Load watts\": 0\n\t\t}\n\t}\n\t... etc ... it never stops ...\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieloneill%2Fepsolarserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanieloneill%2Fepsolarserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieloneill%2Fepsolarserver/lists"}