-
-
Save Brunty/20170da7cc6c27889a5ff2aed309aaec to your computer and use it in GitHub Desktop.
Fetch data from a Hildebrand Glow device over MQTT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
import logging | |
import json | |
import paho.mqtt.client as mqtt # pip3 install paho-mqtt | |
GLOW_LOGIN = "GLOW_LOGIN" | |
GLOW_PASSWORD = "GLOW_PASSWORD" | |
GLOW_DEVICE_ID = "GLOW_DEVICE_ID" | |
# Fields gathered from the ZigBee Smart Energy Standard document | |
# 0702: Metering | |
# - 00: Reading Information Set | |
# - 00: CurrentSummationDelivered: meter reading | |
# - 01: CurrentSummationReceived | |
# - 02: CurrentMaxDemandDelivered | |
# - 07: ReadingSnapshotTime (UTC time) | |
# - 14: Supply Status (enum): 0x2 is on | |
# - 02: Meter Status | |
# - 00: Status (bit map): 10 means power quality event | |
# - 03: Formatting | |
# - 00: UnitofMeasure (enum): 00 means kWh, 01 means m3 | |
# - 01: Multiplier | |
# - 02: Divisor | |
# - 03: SummationFormatting (bit map): | |
# 2B means 3 digits after the decimal point, 2 digits before the decimal point | |
# FB means 3 digits after the decimal point, 16 digits before the decimal point, | |
# no leading zeros | |
# - 04: DemandFormatting | |
# - 06: MeteringDeviceType: 00 means Electric Metering, 80 means Mirrored Gas Metering | |
# - 07: SiteID: MPAN encoded in UTF-8 | |
# - 08: MeterSerialNumber (string) | |
# - 12: AlternativeUnitofMeasure (enum) | |
# - 04: Historical Consumption | |
# - 00: InstantaneousDemand (signed): current consumption | |
# - 01: CurrentDayConsumptionDelivered | |
# - 30: CurrentWeekConsumptionDelivered | |
# - 40: CurrentMonthConsumptionDelivered | |
# - 0C: Alternative Historical Consumption | |
# - 01: CurrentDayConsumptionDelivered | |
# - 30: CurrentWeekConsumptionDelivered | |
# - 40: CurrentMonthConsumptionDelivered | |
# 0705: Prepayment | |
# - 00: Prepayment Information Set | |
# - 00: PaymentControlConfiguration (bit map) | |
# - 01: CreditRemaining (signed) | |
# 0708: Device Management | |
# - 01: Supplier Control Attribute Set | |
# - 01: ProviderName (string) | |
def on_connect(client, _userdata, _flags, result_code): | |
if result_code != mqtt.MQTT_ERR_SUCCESS: | |
logging.error("Error connecting: %d", result_code) | |
return | |
result_code, _message_id = client.subscribe("SMART/HILD/" + GLOW_DEVICE_ID) | |
if result_code != mqtt.MQTT_ERR_SUCCESS: | |
logging.error("Couldn't subscribe: %d", result_code) | |
return | |
logging.info("Connected and subscribed") | |
def on_message(_client, _userdata, message): | |
payload = json.loads(message.payload) | |
current_time = datetime.datetime.now().strftime("%H:%M:%S") | |
electricity_consumption = int(payload["elecMtr"]["0702"]["04"]["00"], 16) | |
electricity_daily_consumption = int(payload["elecMtr"]["0702"]["04"]["01"], 16) | |
electricity_weekly_consumption = int(payload["elecMtr"]["0702"]["04"]["30"], 16) | |
electricity_monthly_consumption = int(payload["elecMtr"]["0702"]["04"]["40"], 16) | |
electricity_multiplier = int(payload["elecMtr"]["0702"]["03"]["01"], 16) | |
electricity_divisor = int(payload["elecMtr"]["0702"]["03"]["02"], 16) | |
electricity_meter = int(payload["elecMtr"]["0702"]["00"]["00"], 16) | |
gas_daily_consumption = int(payload["gasMtr"]["0702"]["0C"]["01"], 16) | |
gas_weekly_consumption = int(payload["gasMtr"]["0702"]["0C"]["30"], 16) | |
gas_monthly_consumption = int(payload["gasMtr"]["0702"]["0C"]["40"], 16) | |
gas_multiplier = int(payload["gasMtr"]["0702"]["03"]["01"], 16) | |
gas_divisor = int(payload["gasMtr"]["0702"]["03"]["02"], 16) | |
gas_meter = int(payload["gasMtr"]["0702"]["00"]["00"], 16) | |
electricity_daily_consumption = electricity_daily_consumption * electricity_multiplier / electricity_divisor | |
electricity_weekly_consumption = electricity_weekly_consumption * electricity_multiplier / electricity_divisor | |
electricity_monthly_consumption = electricity_monthly_consumption * electricity_multiplier / electricity_divisor | |
electricity_meter = electricity_meter * electricity_multiplier / electricity_divisor | |
gas_daily_consumption = gas_daily_consumption * gas_multiplier / gas_divisor | |
gas_weekly_consumption = gas_weekly_consumption * gas_multiplier / gas_divisor | |
gas_monthly_consumption = gas_monthly_consumption * gas_multiplier / gas_divisor | |
gas_meter = gas_meter * gas_multiplier / gas_divisor | |
assert(int(payload["elecMtr"]["0702"]["03"]["00"], 16) == 0) # kWh | |
assert(int(payload["gasMtr"]["0702"]["03"]["01"], 16) == 1) # m3 | |
assert(int(payload["gasMtr"]["0702"]["03"]["12"], 16) == 0) # kWh | |
logging.info("Reading at %s", current_time) | |
logging.info("* electricity consumption: %dW", electricity_consumption) | |
logging.info("* daily electricity consumption: %.3fkWh", electricity_daily_consumption) | |
logging.info("* weekly electricity consumption: %.3fkWh", electricity_weekly_consumption) | |
logging.info("* monthly electricity consumption: %.3fkWh", electricity_monthly_consumption) | |
logging.info("* electricity meter: %.3fkWh", electricity_meter) | |
logging.info("* daily gas consumption: %.3fkWh", gas_daily_consumption) | |
logging.info("* weekly gas consumption: %.3fkWh", gas_weekly_consumption) | |
logging.info("* monthly gas consumption: %.3fkWh", gas_monthly_consumption) | |
logging.info("* gas meter: %.3fm3", gas_meter) | |
logging.info("Full payload: %s", json.dumps(payload, indent=2)) | |
def loop(): | |
logging.basicConfig(level=logging.DEBUG, format='%(message)s') | |
client = mqtt.Client() | |
client.username_pw_set(GLOW_LOGIN, GLOW_PASSWORD) | |
client.on_connect = on_connect | |
client.on_message = on_message | |
client.connect("glowmqtt.energyhive.com") | |
client.loop_forever() | |
if __name__ == "__main__": | |
loop() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment