{"id":19889540,"url":"https://github.com/tsmx/obis-reader","last_synced_at":"2026-02-10T08:31:19.506Z","repository":{"id":42654647,"uuid":"246922538","full_name":"tsmx/obis-reader","owner":"tsmx","description":"NodeJS project for reading OBIS data from a smart-meter and storing them in a MongoDB. Including explanation on how to run on a Raspberry Pi.","archived":false,"fork":false,"pushed_at":"2025-01-28T19:24:33.000Z","size":753,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-28T20:28:30.289Z","etag":null,"topics":["mongodb","obis-data","raspberry-pi","smart-meter"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/tsmx.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":"2020-03-12T20:13:26.000Z","updated_at":"2025-01-28T19:24:37.000Z","dependencies_parsed_at":"2023-12-25T21:29:36.672Z","dependency_job_id":"f9eec510-b67c-4b7c-a42a-930671331a05","html_url":"https://github.com/tsmx/obis-reader","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/tsmx%2Fobis-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobis-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobis-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobis-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsmx","download_url":"https://codeload.github.com/tsmx/obis-reader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241317601,"owners_count":19943202,"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":["mongodb","obis-data","raspberry-pi","smart-meter"],"created_at":"2024-11-12T18:10:39.898Z","updated_at":"2026-02-10T08:31:19.408Z","avatar_url":"https://github.com/tsmx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# obis-reader\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/tsmx/obis-reader/git-build.yml?branch=master)](https://img.shields.io/github/actions/workflow/status/tsmx/obis-reader/git-build.yml?branch=master)\n[![Coverage Status](https://coveralls.io/repos/github/tsmx/obis-reader/badge.svg?branch=master)](https://coveralls.io/github/tsmx/obis-reader?branch=master)\n\n\u003e Read OBIS data from your smart-meter and store it in a MongoDB.\n\nA simple service for reading OBIS data from a smart-meter and saving it into a MongoDB. Including simple steps to ship the solution to a Raspberry Pi and make it run as a systemd service.\n\nOBIS data is read and extracted using the great package [smartmeter-obis](https://www.npmjs.com/package/smartmeter-obis).\n\nA live example of a simple dashboard with the persisted OBIS data can be found here: [PowerBoard](https://powerboard.appspot.com).\n\n## Technical Equipment\n\nWhat you need is:\n- a smart-meter with an interface providing measured data in the OBIS protocol (either push or pull), e.g. EMH ED300L\n- a optical (infrared) or other reader device connected to your smart-meter, e.g. a Read/Write IR optical connector with USB plug\n\n## Functionality\n\nIn this example the OBIS data is read into two entities stored in two different collections.\n\n- `obisActual` \n  - current power consumption\n  - typically read in a very short interval, e.g. every 3 seconds, specified by the configuration parameter `obis.requestInterval` (please consult the manual of your smart-meter for the lowest possible rates)\n  - stored for the last 24 hours in a sliding window (uses MongoDB's TTL index feature)\n- `obisValue`  \n  - current consumption and overall balance\n  - typically stored in a larger interval, e.g. every 5 minutes, specified by the configuration parameter `intervals.persistValuesMinutes`\n  - stored without any TTL limit\n\n## Configuration\n\nThe repo comes along with the following configuration files:\n\n```bash\nconf/\n├── config.js                     # small helper for logging out which config is loaded\n├── config.json                   # configuration for dev environment, reading OBIS data from a static file\n└── sample-config-production.json # configuration example for a production config, reading OBIS data from a USB device\n```\n\nWith the provided `config.json` you can start obis-reader and it will read OBIS data from the static file `test/ed300l.dat` without the need of having an OBIS device attached to your development machine. `sample-config-production.json` contains a production configuration blueprint for reading OBIS data from an USB device instead of a file.\n\nFor easy and secure configuration I use [secure-config](https://www.npmjs.com/package/@tsmx/secure-config) in this project. Different configurations can be used for testing/developing (NODE_ENV not set) and production (NODE_ENV === 'production') use. For that, edit/create two configuration files `config.json` and `config-production.json` under `/conf` following the given example files. It is recommended that you encrypt secret credentials like username and password for the database connection, at least for the production stage. For more details on how to use secure-config also refer to this [article](https://tsmx.net/secure-config/).\n\n\n**Hint:** Set `intervals.persistValuesMinutes` to `-1` in a development configuration to ignore this interval and always generate and store both - the `obisValue` and `obisActual` - when reading data.\n\n## Running on a Raspberry Pi\n\nTo run the OBIS reader on a Raspberry I suggest the following steps. \n\nNote that it is assumed to run in production mode on the Raspberry, thus we'll set the `NODE_ENV` environment variable accordingly and use `config-production.json` as the configuration file. So be sure to have this created and set-up properly.\n\n1. Connect to your Raspberry as `pi`.\n   ```bash\n   ssh pi@raspberrypi\n   ```\n2. Create a new user.\n   ```bash\n   sudo adduser obis\n   ```\n3. Grant the new user the right to read from the smartmeter connector. For most USB connected readers available under `/dev/ttyUSBx` this is done by adding the user to the group `dialout`.\n   ```bash\n   sudo usermod -a -G dialout obis\n   ```\n4. As user `obis` create a new directory for the OBIS reader solution `/home/obis/obis-reader`.\n   ```bash\n   ssh obis@raspberrypi\n   mkdir obis-reader\n   ```\n5. \"Ship\" the solution from your development machine to the Raspberry. This could be easily done using rsync.\n   ```bash\n   rsync -av -e ssh --exclude='node_modules/' obis-reader/ obis@raspberrypi:/home/obis/obis-reader\n   ```\n   Excluding the node_modules folder saves a LOT of time!\n6. On the Raspberry as user `obis` in `/home/obis/obis-reader` install the needed NodeJS packages for productive use.\n   ```bash\n   npm install --production\n   ```\n7. Do a test run: \n   ```bash\n   node /home/obis/obis-reader/app.js\n   ```\n8. As user `pi` create a service for the app by creating a systemd service file.\n   ```bash\n   sudo nano /lib/systemd/system/obis-reader.service\n   ```\n   With the following content:\n   ```bash\n   [Unit]\n   Description=obis-reader - reading and persisting OBIS data from your smart-meter\n   After=network.target\n\n   [Service]\n   Environment=NODE_ENV=\"production\"\n   # configuration encryption key\n   Environment=CONFIG_ENCRYPTION_KEY=\"YOUR_KEY\"\n   Type=simple\n   User=obis\n   # set working dir to make secure-config working properly\n   WorkingDirectory=/home/obis/obis-reader\n   ExecStart=/usr/bin/node /home/obis/obis-reader/app.js\n   Restart=on-failure\n\n   [Install]\n   WantedBy=multi-user.target\n   ```\n9. Start the service and enable it.\n   ```bash\n   sudo systemctl start obis-reader\n   sudo systemctl enable obis-reader\n   ```\nobis-reader is now running as a service.\n\n## Further data usage examples\n\nBy using MongoDB's query functions and aggregation framework, a lot of useful analysis of the persisted data can be done. Some useful examples...\n\n### Average power consumption for each hour of the day\n\n```js\nobisValues.aggregate(\n   [\n      { $group: \n         { \n            _id: { $hour: { date: '$date' } }, \n            consumptionMeasures: { $sum: 1 }, \n            consumptionAvg: { $avg: '$powerCurrent' } \n         } \n      },\n      { $sort: { _id: 1 } }\n   ],\n   (err, result) =\u003e {...});\n```\n\n### Average power consumption over the last x minutes\n\n```js\nobisActuals.aggregate(\n   [\n      { $match: { date: { '$gte': new Date(Date.now() - 1000 * 60 * minutes) } } },\n      { \n         $group: \n         { \n            _id: { $dateToString: { format: '%Y%m%dT%H%M', date: '$date' } },\n            consumptionMeasures: { $sum: 1 }, \n            consumptionAvg: { $avg: '$powerCurrent' } \n         } \n      },\n      { $sort: { _id: -1 } },\n      { $limit: minutes }\n   ],\n   (err, result) =\u003e {...});\n```\n\n### Maximum power consumption of the current day\n\n```js\nlet today = new Date();\ntoday.setHours(0, 0, 0, 0);\nobisActuals\n   .find({ date: { '$gte': today } })\n   .sort({ powerCurrent: -1 })\n   .limit(1)\n   .exec((err, result) =\u003e {...});\n```\n\n### Minimum power consumption of the current day\n\n```js\nlet today = new Date();\ntoday.setHours(0, 0, 0, 0);\nobisActuals\n   .find({ date: { '$gte': today } })\n   .sort({ powerCurrent: 1 })\n   .limit(1)\n   .exec((err, result) =\u003e {...});\n```\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fobis-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsmx%2Fobis-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fobis-reader/lists"}