Skip to content

Commit

Permalink
feat: Add support for local MQTT servers.
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewjw committed Nov 7, 2022
1 parent 128abcb commit 1bb285c
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 39 deletions.
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,99 @@

Receives gas and electric meter data from https://glowmarkt.com/ and exposes it to Prometheus.

```
usage: glowprom [-h] [--mqtt [MQTT]] [--port [PORT]] [--user [USER]] [--passwd [PASSWD]] [--topic [TOPIC]] [--bind [BIND]]
Listens to meter reports from Glow (glowmarkt.com) MQTT and exposes them as prometheus metrics
optional arguments:
-h, --help show this help message and exit
--mqtt [MQTT] the mqtt server to connect to. leave unset for the Glow cloud MQTT. (can also be set with $GLOWPROM_MQTT)
--port [PORT] the mqtt port to connect to. (can also be set with $GLOWPROM_MQTT_PORT)
--user [USER] the user name to use (can also be set with $GLOWPROM_USER)
--passwd [PASSWD] the password to use (can also be set with $GLOWPROM_PASSWD)
--topic [TOPIC] the topic to listen on for cloud MQTT (can also be set with $GLOWPROM_TOPIC)
--bind [BIND] the ip address and port to bind to
```

The Glow IHD can be used to connect a cloud MQTT server provided by Glow, or to your own local MQTT. These methods send different
messages, so different prometheus metrics are exposed depending on what you use.

# Cloud MQTT

```
# HELP consumption The consumption over the given period.
# TYPE consumption counter
glowprom_consumption{type="electricity",period="daily"} 4.761
glowprom_consumption{type="electricity",period="weekly"} 4.761
glowprom_consumption{type="electricity",period="monthly"} 61.483
glowprom_consumption{type="gas",period="daily"} 17.326
glowprom_consumption{type="gas",period="weekly"} 17.326
glowprom_consumption{type="gas",period="monthly"} 383.157
# HELP meter The meter reading.
# TYPE meter counter
glowprom_meter{type="electricity"} 15255.87
glowprom_meter{type="gas"} 5995.276
```

# Local MQTT
```
# HELP glowprom_timestamp The time the last update was received.
# TYPE glowprom_timestamp counter
glowprom_timestamp{type="electric", mpan="your_mpan"} 1667818379.0
glowprom_timestamp{type="gas", mprn="your_mprn"} 1667818361.0
# HELP glowprom_export_cumulative_Wh The total amount of energy exported.
# TYPE glowprom_export_cumulative_Wh counter
glowprom_export_cumulative_Wh{type="electric", mpan="your_mpan"} 0.0
# HELP glowprom_import_cumulative_Wh The total amount of energy imported.
# TYPE glowprom_import_cumulative_Wh counter
glowprom_import_cumulative_Wh{type="electric", mpan="your_mpan"} 15255822.0
glowprom_import_cumulative_Wh{type="gas", mprn="your_mprn"} 66589570.00000001
# HELP glowprom_import_day_Wh The amount of energy imported today.
# TYPE glowprom_import_day_Wh gauge
glowprom_import_day_Wh{type="electric", mpan="your_mpan"} 4714.0
glowprom_import_day_Wh{type="gas", mprn="your_mprn"} 17326.0
# HELP glowprom_import_week_Wh The amount of energy imported this week.
# TYPE glowprom_import_week_Wh gauge
glowprom_import_week_Wh{type="electric", mpan="your_mpan"} 4714.0
glowprom_import_week_Wh{type="gas", mprn="your_mprn"} 17326.0
# HELP glowprom_import_month_Wh The amount of energy imported this month.
# TYPE glowprom_import_month_Wh gauge
glowprom_import_month_Wh{type="electric", mpan="your_mpan"} 61436.0
glowprom_import_month_Wh{type="gas", mprn="your_mprn"} 383157.0
# HELP glowprom_import_price The current unit price for energy.
# TYPE glowprom_import_price gauge
glowprom_import_price{type="electric", mpan="your_mpan"} 0.16401
glowprom_import_price{type="gas", mprn="your_mprn"} 0.03623
# HELP glowprom_import_standing The standing charge for energy.
# TYPE glowprom_import_standing gauge
glowprom_import_standing{type="electric", mpan="your_mpan"} 0.19383
glowprom_import_standing{type="gas", mprn="your_mprn"} 0.168
# HELP glowprom_power_W The current amount of power being used.
# TYPE glowprom_power_W gauge
glowprom_power_W{type="electric", mpan="your_mpan"} 489.0
# HELP glowprom_import_cumulativevol_m3 The total volume of gas imported.
# TYPE glowprom_import_cumulativevol_m3 counter
glowprom_import_cumulativevol_m3{type="gas", mprn="your_mprn"} 5995.276
# HELP glowprom_import_dayvol_Wh The volume of gas imported today.
# TYPE glowprom_import_dayvol_Wh counter
glowprom_import_dayvol_Wh{type="gas", mprn="your_mprn"} 17326.0
# HELP glowprom_import_weekvol_Wh The volume of gas imported this week.
# TYPE glowprom_import_weekvol_Wh counter
glowprom_import_weekvol_Wh{type="gas", mprn="your_mprn"} 17326.0
# HELP glowprom_import_monthvol_Wh The volume of gas imported this month.
# TYPE glowprom_import_monthvol_Wh counter
glowprom_import_monthvol_Wh{type="gas", mprn="your_mprn"} 383157.0
```
2 changes: 1 addition & 1 deletion bin/glowprom
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def main():
args = get_arguments(sys.argv[1:])

