import os, sys import logging logging.basicConfig(stream=sys.stdout, format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s', level=logging.DEBUG if os.environ.get('DEBUG') else logging.INFO) import time import json import asyncio from asyncio_mqtt import Client import pygame import secrets COOLDOWN = time.time() CAMERAS = { 'NE-W-ZoneB': { 'name': 'Front Door', 'sound': 'barkLR.ogg', }, 'SE-N-ZoneB': { 'name': 'Side Door', 'sound': 'barkRL.ogg', } } async def play_sound(filename): pygame.mixer.music.load(filename) pygame.mixer.music.play() logging.info('Playing sound %s', filename) while pygame.mixer.music.get_busy(): #pygame.time.Clock().tick(10) await asyncio.sleep(0.1) async def bark(sound): global COOLDOWN if time.time() - COOLDOWN < 5.0: logging.info('Cooldown skipping.') return COOLDOWN = time.time() await asyncio.sleep(0.1) await play_sound(sound) logging.info('Done barking.') async def process_mqtt(message): text = message.payload.decode() topic = message.topic logging.info('MQTT topic: %s, message: %s', topic, text) if not topic.startswith('iot/cameras'): logging.info('Invalid topic, returning') return try: data = json.loads(text) except json.JSONDecodeError: logging.info('Invalid json, returning') return id_ = str(data.get('id', '')) if id_ not in CAMERAS: logging.info('Invalid id, returning') return camera = CAMERAS[id_] logging.info('Ringing %s...', camera['name']) await ring_bell(doorbell['sound']) async def fetch_mqtt(): await asyncio.sleep(3) async with Client('192.168.0.100') as client: async with client.filtered_messages('iot/cameras') as messages: await client.subscribe('#') async for message in messages: loop = asyncio.get_event_loop() loop.create_task(process_mqtt(message)) if __name__ == '__main__': logging.info('') logging.info('==========================') logging.info('Booting up...') pygame.init() pygame.mixer.pre_init(buffer=4096) pygame.mixer.init(buffer=4096) loop = asyncio.get_event_loop() loop.run_until_complete(fetch_mqtt())