1
0
Fork 0
cherry-switch/cherry/switch/__init__.py

91 lines
2.7 KiB
Python

# cherry-switch - listener for switches and remote actions
# Copyright (C) 2021 Bob Carroll <bob.carroll@alum.rit.edu>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
import asyncio
from contextlib import AsyncExitStack
import logging
import yaml
from dns.asyncresolver import resolve
from asyncio_mqtt import Client
from . import zwave
async def get_broker(config):
"""
Gets the mqtt broker address from an SRV record.
:param config: configuration dictionary
:returns: the broker address
"""
broker = config.get('mqtt', {}).get('broker')
if broker is not None:
return broker
answer = await resolve('_mqtt._tcp', 'SRV', search=True)
return next((x.target.to_text() for x in answer))
async def init(config):
"""
Initializes the switch interface agent.
:param config: configuration dictionary
"""
mappings = config.get('mappings', {})
tasks = set()
async with AsyncExitStack() as stack:
client = Client(await get_broker(config), client_id='cherry-switch')
await stack.enter_async_context(client)
logging.info('Connected to mqtt broker')
topics = {f'zwave/{x}/91/+/scene/+': zwave.receive_central_scene
for x in mappings.keys()}
for t, cb in topics.items():
manager = client.filtered_messages(t)
messages = await stack.enter_async_context(manager)
task = asyncio.create_task(cb(client, mappings, messages))
tasks.add(task)
await client.subscribe('zwave/#')
await asyncio.gather(*tasks)
def main():
"""
CLI entry point.
"""
if len(sys.argv) != 2:
print('USAGE: cherry-switch <config file>')
sys.exit(1)
with open(sys.argv[1], 'r') as f:
config = yaml.safe_load(f)
log = config.get('log', {})
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s',
level=log.get('level', logging.ERROR))
try:
asyncio.run(init(config))
except KeyboardInterrupt:
pass