threading.Thread(target=connect,
args=(args, update_stats),
args=(args, update_stats(args.cloud)),
daemon=True).start()

serve(args)
Expand Down
1 change: 0 additions & 1 deletion glowprom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from .arguments import get_arguments
from .exceptions import InvalidArguments
from .mqtt import connect
from .prometheus import prometheus
from .server import serve, update_stats

__version__ = "0.2.6"
27 changes: 22 additions & 5 deletions glowprom/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,57 @@

from .exceptions import InvalidArguments

DEFAULT_MQTT = "glowmqtt.energyhive.com"

parser = argparse.ArgumentParser(
description='Listens to meter reports from Glow (glowmarkt.com) MQTT and'
+ ' exposes them as prometheus metrics')
parser.add_argument('--mqtt', type=str, nargs='?', default=DEFAULT_MQTT,
help='the mqtt server to connect to. leave unset for the '
+ 'Glow cloud MQTT. (can also be set with $GLOWPROM_MQTT)')
parser.add_argument('--port', type=int, nargs='?', default=1883,
help='the mqtt port to connect to. (can also be set with '
+ '$GLOWPROM_MQTT_PORT)')
parser.add_argument('--user', type=str, nargs='?',
help='the user name to use (can also be set with '
+ '$GLOWPROM_USER)')
parser.add_argument('--passwd', type=str, nargs='?',
help='the password to use (can also be set with '
+ '$GLOWPROM_PASSWD)')
parser.add_argument('--topic', type=str, nargs='?',
help='the topic to listen on (can also be set with '
+ '$GLOWPROM_TOPIC)')
help='the topic to listen on for cloud MQTT'
+ ' (can also be set with $GLOWPROM_TOPIC)')
parser.add_argument('--bind', type=str, nargs='?', default="0.0.0.0:9100",
help='the ip address and port to bind to')


def get_arguments(args):
args = parser.parse_args(args)
if "GLOWPROM_MQTT" in os.environ:
args.mqtt = os.environ["GLOWPROM_MQTT"]
if "GLOWPROM_MQTT_PORT" in os.environ:
args.port = os.environ["GLOWPROM_MQTT_PORT"]
if "GLOWPROM_USER" in os.environ:
args.user = os.environ["GLOWPROM_USER"]
if "GLOWPROM_PASSWD" in os.environ:
args.passwd = os.environ["GLOWPROM_PASSWD"]
if "GLOWPROM_TOPIC" in os.environ:
args.topic = os.environ["GLOWPROM_TOPIC"]

if args.user is None:
args.cloud = args.mqtt == DEFAULT_MQTT

if args.cloud and args.user is None:
raise InvalidArguments("No username supplied. Either use --user "
+ "or set $GLOWPROM_USER")
if args.passwd is None:
if args.cloud and args.passwd is None:
raise InvalidArguments("No password supplied. Either use --passwd "
+ "or set $GLOWPROM_PASSWD")
if args.topic is None:
if args.cloud and args.topic is None:
raise InvalidArguments("No topic supplied. Either use --topic "
+ "or set $GLOWPROM_TOPIC")
if not args.cloud and args.topic is not None:
raise InvalidArguments(
"A topic should only be supplied when using cloud MQTT.")

if ":" not in args.bind:
args.bind = (args.bind, 9100)
Expand Down
15 changes: 8 additions & 7 deletions glowprom/prometheus.py → glowprom/cloud_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,18 @@
# - 01: ProviderName (string)


METRIC = "consumption{{type=\"{type}\",period=\"{period}\"}} {value}"
METER = "meter{{type=\"{type}\"}} {value}"
METRIC = "glowprom_consumption{{type=\"{type}\",period=\"{period}\"}} {value}"
METER = "glowprom_meter{{type=\"{type}\"}} {value}"

METRIC_HELP = "# HELP consumption The consumption over the given period."
METRIC_TYPE = "# TYPE consumption counter"
METRIC_HELP = "# HELP glowprom_consumption" \
+ " The consumption over the given period."
METRIC_TYPE = "# TYPE glowprom_consumption counter"

METER_HELP = "# HELP meter The meter reading."
METER_TYPE = "# TYPE meter counter"
METER_HELP = "# HELP glowprom_meter The meter reading."
METER_TYPE = "# TYPE glowprom_meter counter"


def prometheus(msg):
def cloud_message(msg):
# Code adapted from
# https://gist.github.com/ndfred/b373eeafc4f5b0870c1b8857041289a9
payload = json.loads(msg.payload)
Expand Down
Loading

0 comments on commit 1bb285c

Please sign in to comment.