From ad87239214f9d8438528234eecf8666400bf7b1b Mon Sep 17 00:00:00 2001 From: Bogdan Vlaicu Date: Fri, 11 Sep 2020 19:50:34 -0400 Subject: [PATCH] New oru/coned addon --- CONTRIBUTING.md | 29 ++++++++++++++++ LICENSE.md | 21 ++++++++++++ README.md | 78 +++++++++++++++++++++++++++++++++++++++++++ oru/Dockerfile | 30 +++++++++++++++++ oru/README.md | 73 ++++++++++++++++++++++++++++++++++++++++ oru/config.json | 50 +++++++++++++++++++++++++++ oru/icon.png | Bin 0 -> 3467 bytes oru/logo.png | Bin 0 -> 20438 bytes oru/requirements.txt | 5 +++ oru/run.py | 28 ++++++++++++++++ oru/run.sh | 35 +++++++++++++++++++ renovate.json | 11 ++++++ repository.json | 5 +++ 13 files changed, 365 insertions(+) create mode 100755 oru/Dockerfile create mode 100755 oru/README.md create mode 100755 oru/config.json create mode 100755 oru/icon.png create mode 100755 oru/logo.png create mode 100755 oru/requirements.txt create mode 100755 oru/run.py create mode 100755 oru/run.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e69de29..f2e4bc7 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish +to make via issue, email, or any other method with the owners of this repository +before making a change. + +Please note we have a code of conduct, please follow it in all your interactions +with the project. + +## Issues and feature requests + +You've found a bug in the source code, a mistake in the documentation or maybe +you'd like a new feature? You can help us by submitting an issue to our +[GitHub Repository][github]. Before you create an issue, make sure you search +the archive, maybe your question was already answered. + +Even better: You could submit a pull request with a fix / new feature! + +## Pull request process + +1. Search our repository for open or closed [pull requests][prs] that relates + to your submission. You don't want to duplicate effort. + +1. You may merge the pull request in once you have the sign-off of two other + developers, or if you do not have permission to do that, you may request + the second reviewer to merge it for you. + +[github]: https://github.com/bvlaicu/home-assistant-addons/issues +[prs]: https://github.com/bvlaicu/home-assistant-addons/pulls \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index e69de29..9db0a03 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2019-2020 Bogdan Vlaicu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index e69de29..14194f0 100755 --- a/README.md +++ b/README.md @@ -0,0 +1,78 @@ +# Home Assistant Add-ons + +## About + +Home Assistant allows anyone to create add-on repositories to share their +add-ons for Home Assistant easily. This repository is one of those repositories, +providing extra Home Assistant add-ons for your installation. + +## Installation + +In the Home Assistant add-on store, a possibility to add a repository is provided. + +Use the following URL to add this repository: + +```txt +https://github.com/bvlaicu/home-assistant-addons +``` + +## Add-ons provided by this repository + +### [PHP][addon-php] +### [Dashcast][addon-dashcast] +### [Meter Reader][addon-meter-reader] + + +## Releases + +Releases are based on [Semantic Versioning][semver], and use the format +of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented +based on the following: + +- ``MAJOR``: Incompatible or major changes. +- ``MINOR``: Backwards-compatible new features and enhancements. +- ``PATCH``: Backwards-compatible bugfixes and package updates. + +## Support + +Got questions? + +You have several options to get them answered: + +- The Home Assistant Community Add-ons [Discord Chat Server][discord] +- The Home Assistant [Community Forum][forum]. +- The Home Assistant [Discord Chat Server][discord-ha]. +- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] + +You could also open an issue here on GitHub. Note, we use a separate +GitHub repository for each add-on. Please ensure you are creating the issue +on the correct GitHub repository matching the add-on. + +## License + +MIT License + +Copyright (c) 2019-2020 Bogdan Vlaicu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +[addon-php]: https://github.com/bvlaicu/home-assistant-addons/tree/master/php +[addon-dashcast]: https://github.com/bvlaicu/home-assistant-addons/tree/master/dashcast +[addon-meter-reader]: https://github.com/bvlaicu/home-assistant-addons/tree/master/meter-reader +[addon-minidlna]: https://github.com/bvlaicu/home-assistant-addons/tree/master/minidlna diff --git a/oru/Dockerfile b/oru/Dockerfile new file mode 100755 index 0000000..72750e5 --- /dev/null +++ b/oru/Dockerfile @@ -0,0 +1,30 @@ +FROM debian:buster + +USER root +RUN apt-get update && apt-get upgrade -yq +RUN apt-get install python3 python3-pip jq nano -y + +# Install chrome and dependencies +RUN apt-get update && apt-get install -y \ + apt-transport-https \ + ca-certificates \ + curl \ + gnupg \ + --no-install-recommends \ + && curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ + && echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \ + && apt-get update && apt-get install -y \ + google-chrome-stable \ + --no-install-recommends + +# Chrome won't run from the root user. +RUN groupadd chrome && useradd -g chrome -s /bin/bash -G audio,video chrome \ + && mkdir -p /home/chrome && chown -R chrome:chrome /home/chrome + +COPY requirements.txt . +RUN pip3 install -r requirements.txt + +COPY run.py . +COPY run.sh . + +CMD cd / && chmod +x /run.sh && /run.sh diff --git a/oru/README.md b/oru/README.md new file mode 100755 index 0000000..cc062ee --- /dev/null +++ b/oru/README.md @@ -0,0 +1,73 @@ +# Orange and Rockland Utility to MQTT Bridge hass.io addon + +Add-on for retrieving the last meter read from [Orange and Rockland Utility](oru.com) or [ConEdison](coned.com) and publish the data via MQTT + +## Configuration + +Add-on configuration example: + +```yaml +email: example@email.com +password: '!secret oru_password' +mfa_type: TOTP +mfa_secret: '!secret oru_mfa_secret' +account_uuid: ef788d65-5380-11e8-8211-2655115779ac +meter_number: 706438804 +site: oru +mqtt_host: hassio.local +mqtt_user: mqtt +mqtt_password: '!secret mqtt_password' +``` +### Option: `email` + +The email address for the oru.com / coned.com account + +### Option: `password` + +The password for the oru.com / coned.com account + +### Option: `mfa_type` + +The MFA type for the oru.com / coned.com account. Can be either `SECURITY_QUESTION` or `TOTP` (e.g. Google Authenticator). + +### Option: `mfa_secret` + +The MFA secret for the oru.com / coned.com account. For MFA type Security Question, to set up your MFA secret (answer), log into oru.com / coned.com, go to your profile and reset your 2FA method. When setting up 2FA again, there will be option to say you do not have texting on your phone. Select this and you should be able to use a security question instead. +For MFA type TOTP, choose Google Authenticator, choose a device type and when presented with the QR code, click on "Can't scan?". It should provide you with the MFA secret. + +### Option: `account_uuid` + +The Orange and Rockland Utility account uuid. To find it log into oru.com / coned.com then use the browser developer tools to search for `uuid` in the network tab. + +### Option: `meter_number` + +The Orange and Rockland Utility meter number. You can find it on a utility bill. + +### Option: `site` + +Either `oru` for Orange and Rockland Utility or `coned` for ConEdison + +### Option: `mqtt_host` + +Defines the hostname or ip of the MQTT server + +### Option: `mqtt_user` + +Defines the username for the MQTT server + +### Option: `mqtt_password` + +Defines the password for the MQTT server + + +## MQTT Data + +The addon will publish the latest meter read value and unit of measure to the following topics: + +`electric_meter/startTime` + +`electric_meter/endTime` + +`electric_meter/value` + +`electric_meter/uom` diff --git a/oru/config.json b/oru/config.json new file mode 100755 index 0000000..8dc35d1 --- /dev/null +++ b/oru/config.json @@ -0,0 +1,50 @@ +{ + "name": "Orange and Rockland Utility to MQTT Bridge", + "version": "0.2.4", + "slug": "oru", + "description": "Orange and Rockland Utility meter reading to MQTT", + "url": "https://github.com/bvlaicu/home-assistant-addons/tree/master/oru", + "panel_icon": "mdi:chart-areaspline", + "startup": "application", + "homeassistant": "0.92.0b2", + "boot": "auto", + "map": ["share:rw", "ssl"], + "devices": ["/dev/bus/usb:/dev/bus/usb:rwm"], + "host_network": "False", + "arch": [ + "aarch64", + "amd64", + "armv7", + "i386" + ], + "hassio_api": true, + "auth_api": true, + "hassio_role": "default", + "homeassistant_api": false, + "options": + { + "email": "", + "password": "", + "mfa_type": "", + "mfa_secret": "", + "account_uuid": "", + "meter_number": "", + "site": "", + "mqtt_host": "hassio.local", + "mqtt_user": "", + "mqtt_password": "" + }, + "schema": + { + "email": "str", + "password": "str", + "mfa_type": "str", + "mfa_secret": "str", + "account_uuid": "str", + "meter_number": "str", + "site": "str", + "mqtt_host": "str", + "mqtt_user": "str", + "mqtt_password": "str" + } +} diff --git a/oru/icon.png b/oru/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..196f6e724f2b643a0baebf059e36bce455a31cc1 GIT binary patch literal 3467 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⪚mB8XeQESz@7sKw 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�az?=ru5JnUF|WGAjMP<05nlG0x6} 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 FV1jL!ErkF8 literal 0 HcmV?d00001 diff --git a/oru/requirements.txt b/oru/requirements.txt new file mode 100755 index 0000000..855946c --- /dev/null +++ b/oru/requirements.txt @@ -0,0 +1,5 @@ +pyotp +requests +pyppeteer +paho-mqtt +coned diff --git a/oru/run.py b/oru/run.py new file mode 100755 index 0000000..4b8284b --- /dev/null +++ b/oru/run.py @@ -0,0 +1,28 @@ +import os +import asyncio +from coned import Meter +from coned import MeterError +import paho.mqtt.client as mqtt + +meter = Meter( + email=os.getenv("EMAIL"), + password=os.getenv("PASSWORD"), + mfa_type=os.getenv("MFA_TYPE"), + mfa_secret=os.getenv("MFA_SECRET"), + account_uuid=os.getenv("ACCOUNT_UUID"), + meter_number=os.getenv("METER_NUMBER"), + site=os.getenv("SITE"), + browser_path="/usr/bin/google-chrome-stable" +) +startTime, endTime, val, uom = asyncio.get_event_loop().run_until_complete(meter.last_read()) + +print(f"startTime: {startTime}, endTime: {endTime}, val: {val}, uom: {uom}") + +mqttc = mqtt.Client("oru_meter_reader") +mqttc.username_pw_set(username=os.getenv("MQTT_USER"), password=os.getenv("MQTT_PASS")) +mqttc.connect(os.getenv("MQTT_HOST")) +mqttc.publish('electric_meter/startTime', startTime, retain=True) +mqttc.publish('electric_meter/endTime', endTime, retain=True) +mqttc.publish('electric_meter/value', val, retain=True) +mqttc.publish('electric_meter/uom', uom, retain=True) +mqttc.disconnect() diff --git a/oru/run.sh b/oru/run.sh new file mode 100755 index 0000000..d35e7f9 --- /dev/null +++ b/oru/run.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +CONFIG_PATH=/data/options.json + +export EMAIL="$(jq --raw-output '.email' $CONFIG_PATH)" +export PASSWORD="$(jq --raw-output '.password' $CONFIG_PATH)" +export MFA_TYPE="$(jq --raw-output '.mfa_type' $CONFIG_PATH)" +export MFA_SECRET="$(jq --raw-output '.mfa_secret' $CONFIG_PATH)" +export ACCOUNT_UUID="$(jq --raw-output '.account_uuid' $CONFIG_PATH)" +export METER_NUMBER="$(jq --raw-output '.meter_number' $CONFIG_PATH)" +export SITE="$(jq --raw-output '.site' $CONFIG_PATH)" +export MQTT_HOST="$(jq --raw-output '.mqtt_host' $CONFIG_PATH)" +export MQTT_USER="$(jq --raw-output '.mqtt_user' $CONFIG_PATH)" +export MQTT_PASS="$(jq --raw-output '.mqtt_password' $CONFIG_PATH)" + +echo "Params:" +echo "EMAIL =" $EMAIL +echo "PASSWORD =" $(sed 's/^........../**********/' <<<$PASSWORD) +echo "MFA_TYPE =" $MFA_TYPE +echo "MFA_SECRET =" $(sed 's/^........../**********/' <<<$MFA_SECRET) +echo "ACCOUNT_UUID =" $ACCOUNT_UUID +echo "METER_NUMBER =" $METER_NUMBER +echo "SITE =" $SITE +echo "MQTT_HOST =" $MQTT_HOST +echo "MQTT_USER =" $MQTT_USER +echo "MQTT_PASS =" $(sed 's/^........../**********/' <<<$MQTT_PASS) + +# Start the listener and enter an endless loop +echo "Starting endless loop.." +while true; do + python3 run.py + #tail -f /dev/null + + sleep 300 +done \ No newline at end of file diff --git a/renovate.json b/renovate.json index e69de29..58ca74e 100755 --- a/renovate.json +++ b/renovate.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "config:base" + ], + "commitMessageAction": "Updates", + "commitMessageTopic": "{{depName}}", + "commitMessagePrefix": ":arrow_up:", + "labels": [ + "Type: Maintenance" + ] +} diff --git a/repository.json b/repository.json index e69de29..a88d566 100755 --- a/repository.json +++ b/repository.json @@ -0,0 +1,5 @@ +{ + "name": "bvlaicu's Home Assistant Addons", + "url": "https://github.com/bvlaicu/home-assistant-addons-repository", + "maintainer": "bogdanvlaicu@yahoo.com" +} \ No newline at end of file