Skip to content

Instantly share code, notes, and snippets.

@johnlpage
Created March 17, 2022 09:30
Show Gist options
  • Save johnlpage/41d4283146c0dab0674975ff6f06cd18 to your computer and use it in GitHub Desktop.
Save johnlpage/41d4283146c0dab0674975ff6f06cd18 to your computer and use it in GitHub Desktop.
import aiohttp
import pysmartthings
import pymongo
import json
import asyncio
from pprint import pprint
import datetime
with open("/home/pi/.smartthing_token") as f:
token = f.readline().strip()
interesting_attributes = [
"n",
"switch",
"powerConsumption",
"operatingState",
"ovenSetpoint",
"temperature",
"machineState",
]
# Try to work out a wattage if we can
def estimate_wattage(rec):
if rec.get("n") == "Dishwasher" and rec["machineState"] == "run":
print("Dishwasher on")
return 500 # Average wash is 1500W in 3 hours apparently
if "washer" in rec.get("n"):
pc = rec.get("powerConsumption")
try:
if pc:
start = datetime.datetime.strptime(
pc["start"][:19], "%Y-%m-%dT%H:%M:%S"
)
end = datetime.datetime.strptime(pc["end"][:19], "%Y-%m-%dT%H:%M:%S")
used = pc["deltaEnergy"]
seconds = (end - start).total_seconds()
if seconds > 0:
return (used * 3600) / seconds
except Exception as e:
print(e)
return None
return 0
if "oven" in rec.get("n"):
if rec.get("operatingState", "ready") != "ready":
# Are we heating or holding?
if rec["ovenSetpoint"] * 0.95 > rec["temperature"]:
return 1200
else:
return 400
async def log_devices():
async with aiohttp.ClientSession() as session:
api = pysmartthings.SmartThings(session, token)
devices = await api.devices()
deviceinfo = []
for device in devices:
try:
name = device.label
# Dont record my mobile phone
if "Tully" not in name:
await device.status.refresh()
turned_on = device.status.switch
record = {"on": turned_on, "name": name}
# if "David" in name:
# pprint(device.status.values)
for a in interesting_attributes:
v = device.status.values.get(a, None)
if v != None:
record[a] = v
watts = estimate_wattage(record)
if watts != None:
record["watts"] = watts
record["on"] = True
turned_on = True
# Let's not waste space on things that are off
if turned_on:
deviceinfo.append(record)
except Exception as e:
# Fridge returns an auth error?
print(f"{device.label} not available {e}")
return deviceinfo
def main():
with open("/home/pi/.mongo_uri.txt") as f:
uri = f.readline().strip()
mongoclient = pymongo.MongoClient(uri)
loop = asyncio.get_event_loop()
devices = loop.run_until_complete(log_devices())
loop.close()
# Fridge is always running - we can see on its screen and app how much energy
# Average is about 2 units a day so we will add that 2KW/(24*6) = 83w
devices.append({"n": "fridge", "name": "Fridge", "on": True, "watts": 83})
pprint(devices)
if len(devices) > 0:
# Append this to an array in the latest electicity reading
collection = mongoclient.energy.meter
query = {"type": "electric"}
sort = [("date", -1)]
update = {"$push": {"devices": {"$each": devices}}}
collection.find_one_and_update(query, update, sort=sort)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment