161 lines
5.4 KiB
Markdown
161 lines
5.4 KiB
Markdown
# flow3r-openhab
|
|
|
|
An app for the CCCamp 2023 [flow3r][flow3r] badge that submits detected touch gestures to an MQTT broker.
|
|
|
|
I wrote this so that the flow3r can be used as a remote control for
|
|
OpenHAB (which subscribes to the MQTT broker), but it should be usable
|
|
with other subscribers as well.
|
|
|
|
## Installation
|
|
|
|
1. Copy `flow3r_openhab/config.example.json` to `flow3r_openhab/config.json` and enter your configuration details.
|
|
1. Copy the `flow3r_openhab` directory to `/sys/apps/flow3r_openhab` on the flow3r's flash filesystem.
|
|
1. Reboot the flow3r and start the `OpenHAB` app
|
|
|
|
## MQTT Topics
|
|
|
|
* `flow3r-<macaddress>/event`: The app publishes events to this topic. see "Events" below.
|
|
* `flow3r-<macaddress>/status`: The app publishes the string `Online` to this topic when started, and submits an `Offline` LWT message.
|
|
* `flow3r-<macaddress>/ui_config`: You can publish a label for each petal to this topic, which will be shown on the flow3r's display. See "UI Config" below.
|
|
|
|
## Events
|
|
|
|
All events are published as JSON stringsto the topic `flow3r-<macaddress>/event`.
|
|
|
|
Keys common to all types of events are:
|
|
|
|
| Key | Value |
|
|
|:---|:---|
|
|
| `mode` | The mode that has been set via the `ui_config` topic, see "UI Config" below. |
|
|
| `type` | The type of event. Currently one of `button` or `touch`. |
|
|
|
|
|
|
### Touch Events
|
|
|
|
Example of a touch event:
|
|
|
|
```json
|
|
{"mode":"Numbers","type":"touch","petal":"2","event":"touch_tip","dx":8083,"dy":6960,"duration":150}
|
|
```
|
|
|
|
The keys and their values are defined as follows:
|
|
|
|
| Key | Value |
|
|
|:---|:---|
|
|
| `petal` | The petal the event was detected on. Uses the numbers printed on the PCB (1-10), rather than the `captouch` indexes (0-9). |
|
|
| `event` | The type of gesture that was detected. One of `touch_tip`, `touch_base`, `swipe_up`, `swipe_right`, `swipe_down`, `swipe_left`, whereas `swipe_up` always means a swipe towards the tip of the petal, and `swipe_down` towards its base. |
|
|
| `dx` | The distance between start and end of the touch event in `x` (base-to-tip) direction. Unitless number, as returned by [captouch's `position()` function][captouch]. |
|
|
| `dy` | The distance between start and end of the touch event in `y` (side-to-side) direction. |
|
|
| `duration` | The duration between start and end of the touch event in `ms`. |
|
|
|
|
|
|
### Button Events
|
|
|
|
Presses on the app button (by default the left one) are published to MQTT as well.
|
|
|
|
Example of a button event:
|
|
|
|
```json
|
|
{"mode":"Numbers","type":"button","button":"app_left","repeat":0}
|
|
```
|
|
|
|
The keys and their values are defined as follows:
|
|
|
|
| Key | Value |
|
|
|:---|:---|
|
|
| `button` | The direction in which the button was pressed. One of `app_left`, `app_right`, `app_down`, `os_left`, `os_right`, `os_down`. |
|
|
| `repeat` | If the button is held for a longer time, the button event is repeated every 500ms. This value is `0` for the inital event and incremented by one for each repeat event. |
|
|
|
|
|
|
## UI Config
|
|
|
|
The app subscribes to the topic `flow3r-<macaddress>/ui_config`, at which it listens for JSON arrays such as below:
|
|
|
|
```json
|
|
{
|
|
"mode": "Numbers",
|
|
"labels": ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
|
|
}
|
|
```
|
|
|
|
* `labels`: Each position in the array corrensponds to one of the petals, and the text for each petal is shown on the display close to the corresponding petal.
|
|
* `mode`: The text is shown in big in the center of the display. It is also sent with each event, so that subscribers can perform differnt actions depending on the active mode.
|
|
|
|
|
|
## Integration into OpenHAB
|
|
|
|
The following is an example of how this can be integrated into OpenHAB.
|
|
|
|
The recommended `Thing` definition is as follows:
|
|
|
|
```yaml
|
|
label: flow3r
|
|
thingTypeUID: mqtt:topic
|
|
configuration:
|
|
availabilityTopic: flow3r-<macaddress>/status
|
|
payloadNotAvailable: Offline
|
|
payloadAvailable: Online
|
|
channels:
|
|
- id: event
|
|
channelTypeUID: mqtt:trigger
|
|
label: Event
|
|
configuration:
|
|
stateTopic: flow3r-<macaddress>/event
|
|
- id: ui_config
|
|
channelTypeUID: mqtt:string
|
|
label: UI Config
|
|
configuration:
|
|
commandTopic: flow3r-<macaddress>/ui_config
|
|
```
|
|
|
|
The UI Config can be performed easiest by creating a rule that is triggered by the `Online` message on the status topic:
|
|
|
|
```yaml
|
|
configuration: {}
|
|
triggers:
|
|
- id: "1"
|
|
configuration:
|
|
thingUID: mqtt:topic:...
|
|
status: ONLINE
|
|
type: core.ThingStatusUpdateTrigger
|
|
conditions: []
|
|
actions:
|
|
- inputs: {}
|
|
id: "2"
|
|
configuration:
|
|
itemName: flow3r_ui_config # item needs to be created and linked to the ui_config topic beforehand
|
|
command: '{"labels":["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]}'
|
|
type: core.ItemCommandAction
|
|
```
|
|
|
|
For handling touch gestures, another rule can be created; the example below runs a JS script that parses the JSON payload and reacts on a long press on petal 10:
|
|
|
|
```yaml
|
|
configuration: {}
|
|
triggers:
|
|
- id: "1"
|
|
configuration:
|
|
thingUID: mqtt:topic:...
|
|
channelUID: mqtt:topic:...:event
|
|
type: core.ChannelEventTrigger
|
|
conditions: []
|
|
actions:
|
|
- inputs: {}
|
|
id: "2"
|
|
type: script.ScriptAction
|
|
configuration:
|
|
type: application/javascript
|
|
script: >-
|
|
var payload = JSON.parse(this.event.event);
|
|
if (payload.petal == "10" && payload.duration > 1000) {
|
|
console.log("longpress!");
|
|
}
|
|
```
|
|
|
|
|
|
## License
|
|
|
|
MIT License
|
|
|
|
[flow3r]: https://flow3r.garden/
|
|
[captouch]: https://docs.flow3r.garden/api/captouch.html#captouch.CaptouchPetalState.position
|