diff --git a/README.md b/README.md index 3a36182..61c9e3f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ All configuration is handled through environment variables. | `IDINVITE_OIDC_SCOPE` | `["openid", "email", "profile"]` | JSON list of OIDC scopes to request. The OIDC IDP will need to send the group attribute. | | `IDINVITE_OIDC_USER_ATTR` | `email` | The attribute to use as the user ID. | | `HMDOORIS_REQUIRES_GROUP` | - | Set to require users to be a member of this groups. | +| `HMDOORIS_SPACEAPI_OPEND_NAME` | - | Name of the device to send `spaceapid` updates for | +| `HMDOORIS_SPACEAPI_OPEN_URL` | - | URL for the `spaceapid` open update endpoint. | | `HMDOORIS_URL` | `http://localhost:3000` | URL of the application, used to construct links to itself. | ### Required Group @@ -34,6 +36,14 @@ RaspberryMatic. If you are using a private certificate, you will need to use `HM the HTTP client to a suitable CA certificate. Setting the variable to `false` will disable certificate verification. Alternatively, you can use plain `http`. +### SpaceAPI + +[spaceapid](https://git.hamburg.ccc.de/CCCHH/spaceapid) can be used to provide data +for [SpaceAPI](https://spaceapi.io), and it's open update endpoint can be used to report the open status of a space. By +setting `HMDOORIS_SPACEAPI_OPEND_NAME` to the name of the lock on the main door, and `HMDOORIS_SPACEAPI_OPEN_URL` to the +update endpoint URL hmdooris can update the open status whenever it changes. Add the username and password in the url, +in the `https://user:pass@hostname.tld` format. If you do not set the name, no updates will be sent. + ## Managing the CCU certificate If you want to talk to the RaspberryMatic/CCU-Jack and you are using a self-signed certificate (which is the default), diff --git a/hmdooris/AppConfig.py b/hmdooris/AppConfig.py index 5915f1b..6ec569b 100644 --- a/hmdooris/AppConfig.py +++ b/hmdooris/AppConfig.py @@ -28,6 +28,8 @@ class AppConfig: self.ccujack_certificate_path = getenv('HMDOORIS_CCUJACK_CERTIFICATE_PATH', None) self.ccujack_username = getenv('HMDOORIS_CCUJACK_USERNAME', None) self.ccujack_password = getenv('HMDOORIS_CCUJACK_PASSWORD', None) + self.spaceapid_open_name = getenv('HMDOORIS_SPACEAPI_OPEND_NAME', None) + self.spaceapid_open_url = getenv('HMDOORIS_SPACEAPI_OPEN_URL', 'https://spaceapi.hamburg.ccc.de/state/open') if self.debug is not None and self.debug.lower not in ('0', 'f', 'false'): self.debug = True diff --git a/hmdooris/__main__.py b/hmdooris/__main__.py index d073256..19ef01c 100644 --- a/hmdooris/__main__.py +++ b/hmdooris/__main__.py @@ -39,7 +39,10 @@ auth = BottleOIDC(app, config={ websocket_clients = WebSocketClients() bottle_helpers = BottleHelpers(auth, group=config.requires_group, allowed=config.allowed) -update_poller = UpdatePoller(websocket_clients, ccujack, 1 if config.debug else 0.1) +update_poller = UpdatePoller(websocket_clients, ccujack, + update_delay=1 if config.debug else 0.1, + spaceapid_open_name=config.spaceapid_open_name, + spaceapid_open_url=config.spaceapid_open_url) @app.route("/static/") diff --git a/hmdooris/updatepoller.py b/hmdooris/updatepoller.py index ce16003..5a668b0 100644 --- a/hmdooris/updatepoller.py +++ b/hmdooris/updatepoller.py @@ -3,16 +3,23 @@ import logging from threading import Thread from time import sleep +import requests + from hmdooris.ccujack import CCUJack from hmdooris.websocketcomm import WebSocketClients class UpdatePoller: - def __init__(self, wsc: WebSocketClients, ccu: CCUJack, update_delay = 1.0): + def __init__(self, wsc: WebSocketClients, ccu: CCUJack, + update_delay = 1.0, + spaceapid_open_name=None, + spaceapid_open_url=None): self.wsc = wsc self.ccu = ccu self.current = {} self.update_delay = update_delay + self.spaceapid_open_name = spaceapid_open_name + self.spaceapid_open_url = spaceapid_open_url self.log = logging.getLogger(__name__) Thread(target=self.run, daemon=True).start() @@ -33,6 +40,7 @@ class UpdatePoller: for lock_id, value in new.items(): if force or lock_id not in self.current or self.current[lock_id] != value: update.append(value) + self.spaceapid_open_update(value) data = { "locks": update, } @@ -42,3 +50,8 @@ class UpdatePoller: def send_locks(self, force=False): self.wsc.send(self.get_locks()) + + def spaceapid_open_update(self, lock): + if self.spaceapid_open_name is None: + return + requests.put(self.spaceapid_open_url, data=lock["status"]=="UNLOCKED")