nips/107.md
2023-10-25 12:36:08 +03:00

119 lines
5.5 KiB
Markdown

NIP-107
======
Nostr Internet of Things
-----------------------------------
`draft` `optional` `author:benarc` `author:blackcoffeebtc` `author:motorina0`
## Rationale
The terms/conditions of IoT software/hardware is horrible. A user should be able to message a light or heating system and ask it to turn on/off. Nostr gives the simple, permissionless development environment IoT needs.
## Terms
- `user` - user operating IoT devices with NOSTR key-pair and a client made specifically for IoT
- `device` - device to operate over Nostr with NOSTR key-pair, using a microcontroller client like <a href="https://github.com/lnbits/arduino-nostr">nostr-arduino</a>
## Nostr IoT Clients
### User
Where the `user` registers 'device'(s) and its keys, then updates the `device`(s).
### Device
The `device` uses a client like <a href="https://github.com/lnbits/arduino-nostr">nostr-arduino</a> to receive commands from the `user` or another `device`.
The `device` can also push data such as sensor readings and updates.
## Events
A `device` can publish any of the events described in [NIP-91 Event Kinds](https://github.com/nostr-protocol/nips/blob/iot/91.md#event-kinds).
A `user` can publish these event kinds:
| Kind | | Description | NIP |
|---------|----------|-------------------------------|-----------------------------------------------------------------------------------------|
| `30107` | `config` | Configure a device | [NIP-107 Configure Device Event](https://github.com/arcbtc/nips/edit/nip_107/107.md#configure-device-event) |
| `8000` | `intent` | Trigger an action on a device | [NIP-91 Event Kinds](https://github.com/nostr-protocol/nips/blob/iot/91.md#event-kinds) |
| `8001 - 8999` | `data` | Publish the state of a `device` | [NIP-91 Event Kinds](https://github.com/nostr-protocol/nips/blob/iot/91.md#event-kinds) |
The content of events can be transmitted in clear text (for public data) or as [NIP-59 Gift Wrap](https://github.com/staab/nips/blob/NIP-59/59.md).
### Configure Device Event (`kind: 30107`)
---
This message is sent by an admin `user` to a `device`. The `device` saves the config locally and then uses it.
**Event Content**:
```json
{
"name": <String (optional), set a name for the device>,
"description": <String (optional), device description>,
"categories":[ <String (optional), device category, such as 'boiler'>],
"admin_pubkeys": [ [<String (optional), admin user public-key>]],
"publish_to_pubkeys":[ [<String (optional), user public-key>]],
"intents_from_pubkeys":[ [<String (optional), user public-key>]],
"publish_on_change": <Boolean (optional, default `true`), publish event each time a sensor value changes>,
"publish_interval": <Integer (optional), publish the sensor value at regular intervals (regardless if the value changes or not). The value is in `millisecods`.>
"unix_time": <Integer (optional), set system time in `millisecods`.>
}
```
| Field | Description |
|---|---|
| `admin_pubkeys` | List of public keys that are allowed to configure this device.<br>A fresh/blank device will not have this value.<br/> The `admin_pubkeys` implicitly have the `actions_from_pubkeys` permissions. |
| `publish_to_pubkeys` | List of public keys to which events are published. |
| `actions_from_pubkeys` | List of public keys that are allowed to trigger an action on this device.<br/> The `admin_pubkeys` implicitly have the `actions_from_pubkeys` permissions. |
> [!IMPORTANT]
> The content of the `30107` event should be encrypted if the user chooses the "encrypted" mode
**Event Tags**:
```json
"tags": [["d", <String, pubkey of the configured device]]
```
- the `d` tag is required, its value MUST be the same as the pubkey of the `device`.
### Intent Events (`kind: 8000`)
---
Intent Events represent different actions that can be performed on a device. These actions can be triggered by a `user` or by another `device`.
The content of the event is a `JSON` array representing the data type and the data value as specified in [NIP-91 Event Kinds](https://github.com/nostr-protocol/nips/blob/iot/91.md#event-kinds)
**Event Content**:
```json
[[<Integer, between 8001 and 8999>, <Any Type> ]]
```
Example that turns on a device and sets the temperature to `20.9` degrees Celsius:
```json
[[8001, true], [8003, 20.9]]
```
**Event Tags**:
```json
"tags": [["p", <String, pubkey of the targeted device(s)]]
```
- the `p` tag is required, its value MUST be the same as the pubkey(s) of the target `device`(s).
### Data Events (`kind: 8001 - 8999`)
---
Data Events represent data published by `device`(s). The `kind` of the event and the `content` must follow ths specification from [NIP-91 Event Kinds](https://github.com/nostr-protocol/nips/blob/iot/91.md#event-kinds).
> [!NOTE]
> If a device has more sensors attached (eg: temperature and humidity) then it will publish separate events for each measured value.
**Event Tags**:
```json
"tags": [["p", <String, pubkey of the listening device(s)]]
```
- the `p` tag is optional. If set then its value MUST be the same as the `publish_to_pubkeys` value from the [Configure Device Event](https://github.com/arcbtc/nips/edit/nip_107/107.md#configure-device-event-kind-30107)
> [!IMPORTANT]
> If the transmission mode is encrypted ([NIP-59 Gift Wrap](https://github.com/staab/nips/blob/NIP-59/59.md)) then an individual message must be published for each public key in `publish_to_pubkeys`.