Panel I/O: PanelDef.io ports, scoped publish and upload, I/O section in the Panels dialog

This commit is contained in:
Melvin Strobl
2026-10-13 21:10:54 +02:00
parent 80e595c02e
commit 659799d1e5
9 changed files with 443 additions and 14 deletions
+38
View File
@@ -2863,6 +2863,13 @@ export const PanelDefSchema = {
title: 'Touch',
default: false
},
io: {
items: {
'$ref': '#/components/schemas/PanelPort'
},
type: 'array',
title: 'Io'
},
nonce: {
type: 'integer',
title: 'Nonce',
@@ -2875,6 +2882,37 @@ export const PanelDefSchema = {
description: 'One device, and what it shows.'
} as const;
export const PanelPortSchema = {
properties: {
port: {
type: 'string',
title: 'Port'
},
message: {
type: 'string',
title: 'Message'
},
direction: {
type: 'string',
enum: ['in', 'out'],
title: 'Direction'
},
config: {
additionalProperties: true,
type: 'object',
title: 'Config'
}
},
type: 'object',
required: ['port', 'message', 'direction'],
title: 'PanelPort',
description: `One piece of the device's own hardware, wired to a message.
A wall panel is a node as well as a screen: a button on its GPIO, a
microphone, a speaker. Which ports exist is the device's business, so the
name is free text and \`\`config\`\` is passed through to it unread.`
} as const;
export const PanelsConfigSchema = {
properties: {
panels: {
+19
View File
@@ -962,9 +962,28 @@ export type PanelDef = {
title?: string;
dashboards?: Array<(string)>;
touch?: boolean;
io?: Array<PanelPort>;
nonce?: number;
};
/**
* One piece of the device's own hardware, wired to a message.
*
* A wall panel is a node as well as a screen: a button on its GPIO, a
* microphone, a speaker. Which ports exist is the device's business, so the
* name is free text and ``config`` is passed through to it unread.
*/
export type PanelPort = {
port: string;
message: string;
direction: 'in' | 'out';
config?: {
[key: string]: unknown;
};
};
export type direction = 'in' | 'out';
/**
* Every panel this instance knows about.
*/