2022-01-30 23:52:17 +00:00
|
|
|
import os, sys
|
2021-10-07 04:02:16 +00:00
|
|
|
import logging
|
2022-01-30 23:52:17 +00:00
|
|
|
logging.basicConfig(stream=sys.stdout,
|
2021-10-07 04:02:16 +00:00
|
|
|
format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s',
|
|
|
|
level=logging.DEBUG if os.environ.get('DEBUG') else logging.INFO)
|
|
|
|
|
2021-10-06 09:04:07 +00:00
|
|
|
import time
|
2021-10-07 04:02:16 +00:00
|
|
|
import json
|
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
import asyncio
|
|
|
|
from asyncio_mqtt import Client
|
2021-10-06 09:04:07 +00:00
|
|
|
import pygame
|
2021-10-07 04:02:16 +00:00
|
|
|
|
|
|
|
import secrets
|
2021-10-06 09:04:07 +00:00
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
COOLDOWN = time.time()
|
|
|
|
|
2021-10-06 09:04:07 +00:00
|
|
|
CHIME = 'chime.ogg'
|
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
DOORBELLS = {
|
|
|
|
'647166': {
|
|
|
|
'name': 'Front Door',
|
|
|
|
'sound': 'frontdoor.ogg',
|
|
|
|
},
|
|
|
|
'549660': {
|
|
|
|
'name': 'Back Door',
|
|
|
|
'sound': 'backdoor.ogg',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async def play_sound(filename):
|
2021-10-06 09:04:07 +00:00
|
|
|
pygame.mixer.music.load(filename)
|
|
|
|
pygame.mixer.music.play()
|
|
|
|
|
2021-10-07 04:02:16 +00:00
|
|
|
logging.info('Playing sound %s', filename)
|
|
|
|
|
2021-10-06 09:04:07 +00:00
|
|
|
while pygame.mixer.music.get_busy():
|
2022-01-31 00:53:35 +00:00
|
|
|
#pygame.time.Clock().tick(10)
|
|
|
|
await asyncio.sleep(0.1)
|
|
|
|
|
|
|
|
|
|
|
|
async def ring_bell(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(CHIME)
|
|
|
|
await play_sound(sound)
|
|
|
|
|
|
|
|
await asyncio.sleep(0.75)
|
|
|
|
|
|
|
|
await play_sound(CHIME)
|
|
|
|
await play_sound(sound)
|
|
|
|
|
|
|
|
logging.info('Done ringing.')
|
|
|
|
|
|
|
|
async def process_mqtt(message):
|
|
|
|
text = message.payload.decode()
|
|
|
|
topic = message.topic
|
|
|
|
logging.info('MQTT topic: %s, message: %s', topic, text)
|
2021-10-06 09:04:07 +00:00
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
if not topic.startswith('rtl_433'):
|
|
|
|
logging.info('Invalid topic, returning')
|
|
|
|
return
|
2021-10-06 09:04:07 +00:00
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
try:
|
|
|
|
data = json.loads(text)
|
|
|
|
except json.JSONDecodeError:
|
|
|
|
logging.info('Invalid json, returning')
|
|
|
|
return
|
|
|
|
|
|
|
|
id_ = str(data.get('id', ''))
|
|
|
|
|
|
|
|
if id_ not in DOORBELLS:
|
|
|
|
logging.info('Invalid id, returning')
|
|
|
|
return
|
|
|
|
|
|
|
|
doorbell = DOORBELLS[id_]
|
|
|
|
|
|
|
|
logging.info('Ringing %s...', doorbell['name'])
|
|
|
|
|
|
|
|
await ring_bell(doorbell['sound'])
|
|
|
|
|
|
|
|
|
|
|
|
async def fetch_mqtt():
|
|
|
|
await asyncio.sleep(3)
|
|
|
|
async with Client('localhost') as client:
|
|
|
|
async with client.filtered_messages('#') as messages:
|
|
|
|
await client.subscribe('#')
|
|
|
|
async for message in messages:
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
loop.create_task(process_mqtt(message))
|
2021-10-06 09:04:07 +00:00
|
|
|
|
|
|
|
|
2021-10-07 04:02:16 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
logging.info('')
|
|
|
|
logging.info('==========================')
|
|
|
|
logging.info('Booting up...')
|
2022-01-31 00:53:35 +00:00
|
|
|
|
2021-10-07 04:02:16 +00:00
|
|
|
pygame.init()
|
2022-01-30 23:52:17 +00:00
|
|
|
pygame.mixer.pre_init(buffer=4096)
|
|
|
|
pygame.mixer.init(buffer=4096)
|
2021-10-06 09:04:07 +00:00
|
|
|
|
2022-01-31 00:53:35 +00:00
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
loop.run_until_complete(fetch_mqtt())
|