{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://leukos.local/schemas/domotics-room-v1.json",
  "title": "LeukOS domotics room configuration",
  "type": "object",
  "additionalProperties": false,
  "$defs": {
    "timer": {
      "type": "object",
      "additionalProperties": false,
      "required": ["enabled", "mode"],
      "properties": {
        "enabled": { "const": true },
        "mode": { "enum": ["once", "range", "daily"] },
        "date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
        "time": { "type": "string", "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$" },
        "start": { "type": "string", "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$" },
        "end": { "type": "string", "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$" },
        "action": { "enum": ["on", "off"] }
      },
      "allOf": [
        { "if": { "properties": { "mode": { "const": "once" } } }, "then": { "required": ["date", "time", "action"] } },
        { "if": { "properties": { "mode": { "const": "daily" } } }, "then": { "required": ["time", "action"] } },
        { "if": { "properties": { "mode": { "const": "range" } } }, "then": { "required": ["start", "end"] } }
      ]
    }
  },
  "required": ["schema", "version", "id", "name", "controller", "modules"],
  "properties": {
    "schema": { "const": "leukos.domotics.room" },
    "version": { "const": 1 },
    "id": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,80}$" },
    "name": { "type": "string", "minLength": 1, "maxLength": 80 },
    "icon": { "type": "string" },
    "controller": {
      "type": "object",
      "required": ["board", "port"],
      "properties": {
        "board": { "type": "string" },
        "port": { "type": "string", "pattern": "^tcp://" }
      }
    },
    "modules": {
      "type": "object",
      "minProperties": 1,
      "maxProperties": 16,
      "propertyNames": { "pattern": "^m_[a-f0-9]{12}$" },
      "additionalProperties": {
        "type": "object",
        "required": ["name", "type", "kind"],
        "allOf": [
          {
            "if": { "properties": { "type": { "const": "power_strip" } } },
            "then": { "required": ["outletCount", "outlets"] },
            "else": { "required": ["pin"] }
          }
        ],
        "properties": {
          "name": { "type": "string", "minLength": 1, "maxLength": 80 },
          "type": {
            "enum": ["lamp", "ceiling", "fan", "socket", "power_strip", "washer", "valve", "temperature", "analog", "presence"]
          },
          "kind": { "enum": ["relay", "power_strip", "sensor"] },
          "pin": { "type": "string" },
          "outletCount": { "type": "integer", "minimum": 2, "maximum": 8 },
          "outlets": {
            "type": "array",
            "minItems": 2,
            "maxItems": 8,
            "items": {
              "type": "object",
              "required": ["id", "name", "pin", "activeLow"],
              "properties": {
                "id": { "type": "string", "pattern": "^m_[a-f0-9]{12}$" },
                "name": { "type": "string", "minLength": 1, "maxLength": 80 },
                "connectedDevice": { "type": "string", "maxLength": 48 },
                "connectedIcon": { "enum": ["power", "lamp", "fan", "phone", "water_fountain"] },
                "timer": { "$ref": "#/$defs/timer" },
                "pin": { "type": "string" },
                "activeLow": { "type": "boolean" },
                "input": { "type": "string" },
                "type": { "const": "socket" },
                "kind": { "const": "relay" },
                "target": { "type": "string" }
              }
            }
          },
          "activeLow": { "type": "boolean" },
          "timer": { "$ref": "#/$defs/timer" },
          "referenceVoltage": { "type": "number", "minimum": 1.0, "maximum": 5.5 },
          "target": { "type": "string" },
          "icon": { "type": "string" },
          "unit": { "type": "string" },
          "min": { "type": "number" },
          "max": { "type": "number" }
        }
      }
    }
  }
}
