New meter_reader add-on

This commit is contained in:
Bogdan Vlaicu
2020-04-02 17:06:22 -04:00
parent d49cdf5821
commit 5d0deba9da
8 changed files with 204 additions and 0 deletions
BIN
View File
Binary file not shown.
+22
View File
@@ -0,0 +1,22 @@
ARG BUILD_FROM
FROM $BUILD_FROM
# Add env
ENV LANG C.UTF-8
RUN apk add --no-cache curl
RUN apk add --no-cache python3
RUN apk add --no-cache nano
# install .py script dependency
RUN pip3 install boto3
RUN pip3 install requests
RUN pip3 install paho-mqtt
# Copy data for add-on
COPY ocr_aws.py /
COPY run.sh /
RUN chmod a+x /run.sh
CMD [ "/run.sh" ]
+28
View File
@@ -0,0 +1,28 @@
# Meter Reader
Put a webcam in front of your utility meter and AWS Rekognition sends the reading over MQTT to a MQTT server of your choice.
note: if you restart the addon you will need to update the baseline value.
## Config
upd_interval: value in seconds to be used as interval between data refreshes.
url: where to find the picture of your meter (webcam) - it will be stored temporarily in folder /config/www
user: basic authentication for cam
password: password to obtain webcam picture
baseline: current reading of your meter
under: max you expect it to go down during an update interval (where I live solar panels allow meters to run backwards)
over: max you expect it to go up during an update interval
aws_access_key_id, aws_secret_access_key, region: see link on how to set up an AWS account. Did not really see how to get your region, I use "us-east-2" (https://docs.aws.amazon.com/rekognition/latest/dg/setting-up.html)
mqtt_host, mqtt_port, mqtt_user, mqtt_pwd: find and get access to your MQTT server
mqtt_topic: topic on which meter reading gets published
+14
View File
@@ -0,0 +1,14 @@
{
"name": "Meter reader",
"version": "0.1.13",
"slug": "meterreader",
"homeassistant_api": "no",
"description": "Put a webcam in front of your utility meter and let AWS Rekognition push the reading over mqtt",
"url": "https://github.com/bvlaicu/home-assistant-addons/tree/master/meter_reader",
"startup": "application",
"boot": "auto",
"arch": ["aarch64", "amd64", "armv7", "i386"],
"options": {"upd_interval":1800,"url": "127.0.0.1", "user": null, "password": null, "baseline": 1, "under": 1, "over": 1, "aws_access_key_id": null, "aws_secret_access_key": null, "region": null, "mqtt_host":"127.0.0.1", "mqtt_port":1883, "mqtt_user":"mqtt", "mqtt_pwd":"mqtt_pwd","mqtt_topic":"home/meter"},
"schema": {"upd_interval": "int", "url":"str", "user":"str", "password":"str", "baseline":"int", "under":"int", "over":"int", "aws_access_key_id": "str", "aws_secret_access_key": "str", "region": "str", "mqtt_host":"str", "mqtt_port":"int", "mqtt_user":"str", "mqtt_pwd":"str","mqtt_topic":"str"},
"map": ["config:rw"]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

+135
View File
@@ -0,0 +1,135 @@
import boto3
import paho.mqtt.client as mqtt
import requests
import json
import time
import os
import re
import sys
config_json = json.loads(open("/data/options.json").read())
path = "/root/.aws"
reading = ""
try:
os.mkdir(path)
except OSError:
print("Creation of the directory %s failed" % path)
else:
print("Successfully created the directory %s " % path)
f = open("/root/.aws/credentials", "w")
f.write("[default]")
f.write("\n")
f.write("aws_access_key_id = " + config_json["aws_access_key_id"])
f.write("\n")
f.write("aws_secret_access_key = " + config_json["aws_secret_access_key"])
f.close()
f = open("/root/.aws/config", "w")
f.write("[default]")
f.write("\n")
f.write("region = " + config_json["region"])
f.close()
baseline = int(config_json["baseline"])
base_low = baseline - int(config_json["under"])
base_up = baseline + int(config_json["over"])
client = boto3.client('rekognition')
def processor(base_low, baseline, base_up):
file = "/config/www/meter.jpg"
data_str = reader(file)
response = client.detect_text(Image={'Bytes': data_str})
print(response)
print("")
found = (response['TextDetections'])
reading = ""
for item in found:
print("Tekst:", item['DetectedText'])
print("Type:", item['Type'])
print("Confidence", item['Confidence'])
print("Id", item['Id'])
if item['Type'] != 'LINE':
print("ParentId:", item['ParentId'])
if (item['Type'] == 'WORD') or (item['Type'] == 'LINE'):
print("value conversion")
temp = item['DetectedText']
print("x", temp, "x")
temp = re.sub("[^0-9]", "", temp)
print("x", temp, "x")
nw = 0
try:
nw = int(temp)
except Exception:
print("Conversion failed")
pass
print("Nw: ", nw)
if (base_low <= nw and nw <= base_up):
print("erg waarschijnlijk juist:")
reading = temp
print(temp)
print(base_low, nw, base_up)
print("-----------")
return reading
def reader(file):
with open(file, "rb") as image_file:
encoded_string = image_file.read()
return encoded_string
def takereading():
# download the url contents in binary format
r = requests.get(config_json["url"], auth=(config_json["user"], config_json["password"]))
# open method to open a file on your system and write the contents
with open("/config/www/meter.jpg", "wb") as code:
code.write(r.content)
print("File downloaded")
def publishMQTT(reading):
mqttc = mqtt.Client("meter_reader")
mqttc.username_pw_set(username=config_json["mqtt_user"], password=config_json["mqtt_pwd"])
mqttc.connect(config_json["mqtt_host"], int(config_json["mqtt_port"]))
mqttc.publish(config_json["mqtt_topic"], reading, retain=True)
mqttc.disconnect()
def publishhiloMQTT(low, high):
mqttc = mqtt.Client("meter_reader")
mqttc.username_pw_set(username=config_json["mqtt_user"], password=config_json["mqtt_pwd"])
mqttc.connect(config_json["mqtt_host"], int(config_json["mqtt_port"]))
mqttc.publish("home/band/low", str(low), retain=True)
mqttc.publish("home/band/high", str(high), retain=True)
mqttc.disconnect()
if __name__ == '__main__':
baseline = int(config_json["baseline"])
base_low = baseline - int(config_json["under"])
base_up = baseline + int(config_json["over"])
while True:
print("Start")
try:
takereading()
print("foto action finished")
reading = processor(base_low, baseline, base_up)
if reading != "":
print("Reading = ok = ", reading)
baseline = int(reading)
base_low = baseline - int(config_json["under"])
base_up = baseline + int(config_json["over"])
publishMQTT(reading)
publishhiloMQTT(base_low, base_up)
else:
base_low = base_low - int(config_json["under"])
base_up = base_up + int(config_json["over"])
publishhiloMQTT(base_low, base_up)
except Exception:
print("Unexpected error:", sys.exc_info())
print("OCR failed. Will try again later.")
time.sleep(int(config_json["upd_interval"]))
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -e
python3 ocr_aws.py