Skip to content

Instantly share code, notes, and snippets.

@jdrews
Last active December 19, 2023 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdrews/1ce07e6ed46c91c71c1ccffbe3f81154 to your computer and use it in GitHub Desktop.
Save jdrews/1ce07e6ed46c91c71c1ccffbe3f81154 to your computer and use it in GitHub Desktop.
petfeeders
import sys
import yaml
from influxdb_client import InfluxDBClient, Point
import logging
from logging.handlers import RotatingFileHandler
from datetime import datetime
# imports for surepy
import asyncio
from typing import List
import logging
from surepy import Surepy
from surepy.entities.pet import Pet
from datetime import date
from datetime import timedelta
from zoneinfo import ZoneInfo
import os
import time
# import schedule
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler('petfeeders.log', maxBytes=5000, backupCount=5)
logger.addHandler(handler)
# settings for petfeeders
with open("config.yaml", "r", encoding="UTF-8") as yamlfile:
conf = yaml.safe_load(yamlfile)
pollrate = conf['pollrate']
influxhost = conf['influxhost']
influxport = conf['influxport']
surepetuser = conf['surepetuser']
surepetpassword = conf['surepetpassword']
retention_policy = 'autogen'
influxdatabase = 'plantmon'
bucket = f'{influxdatabase}/{retention_policy}'
# user/password authentication (gets a token in background)
surepy = Surepy(email=surepetuser, password=surepetpassword)
async def getFoodConsumption(surepy: Surepy, day: str) -> dict[str, int | float]:
logging.basicConfig(level=logging.DEBUG)
pets: List[Pet] = await surepy.get_pets()
petFoodConsumption: dict[str, int | float] = {}
for pet in pets:
logger.info(f"\n\{day} - {pet.name}: {pet.state} | {pet.location}\n")
total_food_change_in_grams = await surepy.get_pet_dry_food_consumption_report(pet.household_id, pet.id, day, day)
logger.info(
f"total food change in grams = {total_food_change_in_grams}")
petFoodConsumption[pet.name] = total_food_change_in_grams
return petFoodConsumption
try:
try:
today = datetime.now(ZoneInfo("America/New_York"))
yesterday = today - timedelta(days=1)
# yesterday = datetime(year=2023, month=12, day=18)
queryDay = f"{yesterday.year}-{yesterday.month}-{yesterday.day}"
logger.info(f"Query day is {queryDay}")
petFoodConsumption = asyncio.run(getFoodConsumption(surepy, yesterday))
except Exception as e:
logger.error('Error at %s', 'web request', exc_info=e)
sys.exit()
logger.info(petFoodConsumption)
with InfluxDBClient(url='http://' + influxhost + ':' + influxport, org='-') as client:
with client.write_api() as write_api:
maudieFoodGrams = petFoodConsumption["Maudie"]
lucyFoodGrams = petFoodConsumption["Lucy"]
logger.info(str(datetime.now())
+ " -- maudieFoodGrams (g): " + str(maudieFoodGrams)
+ ", lucyFoodGrams (g): " + str(lucyFoodGrams)
)
point = Point("plantmon").tag("tag", "pet")\
.time(datetime(year=yesterday.year, month=yesterday.month, day=yesterday.day, hour=8))\
.field("petfood_maudie_g", maudieFoodGrams)\
.field("petfood_lucy_g", lucyFoodGrams)
logger.info(point.to_line_protocol())
write_api.write(bucket=bucket, record=point)
except Exception as e:
logger.error('Error at %s', 'pet feeder', exc_info=e)
# settings for influxdb
influxhost: "redacted-influxhost"
influxport: "8086"
# settings for sure petcare
surepetuser: "redacted"
surepetpassword: "redacted"
[Unit]
Description=Monitor pet feeders and push to grafana
After=multi-user.target
[Service]
WorkingDirectory=/home/alarm/git/petfeeders
User=alarm
ExecStart=/home/alarm/git/petfeeders/venv/bin/python /home/alarm/git/petfeeders/petfeeders.py
Type=oneshot
[Unit]
Description=Run petfeeders daily at 4am
[Timer]
OnCalendar=*-*-* 4:00:00
Persistent=true
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment