Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ in YAML format.

| UCR Firmware | Core Simulator | REST API | WS API |
|--------------|----------------|----------|--------|
| 2.9.3-beta | 0.73.1 | 0.46.0 | 0.35.3 |
| 2.9.1-beta | 0.71.0 | 0.45.3 | 0.35.3 |
| 2.9.0-beta | 0.70.4 | 0.45.1 | 0.35.1 |
| 2.8.4-beta | 0.69.3 | 0.44.4 | 0.34.0 |
Expand Down
3 changes: 3 additions & 0 deletions core-api/rest/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ This section contains unreleased changes which will be part of an upcoming relea

---

## 0.46.0
- Update option when installing a custom integration.

## 0.45.3
### Added
- Add an optional description field to AvailableEntity.
Expand Down
19 changes: 18 additions & 1 deletion core-api/rest/UCR-core-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ openapi: 3.1.1
info:
title: Remote Two/3 REST Core-API
summary: REST Core-API for Remote Two/3
version: 0.45.4
version: 0.46.0
contact:
name: API Support
url: https://github.com/unfoldedcircle/core-api/issues
Expand Down Expand Up @@ -1649,12 +1649,20 @@ paths:
- `STATE_DIRECTORY`: data directory.
- The returned path may not be stored, it may change with future software updates.

Existing custom integrations can be updated by setting the `update` query parameter to `true`.
- A custom integration must be installed having the same `driver_id`, otherwise error `404` is returned.
- Existing configuration files are not replaced.
- It is recommended to not include dynamic configuration files in the archive. The integration should create them
at runtime and automatically migrate them if required.
- All binary and data files are overwritten.

To delete a custom integration, use the regular endpoints to delete an integration instance and driver:
- Delete integration `DELETE /api/intg/instances/:intgId`.
- Delete driver and installation files: `DELETE /api/intg/drivers/:driverId`.

Error response codes:
- `400`: invalid archive, missing data in archive or included metadata cannot be read.
- `404`: custom integration not found for updating, there's no installed custom integration with the same `driver_id`.
- `409`: custom integration is not compatible with the current firmware or the maximum amount of custom integration
installations has been reached.
- `413`: archive is too large.
Expand All @@ -1663,6 +1671,13 @@ paths:
installation and the device needs to be restarted.
- `507`: insufficient storage to upload and process installation archive.
operationId: installCustomIntegration
parameters:
- name: update
in: query
description: Update an existing custom integration.
required: false
schema:
type: boolean
requestBody:
content:
multipart/form-data:
Expand All @@ -1686,6 +1701,8 @@ paths:
$ref: '#/components/responses/Err401Unauthorized'
'403':
$ref: '#/components/responses/Err403Forbidden'
'404':
$ref: '#/components/responses/Err404NotFound'
'409':
$ref: '#/components/responses/Err409Conflict'
'413':
Expand Down
79 changes: 55 additions & 24 deletions doc/integration-driver/driver-installation.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Driver installation on the Remote
# Custom driver installation on the Remote

Starting with firmware v1.9.0, custom installation drivers can be installed on the Remote.

Expand Down Expand Up @@ -92,7 +92,7 @@ It is a reduced version of the `IntegrationDriver` object, without driver connec
A driver icon can either use a predefined icon or a custom icon. Predefined icons are prefixed with `uc:`, followed by
the icon identifier in lowercase.

A custom driver icon can be installed automatically as custom icon resource.
A custom driver icon can be installed automatically as a custom icon resource.

1. In `driver.json` set the icon field to `custom:$ICON_FILENAME`
2. Include `$ICON_FILENAME` in the root of the archive.
Expand All @@ -105,7 +105,11 @@ Example `driver.json` (other fields omitted for simplicity):
```

The icon file called `foobar.png` must be added to the root of the archive.
Icons must be of size 90x90 pixels and either in PNG or JPG format. Maximum size is 32 KB.

Icon requirements and restrictions:
- Size must be 90x90 pixels.
- Supported image formats: PNG and JPG.
- Maximum size: 16 KB.

### Installation archive example

Expand Down Expand Up @@ -140,19 +144,16 @@ Example of a Node.js based integration driver archive (contents of bin/node_modu
## Restrictions

- Maximum 10 custom integrations can be installed.
- Only Node.js is supported besides a statically linked binary. Other runtimes are not supported at the moment.
- Only Node.js is supported beside a statically linked binary. Other runtimes are not supported at the moment.
- Python integrations must pack the Python runtime into the archive.
- The integration driver runs in a sandbox. Access to devices and the filesystem is restricted.
- No symlinks are allowed. They are automatically removed during the installation.
- Executable files are only allowed in the `./bin` directory.
- No other tools are provided in the runtime environment. E.g. there is no shell available and no other tools
- No other tools are provided in the runtime environment. E.g., there is no shell available and no other tools
like `cp` or `mv`.

### Missing features

- [ ] Resource restrictions for integration drivers: limit maximum amount of memory and CPU usage.
- [ ] Update an installed integrations.
- Workaround: remove and re-install.
- [ ] Resource usage: provide memory and CPU usage per integration.
- Only the overall resource usage can be monitored with `GET /api/pub/status`.

Expand All @@ -165,7 +166,7 @@ The driver runs in a sandbox with limited access to the host system.
- `UC_INTEGRATION_HTTP_PORT`: port number.
- The working directory is set to the binary directory.
- The binary directory is read-only.
- Node.js version: v20.16 (firmware release 1.9.3 and newer).
- Node.js version: v22.22 (firmware release 2.9.2 and newer, v22.13 in firmware 2.8.2, v20.16 in firmware 1.9.3).
- There are no pre-installed node modules.
- An integration driver must include all required modules in the installation archive, including `uc-integration-api` (if used).
- File access with relative paths between `bin`, `config`, and `data` is not possible.
Expand All @@ -181,10 +182,13 @@ The driver runs in a sandbox with limited access to the host system.
- The user and group IDs may change between driver restarts.
- Write access to the `$UC_CONFIG_HOME`, `$UC_DATA_HOME` and `/tmp` directories is ensured.

⚠️ CPU and memory restrictions are not yet in place but will be enforced in a future firmware update!
- A single integration driver should not use more than 100 MB of memory.
#### Resource restrictions

A single custom integration should not use more than 100 MB of memory and conserve CPU usage.

_TODO more details about sandbox environment_
- All custom integrations (max 10) share a common memory pool of 1 GB and are limited to 200% CPU usage (2 cores).
- If the memory pool is exceeded, custom integrations will be terminated. Integrations using the most memory will be terminated first.
- A single custom integration will be throttled if it uses more than 250 MB and terminated if it uses more than 350 MB.

#### Network

Expand All @@ -205,7 +209,15 @@ a native binary for the Remote.
- The driver must be compiled as a static binary for libc.
- Most dynamic libraries in the cross-compile sysroot are NOT available in the custom integration runtime environment!

## Install driver
## Driver installation

The easiest way to manage custom integration drivers is to use the web-configurator.

### Upload a new driver

In the web-configurator open the integration view and chose _Add new, Install custom_.

#### REST API

```shell
curl --location 'http://$IP/api/intg/install' \
Expand All @@ -215,18 +227,34 @@ curl --location 'http://$IP/api/intg/install' \

See [REST Core API](https://unfoldedcircle.github.io/core-api/rest/) for more details.

## Delete driver
### Update driver

ℹ️ The driver update feature requires firmware release v2.9.3 or newer.

In the web-configurator open the integration view and chose _Add new, Install custom_ and check the
`Update existing driver` option.

#### REST API

```shell
curl --location 'http://$IP/api/intg/install?update=true' \
--user 'web-configurator:$PIN' \
--form 'file=@"custom-intg.tar.gz"'
```

### Delete driver

The integration instance and driver can be deleted in the web-configurator within the main integration view.
If there's an active instance of the custom integration driver, the instance needs to be deleted first, then the driver.

#### REST API

To delete a custom integration, use the regular endpoints to delete an integration instance and driver.
These are the same endpoints as for an external network integration driver:

- Delete integration instance `DELETE /api/intg/instances/:intgId`.
- Delete driver and installation files: `DELETE /api/intg/drivers/:driverId`.

See [REST Core API](https://unfoldedcircle.github.io/core-api/rest/) for more details.

The instance and driver can also be deleted in the web-configurator.

## Log access

Output to stdout and stderr are automatically stored with a timestamp and accessible as the other system logs:
Expand All @@ -240,7 +268,7 @@ Log files can also be downloaded in the web-configurator: _Settings, Development

### Web-app log viewer

⚠️ Available from firmware release v2.1.0
ℹ️️ Available from firmware release v2.1.0

The [Logdy](https://logdy.dev/) web application is installed on the device to monitor integration driver log events in
near real time.
Expand Down Expand Up @@ -292,10 +320,13 @@ curl --request PUT 'http://$IP/api/system/logs/web' \

## Example integrations

The following Python based integration drivers create a custom integration installation archive during build with a
GitHub action:
The following integration drivers create a custom integration installation archive during build with a GitHub action:

- [Android TV](https://github.com/unfoldedcircle/integration-androidtv)
- [Apple TV](https://github.com/unfoldedcircle/integration-appletv)
- [Denon AVR](https://github.com/unfoldedcircle/integration-denonavr)
- Node.js based:
- [Philips Hue](https://github.com/unfoldedcircle/integration-philipshue)
- [Roon](https://github.com/unfoldedcircle/integration-roon)
- Python based:
- [Android TV](https://github.com/unfoldedcircle/integration-androidtv)
- [Apple TV](https://github.com/unfoldedcircle/integration-appletv)
- [Denon AVR](https://github.com/unfoldedcircle/integration-denonavr)