{
  "openapi": "3.1.0",
  "info": {
    "title": "Koala AC — API кабінету",
    "version": "1.0.0",
    "summary": "Керування кондиціонерами та розумними розетками Koala AC",
    "description": "Приватний API кабінету ac.koala.ua: ним користується веб-кабінет після входу. Авторизація — сесійна cookie (PHPSESSID) після POST /login з email і паролем облікового запису клієнта. Усі відповіді — JSON. Доступ обмежений пристроями клієнта (для менеджерів — лише доступними їм локаціями). Публічних ключів API та OAuth поки немає; для інтеграцій пишіть у підтримку: https://t.me/help_koala. Документація: https://ac.koala.ua/docs",
    "contact": {
      "name": "Koala support",
      "url": "https://t.me/help_koala",
      "email": "beregovoy.ds@gmail.com"
    },
    "termsOfService": "https://ac.koala.ua/"
  },
  "servers": [
    {
      "url": "https://ac.koala.ua"
    }
  ],
  "tags": [
    {
      "name": "Auth"
    },
    {
      "name": "Devices",
      "description": "Команди пристроям та їхній стан"
    },
    {
      "name": "Data",
      "description": "Температура, вологість, споживання, історія"
    },
    {
      "name": "Dashboard"
    }
  ],
  "paths": {
    "/login": {
      "post": {
        "summary": "Вхід у кабінет (форма)",
        "description": "Стандартна форма Symfony: поля email, password, _csrf_token. Успішний вхід встановлює сесійну cookie, яку далі приймають усі /api/* маршрути.",
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "_csrf_token": {
                    "type": "string"
                  }
                },
                "required": [
                  "email",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/api/dashboard/state": {
      "get": {
        "summary": "Поточний стан усіх пристроїв клієнта",
        "description": "Компактний знімок: температури, увімкнено/вимкнено, онлайн/офлайн, ознака ручного керування з пульта. Тільки читання.",
        "tags": [
          "Dashboard"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/device/{mac}/command": {
      "post": {
        "summary": "Команда кондиціонеру",
        "description": "Надіслати ІЧ-команду: живлення, режим (cool/heat/fan/auto/dry), температура, швидкість вентилятора.",
        "tags": [
          "Devices"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "power": {
                    "type": "string",
                    "enum": [
                      "on",
                      "off"
                    ]
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "cool",
                      "heat",
                      "fan",
                      "auto",
                      "dry"
                    ]
                  },
                  "temp": {
                    "type": "integer",
                    "minimum": 16,
                    "maximum": 30
                  },
                  "fan": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/group/command": {
      "post": {
        "summary": "Групова команда",
        "description": "Та сама команда для кількох пристроїв (наприклад, уся локація). Публікується послідовно на одному з'єднанні з брокером — так надійніше, ніж паралельні запити.",
        "tags": [
          "Devices"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "macs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "power": {
                    "type": "string"
                  },
                  "mode": {
                    "type": "string"
                  },
                  "temp": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/device/{mac}/socket/{cmd}": {
      "post": {
        "summary": "Увімкнути / вимкнути розетку",
        "description": "cmd — on, off або toggle.",
        "tags": [
          "Devices"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          },
          {
            "name": "cmd",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "on",
                "off",
                "toggle"
              ]
            }
          }
        ]
      }
    },
    "/api/device/{mac}/energy": {
      "get": {
        "summary": "Споживання розетки (сирі точки)",
        "description": "Точки з лічильником kWh і миттєвою потужністю power_w за вікно from/to (зберігається 7 днів).",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Початок вікна: Y-m-d, Y-m-d H:i:s або ISO-8601 (типово — останні 24 години)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Кінець вікна (типово — зараз)"
          }
        ]
      }
    },
    "/api/device/{mac}/energy/series": {
      "get": {
        "summary": "Споживання розетки для графіка",
        "description": "Те саме, згруповане по 10-хвилинних інтервалах — як температурні серії.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Початок вікна: Y-m-d, Y-m-d H:i:s або ISO-8601 (типово — останні 24 години)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Кінець вікна (типово — зараз)"
          }
        ]
      }
    },
    "/api/location/{id}/energy": {
      "get": {
        "summary": "Споживання локації",
        "description": "Сума по всіх доступних розетках локації.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID локації"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Початок вікна: Y-m-d, Y-m-d H:i:s або ISO-8601 (типово — останні 24 години)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Кінець вікна (типово — зараз)"
          }
        ]
      }
    },
    "/api/device/{mac}/climate": {
      "get": {
        "summary": "Температура й вологість пристрою",
        "description": "Серія показань датчика пульта за вікно from/to, 10-хвилинні інтервали.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Початок вікна: Y-m-d, Y-m-d H:i:s або ISO-8601 (типово — останні 24 години)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Кінець вікна (типово — зараз)"
          }
        ]
      }
    },
    "/api/location/{id}/climate": {
      "get": {
        "summary": "Клімат локації",
        "description": "Середні температура й вологість по локації плюс серії кожного пристрою (items: mac, name).",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID локації"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Початок вікна: Y-m-d, Y-m-d H:i:s або ISO-8601 (типово — останні 24 години)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Кінець вікна (типово — зараз)"
          }
        ]
      }
    },
    "/api/activity/history": {
      "get": {
        "summary": "Історія дій",
        "description": "Останні події по пристроях клієнта: хто, коли, яку команду надіслав; спрацювання розкладів; натискання штатного пульта.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/activity/presence": {
      "get": {
        "summary": "Епізоди офлайну",
        "description": "Коли кожен пристрій втратив зв'язок і коли повернувся; відкритий епізод — пристрій досі офлайн.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/sockets/idle": {
      "get": {
        "summary": "Розетки, які варто вимкнути",
        "description": "Розетки, що споживають вище власного порогу простою поза робочими годинами локації. Лише звіт — вимикання через /socket/{cmd}.",
        "tags": [
          "Dashboard"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/ir/identify": {
      "post": {
        "summary": "Визначити марку кондиціонера",
        "description": "Запускає розпізнавання ІЧ-протоколу за натисканням штатного пульта.",
        "tags": [
          "Devices"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/device/{mac}/preset/{presetId}": {
      "post": {
        "summary": "Призначити ІЧ-пресет",
        "description": "Вручну прив'язати до пристрою протокол/пресет кондиціонера.",
        "tags": [
          "Devices"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "name": "mac",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "MAC-адреса пристрою (12 hex-символів, як у кабінеті)"
          },
          {
            "name": "presetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "PHPSESSID",
        "description": "Сесія після входу через /login"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Немає сесії — увійдіть через /login"
      },
      "Forbidden": {
        "description": "Пристрій або локація не належать вашому клієнту"
      }
    }
  }
}