diff --git a/src/sa/model/index.md b/src/sa/model/index.md index 9b6f222..8dc6e67 100644 --- a/src/sa/model/index.md +++ b/src/sa/model/index.md @@ -777,11 +777,21 @@ Exceed: Redesign based on >3 reused components (1 Logical View, >1 Process View, } -Components TBD: -- https://github.com/hap-java/HAP-Java -- https://github.com/tlaukkan/MQTT4java -- instances of the PostgreSQL 15 RDBMS ([sources here](https://github.com/postgres/postgres) and [specification here](https://www.postgresql.org/docs/15/index.html)), a _free as in beer_ and FOSS piece of software. -- https://spring.io/projects/spring-boot +## Component selection process ADRs + +TBD HAP-java + paho.mqtt.java + +TBD postgres (cite ADR #3 - reational DBs) + +## Chosen components + +| **Name** | **Version** | **Description** | **Price** | **Sources** | +| -------- | ----------- | --------------- | --------- | - | +| HAP-Java | 2.0.4 (2022-11-23) | Java implementation of the HomeKit Accessory Protocol | free (MIT license) | https://github.com/hap-java/HAP-Java/tree/hap-2.0.4 | +| Eclipse Paho Java MQTT client | 1.2.5 SR (2020-07-15) | Java client for the MQTT protocol | free (EPL 2.0 license) | https://github.com/eclipse/paho.mqtt.java/tree/v1.2.5 | +| PostgreSQL | 15.2 (2023-02-06) | Relational DBMS | free (PostgreSQL license) | https://github.com/postgres/postgres/tree/REL_15_2 | + +## Logical View ```puml @startuml @@ -889,17 +899,18 @@ skinparam defaultFontName Courier @enduml ``` -Use case: a user alters manually the state of device 'D' in the UI, and the device updates accordingly. Device 'D' is not part of any defined trigger. +## Process Views + +Use Case: An homekit smart sensor 'HS' and a MQTT smart sensor 'MS' report values which satisfy the condition defined in a trigger. Thanks to an automation specification, this in turn triggers the application of a scene which changes the state of homekit smart device 'D'. ```puml @startuml -title Process View: UI updates state of device +title Process View: Sensor triggers trigger and scene application box "IoT Devices" - participant "HomeKit dev." as HD - participant "HomeKit sens." as HS - participant "MQTT dev." as ZD - participant "MQTT sens." as ZS + participant "HomeKit device 'D'" as HD + participant "HomeKit sensor 'HS'" as HS + participant "MQTT sensor 'MS'" as ZS end box box "User Interface" @@ -925,14 +936,78 @@ box "Scenes" participant "DB" as SCDB end box -UI -> DI: update state (HTTP PUT) +HS -> HAP: Homekit protocol\n(report new temperature value) +HAP -> DI: TemperatureSensorAccessory.getCurrentTemperature() Future resolves\n(report new temperature value from 'HS') +ZS -> ZIG: MQTT PUBLISH\n(report new temperature value) +ZIG -> DI: subscriber.subscribe(...) observer called\n(report new temperature value from 'MS') +DI -> DIDB: JDBC transaction (UPDATE)\n(store new states) +DI -> WSS: s.getBasicRemote().sendText(...)\n(send new device states) +WSS <- WSC: WebSocket protocol +WSC -> UI: connection.onmessage called\n(new device states received, updates UI) +DI -> T: report latest device states +T -> TDB: prepared SELECT statement\n(query for relevant triggers) +T -> TDB: prepared SELECT statement\n(query for triggered automations) +T -> TDB: prepared SELECT statement\n(query for scenes included in automation) +T -> SC: request scene application +SC -> SCDB: prepared SELECT statement\n(query for device states to apply) + +SC -> DI: HTTP 1.1 PUT /devices/{id}/state\n(apply new state to device 'D') +DI -> HAP: LightbulbAccessory.setLightbulbPowerState(...)\n(apply new state to device 'D') +HAP -> HD: Homekit protocol\n(apply new state) +HD -> HAP: Homekit protocol\n(report successful application) +HAP -> DI: LightbulbAccessory.setLightbulbPowerState(...) Future completes\n(report successful application) +DI -> DIDB: JDBC transaction (UPDATE)\n(store new state) +DI -> WSS: s.getBasicRemote().sendText(...)\n(send new device state) +WSS <- WSC: WebSocket protocol +WSC -> UI: connection.onmessage called\n(new device state received, updates UI) + +skinparam monochrome true +skinparam shadowing false +skinparam defaultFontName Courier +@enduml +``` + +Use case: a user alters manually the state of device 'D' in the UI, and the device updates accordingly. Device 'D' is not part of any defined trigger. + +```puml +@startuml +title Process View: UI updates state of device + +box "IoT Devices" + participant "MQTT device 'D'" as ZD +end box + +box "User Interface" + participant "UI" as UI + participant "WebSockets API (JS)" as WSC +end box + +box "Users and Devices" + participant "javax.websocket" as WSS + participant "HAP-java" as HAP + participant "paho.mqtt.java" as ZIG + participant "Engine" as DI + participant "DB" as DIDB +end box + +box "Triggers and Automations" + participant "Engine" as T + participant "DB" as TDB +end box + +box "Scenes" + participant "Engine" as SC + participant "DB" as SCDB +end box + +UI -> DI: HTTP 1.1 PUT /devices/{id}/state\n(update state) DI -> ZIG: client.publish(\n TOPIC,\n new MqttMessage(...)\n);\n(request state update) -ZIG -> ZD: PUBLISH\n(state update request) -ZD -> ZIG: PUBLISH\n(new state) +ZIG -> ZD: MQTT PUBLISH\n(state update request) +ZD -> ZIG: MQTT PUBLISH\n(new state) ZIG -> DI: subscriber.subscribe(...) observer called \n(successful application) DI -> DIDB: JDBC transaction (UPDATE)\n(store new state) DI -> WSS: s.getBasicRemote().sendText(...)\n(send new device state) -WSS -> WSC: WebSocket protocol +WSS <--> WSC: WebSocket protocol WSC -> UI: connection.onmessage called\n(new device state received, updates UI) DI -> T: report latest device state