|
| 1 | +#!/usr/bin/python3 |
| 2 | +# |
| 3 | +# Script to get data from Shelly3EM and store it in InfluxDB |
| 4 | +# |
| 5 | +# Author: Michalux |
| 6 | +# Version: 1.0 |
| 7 | +# |
| 8 | + |
| 9 | +import configparser |
| 10 | +import urllib3 |
| 11 | +from urllib.parse import urlencode |
| 12 | +import json |
| 13 | +import os.path |
| 14 | +import sys |
| 15 | +import datetime |
| 16 | +from datetime import datetime |
| 17 | +from influxdb import InfluxDBClient |
| 18 | + |
| 19 | +# Prepare data to write do InfluxDB |
| 20 | +def PrepareInfluxData(IfData, fieldname, fieldvalue): |
| 21 | + IfData[0]["fields"][fieldname] = float(fieldvalue) |
| 22 | + return IfData |
| 23 | + |
| 24 | +def Write2InfluxDB(IfData): |
| 25 | + ifclient.write_points(IfData) |
| 26 | + |
| 27 | +os.chdir(os.path.dirname(os.path.abspath(sys.argv[0]))) |
| 28 | + |
| 29 | +# CONFIG |
| 30 | +configParser = configparser.RawConfigParser() |
| 31 | +configFilePath = r'./config.cfg' |
| 32 | +configParser.read(configFilePath) |
| 33 | + |
| 34 | +SHELLYIP=configParser.get('Shelly3EM', 'IP') |
| 35 | +SHELLYUSERPASS=configParser.get('Shelly3EM', 'userpass') |
| 36 | +INFLUXDB = configParser.get("InfluxDB", "influxdb") |
| 37 | +IFHOST = configParser.get("InfluxDB", "influxdb_host") |
| 38 | +IFPORT = configParser.get("InfluxDB", "influxdb_port") |
| 39 | +IFUSER = configParser.get("InfluxDB", "influxdb_user") |
| 40 | +IFPASS = configParser.get("InfluxDB", "influxdb_password") |
| 41 | +IFDB = configParser.get("InfluxDB", "influxdb_dbname") |
| 42 | +verbose = configParser.get("General", "verbose") |
| 43 | +termout = configParser.get("General", "terminal_output") |
| 44 | +lang = configParser.get("General", "lang") |
| 45 | + |
| 46 | +# Get parameter's definitions to monitor |
| 47 | +pfilename="./params_"+lang+".json" |
| 48 | +with open(pfilename) as paramfile: |
| 49 | + params=json.loads(paramfile.read()) |
| 50 | + |
| 51 | +# Initialise InfluxDB support |
| 52 | +if INFLUXDB == "1": |
| 53 | + timestamputc = str(datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")) |
| 54 | + ifclient = InfluxDBClient(IFHOST, IFPORT, IFUSER, IFPASS, IFDB) |
| 55 | + InfluxData = [{"measurement": "Shelly3EM", "time": timestamputc, "fields": {}}] |
| 56 | + |
| 57 | +# Initialise HTTP Manager |
| 58 | +http = urllib3.PoolManager() |
| 59 | +header = urllib3._collections.HTTPHeaderDict() |
| 60 | + |
| 61 | +# Get data from Shelly3EM |
| 62 | +header = urllib3.make_headers(basic_auth=SHELLYUSERPASS) |
| 63 | +URL='http://'+SHELLYIP+'/status' |
| 64 | +try: |
| 65 | + apiresponse = http.request('GET', URL, headers=header) |
| 66 | +except: |
| 67 | + print("** Error getting data from Shelly3EM **") |
| 68 | + sys.exit(1) |
| 69 | +response = json.loads(apiresponse.data) |
| 70 | + |
| 71 | +if verbose=="1": |
| 72 | + print("** Shelly3EM response: **") |
| 73 | + print(json.dumps(response, indent=4, sort_keys=False, ensure_ascii=False)) |
| 74 | + |
| 75 | +# Parse Shelly3EM response |
| 76 | +Total=0 |
| 77 | +TotalR=0 |
| 78 | +if termout=="1": |
| 79 | + print("Home grid statistics:") |
| 80 | +faza=1 |
| 81 | +for shellydata in response["emeters"]: |
| 82 | + if termout=="1": |
| 83 | + print("Phase "+str(faza)) |
| 84 | + for param in params: |
| 85 | + if param != "total_power" and param != "total_sum" and param != "total_returned_sum": |
| 86 | + if termout=="1": |
| 87 | + print(" "+params[param]+": "+str(shellydata[param])) |
| 88 | + param_name=param+"_"+str(faza) |
| 89 | + if param == "total": |
| 90 | + Total+=shellydata[param] |
| 91 | + if param == "total_returned": |
| 92 | + TotalR+=shellydata[param] |
| 93 | + if INFLUXDB=="1": |
| 94 | + PrepareInfluxData(InfluxData, param_name, shellydata[param]) |
| 95 | + faza+=1 |
| 96 | +if termout=="1": |
| 97 | + print(params["total_power"]+" : "+str(response["total_power"])) |
| 98 | + print(params["total_sum"]+" : "+str(Total)) |
| 99 | + print(params["total_returned_sum"]+" : "+str(TotalR)) |
| 100 | +if INFLUXDB=="1": |
| 101 | + PrepareInfluxData(InfluxData, "total_power", response["total_power"]) |
| 102 | + PrepareInfluxData(InfluxData, "total_sum", Total) |
| 103 | + PrepareInfluxData(InfluxData, "total_returned_sum", TotalR) |
| 104 | + |
| 105 | +# Write data to Influx Database |
| 106 | +if INFLUXDB=="1": |
| 107 | + Write2InfluxDB(InfluxData) |
| 108 | + if verbose=="1": |
| 109 | + print("** Data written to InfluxDB: **") |
| 110 | + print(json.dumps(InfluxData, indent=4, sort_keys=False, ensure_ascii=False)) |
0 commit comments