{
    "openapi": "3.0.0",
    "info": {
        "version": "1.1.0",
        "title": "KIP Plugin API",
        "description": "Endpoints\n- List remote displays and control remote dashboard of a given KIP instance.\n- Configure data series for widget framework historical data series and data chart widgets.",
        "termsOfService": "http://signalk.org/terms/",
        "license": {
            "name": "Apache 2.0",
            "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
        }
    },
    "externalDocs": {
        "url": "http://signalk.org/specification/",
        "description": "Signal K specification."
    },
    "servers": [
        {
            "url": "/"
        }
    ],
    "tags": [
        {
            "name": "Displays",
            "description": "KIP remote display discovery and control."
        },
        {
            "name": "Series",
            "description": "KIP widget history series configuration."
        }
    ],
    "components": {
        "schemas": {
            "DisplayInfo": {
                "type": "object",
                "properties": {
                    "displayId": {
                        "type": "string",
                        "description": "KIP instance UUID"
                    },
                    "displayName": {
                        "type": "string",
                        "nullable": true
                    }
                },
                "required": [
                    "displayId"
                ]
            },
            "ScreenItem": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "icon": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "icon"
                ]
            },
            "ScreenListOrNull": {
                "type": "array",
                "nullable": true,
                "items": {
                    "$ref": "#/components/schemas/ScreenItem"
                }
            },
            "SuccessResponse": {
                "type": "object",
                "properties": {
                    "state": {
                        "type": "string",
                        "enum": [
                            "SUCCESS"
                        ]
                    },
                    "statusCode": {
                        "type": "integer",
                        "enum": [
                            200
                        ]
                    }
                },
                "required": [
                    "state",
                    "statusCode"
                ]
            },
            "ErrorResponse": {
                "type": "object",
                "properties": {
                    "state": {
                        "type": "string",
                        "enum": [
                            "FAILED"
                        ]
                    },
                    "statusCode": {
                        "type": "integer"
                    },
                    "message": {
                        "type": "string"
                    }
                },
                "required": [
                    "state",
                    "statusCode",
                    "message"
                ]
            },
            "ActiveScreenSetRequest": {
                "type": "object",
                "properties": {
                    "screenIdx": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Index of active screen or null to clear"
                    }
                }
            },
            "AnyObjectOrNull": {
                "type": "object",
                "nullable": true,
                "additionalProperties": true
            },
            "SeriesDefinitionBase": {
                "type": "object",
                "properties": {
                    "seriesId": {
                        "type": "string"
                    },
                    "datasetUuid": {
                        "type": "string"
                    },
                    "ownerWidgetUuid": {
                        "type": "string"
                    },
                    "ownerWidgetSelector": {
                        "type": "string",
                        "nullable": true
                    },
                    "path": {
                        "type": "string"
                    },
                    "context": {
                        "type": "string",
                        "nullable": true
                    },
                    "source": {
                        "type": "string",
                        "nullable": true
                    },
                    "timeScale": {
                        "type": "string",
                        "nullable": true
                    },
                    "period": {
                        "type": "integer",
                        "nullable": true
                    },
                    "retentionDurationMs": {
                        "type": "integer",
                        "nullable": true
                    },
                    "sampleTime": {
                        "type": "integer",
                        "nullable": true
                    },
                    "enabled": {
                        "type": "boolean",
                        "default": true
                    },
                    "methods": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "min",
                                "max",
                                "avg",
                                "sma",
                                "ema"
                            ]
                        }
                    },
                    "reconcileTs": {
                        "type": "integer",
                        "nullable": true
                    }
                },
                "required": [
                    "seriesId",
                    "datasetUuid",
                    "ownerWidgetUuid",
                    "ownerWidgetSelector",
                    "path",
                    "enabled"
                ]
            },
            "ConcreteSeriesDefinition": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/SeriesDefinitionBase"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "expansionMode": {
                                "nullable": true,
                                "description": "Null for concrete series definitions."
                            },
                            "familyKey": {
                                "type": "string",
                                "nullable": true,
                                "description": "Concrete series do not use family key and should leave this null."
                            },
                            "allowedIds": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                    "type": "string"
                                },
                                "description": "Concrete series do not use template filters and should leave this null."
                            },
                            "trackedDevices": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string"
                                        },
                                        "source": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "source"
                                    ]
                                },
                                "description": "Concrete series do not use tracked device template filters and should leave this null."
                            }
                        }
                    }
                ]
            },
            "TemplateSeriesDefinition": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/SeriesDefinitionBase"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "ownerWidgetSelector": {
                                "type": "string",
                                "enum": [
                                    "widget-bms",
                                    "widget-solar-charger",
                                    "widget-charger",
                                    "widget-inverter",
                                    "widget-alternator",
                                    "widget-ac"
                                ]
                            },
                            "expansionMode": {
                                "type": "string",
                                "enum": [
                                    "bms-battery-tree",
                                    "solar-tree",
                                    "charger-tree",
                                    "inverter-tree",
                                    "alternator-tree",
                                    "ac-tree"
                                ]
                            },
                            "familyKey": {
                                "type": "string",
                                "enum": [
                                    "batteries",
                                    "solar",
                                    "chargers",
                                    "inverters",
                                    "alternators",
                                    "ac"
                                ]
                            },
                            "allowedIds": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                    "type": "string"
                                },
                                "description": "Template device IDs to include. Null or empty includes all discovered devices."
                            },
                            "trackedDevices": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string"
                                        },
                                        "source": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "source"
                                    ]
                                },
                                "description": "Explicit tracked device id/source pairs to expand. When provided, template expansion skips self-tree discovery and emits one concrete series per pair and metric."
                            }
                        },
                        "required": [
                            "ownerWidgetSelector",
                            "expansionMode",
                            "familyKey"
                        ]
                    }
                ]
            },
            "SeriesDefinition": {
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/ConcreteSeriesDefinition"
                    },
                    {
                        "$ref": "#/components/schemas/TemplateSeriesDefinition"
                    }
                ]
            },
            "SeriesReconcileResult": {
                "type": "object",
                "properties": {
                    "created": {
                        "type": "integer"
                    },
                    "updated": {
                        "type": "integer"
                    },
                    "deleted": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    }
                },
                "required": [
                    "created",
                    "updated",
                    "deleted",
                    "total"
                ]
            }
        },
        "parameters": {
            "DisplayIdParam": {
                "in": "path",
                "required": true,
                "name": "displayId",
                "description": "KIP instance UUID",
                "schema": {
                    "type": "string"
                }
            },
            "SeriesIdParam": {
                "in": "path",
                "required": true,
                "name": "seriesId",
                "description": "Series identifier (dataset UUID)",
                "schema": {
                    "type": "string"
                }
            }
        },
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            },
            "cookieAuth": {
                "type": "apiKey",
                "in": "cookie",
                "name": "JAUTHENTICATION"
            }
        }
    },
    "security": [
        {
            "cookieAuth": []
        },
        {
            "bearerAuth": []
        }
    ],
    "paths": {
        "/plugins/kip/displays": {
            "get": {
                "tags": [
                    "Displays"
                ],
                "summary": "List available KIP displays",
                "responses": {
                    "200": {
                        "description": "List of KIP instances discovered under self.displays",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/DisplayInfo"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/displays/{displayId}": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DisplayIdParam"
                }
            ],
            "get": {
                "tags": [
                    "Displays"
                ],
                "summary": "List screens for a display (self.displays.{displayId}.value.screens)",
                "responses": {
                    "200": {
                        "description": "Array of screen entries (or null)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ScreenListOrNull"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Displays"
                ],
                "summary": "Set display entry under self.displays.{displayId}",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AnyObjectOrNull"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/displays/{displayId}/screenIndex": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DisplayIdParam"
                }
            ],
            "get": {
                "tags": [
                    "Displays"
                ],
                "summary": "Get current screen index for display (self.displays.{displayId}.screenIndex)",
                "responses": {
                    "200": {
                        "description": "Current screen index or null",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "integer",
                                    "nullable": true
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Displays"
                ],
                "summary": "Set current screen index for display (self.displays.{displayId}.screenIndex)",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ActiveScreenSetRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/displays/{displayId}/activeScreen": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DisplayIdParam"
                }
            ],
            "get": {
                "tags": [
                    "Displays"
                ],
                "summary": "Get requested screen change index (self.displays.{displayId}.activeScreen)",
                "responses": {
                    "200": {
                        "description": "Requested screen index or null",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "integer",
                                    "nullable": true
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "tags": [
                    "Displays"
                ],
                "summary": "Request a screen change (sets self.displays.{displayId}.activeScreen)",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ActiveScreenSetRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/series": {
            "get": {
                "tags": [
                    "Series"
                ],
                "summary": "List all configured history series",
                "responses": {
                    "200": {
                        "description": "Current series definitions",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/SeriesDefinition"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/series/{seriesId}": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/SeriesIdParam"
                }
            ],
            "put": {
                "tags": [
                    "Series"
                ],
                "summary": "Create or update a series definition",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SeriesDefinition"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Series upserted",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SeriesDefinition"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Series"
                ],
                "summary": "Delete a series definition",
                "responses": {
                    "200": {
                        "description": "Series removed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SuccessResponse"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Series not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/plugins/kip/series/reconcile": {
            "post": {
                "tags": [
                    "Series"
                ],
                "summary": "Reconcile full desired series set",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/SeriesDefinition"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Reconcile summary",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SeriesReconcileResult"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Bad request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ErrorResponse"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
