# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: keyapis/telemetry_control/v1/keyapis_telemetry_control_building_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_device_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_dictionary_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_events_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_metric_point_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_stream_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_system_v1.proto, keyapis/telemetry_control/v1/keyapis_telemetry_control_template_v1.proto
# plugin: python-betterproto
# This file has been @generated
import warnings
from collections.abc import (
    AsyncIterable,
    AsyncIterator,
    Iterable,
)
from datetime import datetime
from typing import TYPE_CHECKING

import betterproto
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase
from pydantic import model_validator
from pydantic.dataclasses import (
    dataclass,
    rebuild_dataclass,
)

if TYPE_CHECKING:
    import grpclib.server
    from betterproto.grpc.grpclib_client import MetadataLike
    from grpclib.metadata import Deadline


class TemplateDevicePagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По идентификатору"""

    METRIC_TYPE = 2
    """По типу энергоресурса"""

    MODEL = 3
    """По модели счетчика"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateDevicePagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateDeviceMetricType(betterproto.Enum):
    """Справочние типов энергоресурсов"""

    METRIC_TYPE_UNKNOWN = 0
    """Значение не указано"""

    HOT_WATER = 1
    """Горячая вода"""

    COLD_WATER = 2
    """Холодная вода"""

    HEAT = 3
    """Теплоэнергия"""

    GAS = 4
    """Газ"""

    ELECTRICITY = 5
    """Электроэнергия"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateDevicePlanType(betterproto.Enum):
    """Тип тарифного плана"""

    PLAN_TYPE_UNKNOWN = 0
    """Значение не указано"""

    SINGLE = 1
    """Однотарифный"""

    DOUBLE = 2
    """Двухтарифный"""

    TRIPLE = 3
    """Трёхтарифный"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorPagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По идентификатору"""

    SIGN_TYPE = 2
    """По типу измерений"""

    ARCHIVE_TYPE = 3
    """По типу архивности показаний"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorVendorType(betterproto.Enum):
    """Посредники получения показаний"""

    VENDOR_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ENVIRO = 1
    """Энвайро"""

    LARTECH = 2
    """Лартех"""

    RTK = 3
    """РТК"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorUnitType(betterproto.Enum):
    """Справочник типов единиц измерений"""

    UNIT_TYPE_UNKNOWN = 0
    """Значение не указано"""

    PERCENT = 1
    """Процент"""

    C = 2
    """Градус по Цельсию"""

    WT = 3
    """Ватт"""

    GKAL = 4
    """Гигакалория"""

    VALUE = 5
    """Количество"""

    KWH = 6
    """Киловaтт-час"""

    KG_CM2 = 7
    """Килограмм на квадратный сантиметр"""

    KGF_CM2 = 8
    """Килограмм-сила на квадратный сантиметр"""

    M3 = 9
    """Кубический метр"""

    M3_H = 10
    """Кубический метр в час"""

    MPA = 11
    """Мегапаскаль"""

    MS = 12
    """Миллисекунда"""

    BOOLEAN = 13
    """Флаг состояния"""

    T = 14
    """Тонна"""

    T_H = 15
    """Тонна в час"""

    H = 16
    """Час"""

    NON_MEASURABLE = 17
    """Безразмерная величина"""

    IMP = 18
    """Импульс"""

    J = 19
    """Джоуль"""

    KJ = 20
    """Килоджоуль"""

    GJ = 21
    """Гигаджоуль"""

    WTH = 22
    """Ватт-час"""

    KWT = 23
    """Киловатт"""

    MIN = 24
    """Минута"""

    S = 25
    """Секунда"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorSignType(betterproto.Enum):
    """Справочник типов измерений"""

    SIGN_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ABSOLUTE_DS = 1
    """Абсолютный показатель"""

    ABSOLUTE_RC = 2
    """Абсолютный расход ресурса"""

    INTERVAL_DS = 3
    """Интервальный показатель состояния"""

    INTERVAL_RC = 4
    """Интервальный расход ресурса"""

    CURRENT_DS = 5
    """Текущее состояние"""

    CURRENT_RS = 6
    """Текущее состояние ресурса"""

    VOLUME = 7
    """Объём"""

    PARAMETER = 8
    """Параметр конфигурации"""

    FLAG = 9
    """Флаг состояния"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class TemplateIndicatorArchiveType(betterproto.Enum):
    """
    Справочник типа архивности показаний.
     Используется для указания за какой период произошло измерение.
     По умолчанию CURRENT
    """

    ARCHIVE_TYPE_UNKNOWN = 0
    """Значение не указано"""

    CURRENT = 1
    """Текущие показания"""

    HALFHOUR = 2
    """За 30 мин"""

    HOUR = 3
    """За час"""

    DAY = 4
    """За суток"""

    MONTH = 5
    """За месяц"""

    YEAR = 6
    """За год"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingGroupPagingOrderByType(betterproto.Enum):
    """Справочник типов сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    GROUP_ID = 1
    """По Идентификатору группы пользователя"""

    BUILDING_ID = 2
    """По Объекту строительства"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingGroupPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingPagingOrderByType(betterproto.Enum):
    """Справочник типов сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По уникальному ключу"""

    TITLE = 2
    """По наименованию"""

    CREATED_AT = 3
    """По дате создания"""

    CHANGED_AT = 4
    """По дате изменения"""

    FIAS_ID = 5
    """По ФИАС"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingMrfType(betterproto.Enum):
    """Справочник МРФ (Макрорегионы)"""

    MRF_TYPE_UNKNOWN = 0
    """Значение не указано"""

    TSENTR = 1
    """Центр"""

    YUG = 2
    """Юг"""

    URAL = 3
    """Урал"""

    SIBIR = 4
    """Сибирь"""

    SEVERO_ZAPAD = 5
    """Северо-Запад"""

    DALNIY_VOSTOK = 6
    """Дальний Восток"""

    VOLGA = 7
    """Волга"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingRfType(betterproto.Enum):
    """Справочник РФ (Регионы)"""

    RF_TYPE_UNKNOWN = 0
    """Значение не указано"""

    UFA = 1
    """Республика Башкортостан"""

    KIROV = 2
    """Кировская область"""

    IVANOVO = 3
    """Ивановский филиал"""

    KALUGA = 4
    """Калужский филиал"""

    KOSTROMA = 5
    """Костромской филиал"""

    KURSK = 6
    """Курский филиал"""

    LIPETSK = 7
    """Липецкий филиал"""

    MOSOBLAST = 8
    """Московская область"""

    OREL = 9
    """Орловский филиал"""

    RYAZAN = 10
    """Рязанский филиал"""

    TAMBOV = 11
    """Тамбовский филиал"""

    TVER = 12
    """Тверской филиал"""

    YAROSLAVL = 13
    """Ярославский филиал"""

    SMOLENSK = 14
    """Смоленский филиал"""

    TULA = 15
    """Тульский филиал"""

    MOSCOW = 16
    """Москва"""

    EAO = 17
    """ЕАО"""

    KURGAN = 18
    """Филиал в Тюменской и Курганской областях"""

    TUMEN = 19
    """Филиал в Тюменской и Курганской областях"""

    HANTY = 20
    """Ханты-Мансийский филиал"""

    AMUR = 21
    """Амурская область"""

    KAMCHATKA = 22
    """Камчатский край"""

    MAGADAN = 23
    """Магаданская область"""

    PRIMORYE = 24
    """Приморский край"""

    SAKHALIN = 25
    """Сахалинская область"""

    KHABAROVSK = 26
    """Хабаровский край"""

    CHITA = 27
    """Забайкальский край"""

    CHUKOTKA = 28
    """ЧАО"""

    ARCHANGELSK = 29
    """Архангельск"""

    VOLOGDA = 30
    """Вологда"""

    KALININGRAD = 31
    """Калининград"""

    KARELIA = 32
    """Карелия"""

    KOMI = 33
    """Коми"""

    LENOBLAST = 34
    """Лен область"""

    MURMANSK = 35
    """Мурманск"""

    NOVGOROD = 36
    """Новгород"""

    PSKOV = 37
    """Псков"""

    SPB = 38
    """СПб"""

    ALTAI = 39
    """Алтайский филиал"""

    BURYATIYA = 40
    """Бурятский филиал"""

    IRKUTSK = 41
    """Иркутский филиал"""

    KEMEROVO = 42
    """Кемеровский филиал"""

    KRASNOYARSK = 43
    """Красноярский филиал"""

    OMSK = 44
    """Омский филиал"""

    HAKASIYA = 45
    """Республика Хакасия"""

    RALTAY = 46
    """Республика Алтай"""

    TUVA = 47
    """Республика Тыва"""

    TOMSK = 48
    """Томский филиал"""

    ORENBURG = 49
    """Оренбургская область"""

    BELGOROD = 50
    """Белгородский филиал"""

    SAKHA = 51
    """Саха"""

    EKT = 52
    """Екатеринбургский филиал"""

    VOLGOGRAD = 53
    """Волгоградский филиал"""

    YAMAL = 54
    """Ямало-Ненецкий филиал"""

    CHELYABINSK = 55
    """Челябинский филиал"""

    PERM = 56
    """Пермский филиал ПАО "Ростелеком"""

    MARYEL = 57
    """Республика Марий Эл"""

    PENZA = 58
    """Пензенская область"""

    INGUSHETIA = 59
    """Ингушский филиал"""

    NALCHIK = 60
    """Кабардино-Балкарский филиал"""

    ELISTA = 61
    """Калмыцкий филиал"""

    ROSTOV = 62
    """Ростовский филиал"""

    MAHACHKALA = 63
    """Дагестанский филиал"""

    MORDOVIYA = 64
    """Республика Мордовия"""

    KAZAN = 65
    """Республика Татарстан (Татарстан)"""

    SAMARA = 66
    """Самарская область"""

    SARATOV = 67
    """Саратовская область"""

    UDMURTIYA = 68
    """Удмуртская Республика"""

    ULYANOVSK = 69
    """Ульяновская область"""

    CHUVASHIYA = 70
    """Чувашская Республика - Чувашия"""

    NNOVGOROD = 71
    """Нижегородская область"""

    BRYANSK = 72
    """Брянский филиал"""

    VLADIMIR = 73
    """Владимирский филиал"""

    VORONEZH = 74
    """Воронежский филиал"""

    VLADIKAVKAZ = 75
    """Северо-Осетинский филиал"""

    STAVROPOL = 76
    """Ставропольский филиал"""

    CHERKESSK = 77
    """Республика Карачаево-Черкесская"""

    MAYKOP = 78
    """Республика Адыгея"""

    ASTRAKHAN = 79
    """Астраханский филиал"""

    KRASNODAR = 80
    """Краснодарский филиал"""

    TEST = 81
    """Тестовый"""

    NOVOSIBIRSK = 82
    """Новосибирский филиал"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class BuildingStatusType(betterproto.Enum):
    """Статусы объектов строительства"""

    STATUS_TYPE_UNKNOWN = 0
    """Значение не указано"""

    BUILDING = 1
    """СМР"""

    ACCEPTANCE = 2
    """Реализован"""

    ACTIVE = 3
    """Обслуживание"""

    ARCHIVE = 4
    """Снят с обслуживания"""

    CANCELLED = 5
    """Отказ от заключения договора"""

    TEST_STATUS_TYPE = 6
    """Тестовый"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceGroupPagingOrderByType(betterproto.Enum):
    """Справочник типов сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    GROUP_ID = 1
    """По Идентификатору группы пользователя"""

    DEVICE_ID = 2
    """По ПУ"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceGroupPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorPagingOrderByType(betterproto.Enum):
    """Справочник типов сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По уникальному ключу"""

    SIGN_TYPE = 2
    """По типу измерений"""

    DEVICE_ID = 3
    """По Прибору учета"""

    CREATED_AT = 4
    """По Дате создания"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorVendorType(betterproto.Enum):
    """Посредники получения показаний"""

    VENDOR_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ENVIRO = 1
    """Энвайро"""

    LARTECH = 2
    """Лартех"""

    RTK = 3
    """РТК"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorUnitType(betterproto.Enum):
    """Справочник типов единиц измерений"""

    UNIT_TYPE_UNKNOWN = 0
    """Значение не указано"""

    PERCENT = 1
    """Процент"""

    C = 2
    """Градус по Цельсию"""

    WT = 3
    """Ватт"""

    GKAL = 4
    """Гигакалория"""

    VALUE = 5
    """Количество"""

    KWH = 6
    """Киловaтт-час"""

    KG_CM2 = 7
    """Килограмм на квадратный сантиметр"""

    KGF_CM2 = 8
    """Килограмм-сила на квадратный сантиметр"""

    M3 = 9
    """Кубический метр"""

    M3_H = 10
    """Кубический метр в час"""

    MPA = 11
    """Мегапаскаль"""

    MS = 12
    """Миллисекунда"""

    BOOLEAN = 13
    """Флаг состояния"""

    T = 14
    """Тонна"""

    T_H = 15
    """Тонна в час"""

    H = 16
    """Час"""

    NON_MEASURABLE = 17
    """Безразмерная величина"""

    IMP = 18
    """Импульс"""

    J = 19
    """Джоуль"""

    KJ = 20
    """Килоджоуль"""

    GJ = 21
    """Гигаджоуль"""

    WTH = 22
    """Ватт-час"""

    KWT = 23
    """Киловатт"""

    MIN = 24
    """Минута"""

    S = 25
    """Секунда"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorSignType(betterproto.Enum):
    """Справочник типов измерений"""

    SIGN_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ABSOLUTE_DS = 1
    """Абсолютный показатель"""

    ABSOLUTE_RC = 2
    """Абсолютный расход ресурса"""

    INTERVAL_DS = 3
    """Интервальный показатель состояния"""

    INTERVAL_RC = 4
    """Интервальный расход ресурса"""

    CURRENT_DS = 5
    """Текущее состояние"""

    CURRENT_RS = 6
    """Текущее состояние ресурса"""

    VOLUME = 7
    """Объём"""

    PARAMETER = 8
    """Параметр конфигурации"""

    FLAG = 9
    """Флаг состояния"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class IndicatorArchiveType(betterproto.Enum):
    """
    Справочник типа архивности показаний.
     Используется для указания за какой период произошло измерение.
     По умолчанию CURRENT
    """

    ARCHIVE_TYPE_UNKNOWN = 0
    """Значение не указано"""

    CURRENT = 1
    """Текущие показания"""

    HALFHOUR = 2
    """За 30 мин"""

    HOUR = 3
    """За час"""

    DAY = 4
    """За сутки"""

    MONTH = 5
    """За месяц"""

    YEAR = 6
    """За год"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceSecondaryCurrentType(betterproto.Enum):
    """
    Справочник типов номинальных нагрузок вторичных обмоток.
     У трансформаторов тока (В*А)
    """

    SECONDARY_CURRENT_TYPE_UNKNOWN = 0
    """Значение не указано"""

    TT1A = 1
    """1 (А)"""

    TT2A = 2
    """2 (А)"""

    TT5A = 3
    """5 (А)"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceType(betterproto.Enum):
    """Справочник типов приборов учёта(ПУ)"""

    TYPE_UNKNOWN = 0
    """Значение не указано"""

    HUB = 1
    """Коммуникационный модуль"""

    PULSE_COUNTER_RECORDER = 2
    """Счетчик импульсов - регистратор"""

    PULSE_COUNTER_RECORDER_LR = 3
    """Счетчик импульсов - регистратор LoRaWAN"""

    METERING_DEVICE = 4
    """Прибор учета расхода коммунальных услуг"""

    INTERFACE_CONVERTER = 5
    """Конвертер интерфейсов"""

    M_BUS_HUB = 6
    """M-BUS концентратор"""

    COMMUNICATION_MODULE_LR = 7
    """Модуль связи LoRaWAN"""

    BASE_LR = 8
    """Базовая станция LoRaWAN"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceStatusType(betterproto.Enum):
    """Справочник типов статусов"""

    STATUS_TYPE_UNKNOWN = 0
    """Значение не указано"""

    RECEIVED = 1
    """Получен клиентом, еще не сконфигурирован"""

    ACTIVE = 2
    """Сконфигурирован клиентом, активен"""

    WRONG = 3
    """Обработан клиентом, возникла ошибка"""

    ARCHIVE = 4
    """Переведен в архивный статус"""

    DELETE = 5
    """Удален"""

    UNLINK = 6
    """Отсоединен"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DevicePlanType(betterproto.Enum):
    """Справочник типов тарифных планов"""

    PLAN_TYPE_UNKNOWN = 0
    """Значение не указано"""

    SINGLE = 1
    """Однотарифный"""

    DOUBLE = 2
    """Двухтарифный"""

    TRIPLE = 3
    """Трёхтарифный"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DevicePipeType(betterproto.Enum):
    """Справочник типов трубопроводов"""

    PIPE_TYPE_UNKNOWN = 0
    """Значение не указано"""

    INFEED = 1
    """Подающий"""

    CIRCULATING = 2
    """Циркуляционный"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceMetricPointMetricType(betterproto.Enum):
    """Справочние типов энергоресурсов"""

    METRIC_TYPE_UNKNOWN = 0
    """Значение не указано"""

    HOT_WATER = 1
    """Горячая вода"""

    COLD_WATER = 2
    """Холодная вода"""

    HEAT = 3
    """Теплоэнергия"""

    GAS = 4
    """Газ"""

    ELECTRICITY = 5
    """Электроэнергия"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceMetricPointStatusType(betterproto.Enum):
    """Справочник типов статусов"""

    STATUS_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ACTIVE = 1
    """Активная"""

    WRONG = 2
    """Не активная"""

    ARCHIVE = 3
    """Архивная"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceMetricPointAccountingType(betterproto.Enum):
    """Справочник типов учёта"""

    ACCOUNTING_TYPE_UNKNOWN = 0
    """Значение не указано"""

    COMMERCIAL = 1
    """Коммерческий учёт"""

    TECHNICAL = 2
    """Технический учёт"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceMetricPointPrimaryCurrentType(betterproto.Enum):
    """
    Справочник типов номиналов первичных токов.
     У выпускаемых трансформаторов тока (А)
    """

    PRIMARY_CURRENT_TYPE_UNKNOWN = 0
    """Значение не указано"""

    TT1A = 1
    """1 (А)"""

    TT5A = 2
    """5 (А)"""

    TT10A = 3
    """10 (А)"""

    TT15A = 4
    """15 (А)"""

    TT20A = 5
    """20 (А)"""

    TT30A = 6
    """30 (А)"""

    TT40A = 7
    """40 (А)"""

    TT50A = 8
    """50 (А)"""

    TT75A = 9
    """75 (А)"""

    TT80A = 10
    """80 (А)"""

    TT100A = 11
    """100 (А)"""

    TT150A = 12
    """150 (А)"""

    TT200A = 13
    """200 (А)"""

    TT300A = 14
    """300 (А)"""

    TT400A = 15
    """400 (А)"""

    TT500A = 16
    """500 (А)"""

    TT600A = 17
    """600 (А)"""

    TT750A = 18
    """750 (А)"""

    TT800A = 19
    """800 (А)"""

    TT1000A = 20
    """1000 (А)"""

    TT1200A = 21
    """1200 (А)"""

    TT1500A = 22
    """1500 (А)"""

    TT2000A = 23
    """2000 (А)"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DevicePagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По идентификатору"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DevicePagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceIndicatorMetricPointPagingOrderByType(betterproto.Enum):
    """Справочник типов сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    INDICATOR_ID = 1
    """По Идентификатору индикатора"""

    METRIC_POINT_ID = 2
    """По По Идентификатору ТУ"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DeviceIndicatorMetricPointPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class MetricPointPagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По идентификатору"""

    METRIC_TYPE = 2
    """По типу энергоресурса"""

    STATUS_TYPE = 3
    """По типу статуса"""

    ROOM_NUMBER = 4
    """По Номеру помещения"""

    ROOM_LABEL = 5
    """По Лейблу помещения"""

    BUILDING_ID = 6
    """По идентификатору объекта строительства"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class MetricPointPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DictionaryDeviceModelPagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ID = 1
    """По идентификатору"""

    TITLE = 2
    """По заголовку элемента"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DictionaryDeviceModelPagingDirectionType(betterproto.Enum):
    """
    Справочник типов направлений сортировки.
     По умолчанию: ASC
    """

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DictionaryMrfMrfType(betterproto.Enum):
    """Справочник Макрорегионы (МРФ)"""

    MRF_TYPE_UNKNOWN = 0
    """Значение не указано"""

    TSENTR = 1
    """Центр"""

    YUG = 2
    """Юг"""

    URAL = 3
    """Урал"""

    SIBIR = 4
    """Сибирь"""

    SEVERO_ZAPAD = 5
    """Северо-Запад"""

    DALNIY_VOSTOK = 6
    """Дальний Восток"""

    VOLGA = 7
    """Волга"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DictionaryPermissionPermissionType(betterproto.Enum):
    """Справочник Разрешения Телеметрии"""

    PERMISSION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class DictionaryRfRfType(betterproto.Enum):
    """Справочник Регионы (РФ)"""

    RF_TYPE_UNKNOWN = 0
    """Значение не указано"""

    UFA = 1
    """Республика Башкортостан"""

    KIROV = 2
    """Кировская область"""

    IVANOVO = 3
    """Ивановский филиал"""

    KALUGA = 4
    """Калужский филиал"""

    KOSTROMA = 5
    """Костромской филиал"""

    KURSK = 6
    """Курский филиал"""

    LIPETSK = 7
    """Липецкий филиал"""

    MOSOBLAST = 8
    """Московская область"""

    OREL = 9
    """Орловский филиал"""

    RYAZAN = 10
    """Рязанский филиал"""

    TAMBOV = 11
    """Тамбовский филиал"""

    TVER = 12
    """Тверской филиал"""

    YAROSLAVL = 13
    """Ярославский филиал"""

    SMOLENSK = 14
    """Смоленский филиал"""

    TULA = 15
    """Тульский филиал"""

    MOSCOW = 16
    """Москва"""

    EAO = 17
    """ЕАО"""

    KURGAN = 18
    """Филиал в Тюменской и Курганской областях"""

    TUMEN = 19
    """Филиал в Тюменской и Курганской областях"""

    HANTY = 20
    """Ханты-Мансийский филиал"""

    AMUR = 21
    """Амурская область"""

    KAMCHATKA = 22
    """Камчатский край"""

    MAGADAN = 23
    """Магаданская область"""

    PRIMORYE = 24
    """Приморский край"""

    SAKHALIN = 25
    """Сахалинская область"""

    KHABAROVSK = 26
    """Хабаровский край"""

    CHITA = 27
    """Забайкальский край"""

    CHUKOTKA = 28
    """ЧАО"""

    ARCHANGELSK = 29
    """Архангельск"""

    VOLOGDA = 30
    """Вологда"""

    KALININGRAD = 31
    """Калининград"""

    KARELIA = 32
    """Карелия"""

    KOMI = 33
    """Коми"""

    LENOBLAST = 34
    """Лен область"""

    MURMANSK = 35
    """Мурманск"""

    NOVGOROD = 36
    """Новгород"""

    PSKOV = 37
    """Псков"""

    SPB = 38
    """СПб"""

    ALTAI = 39
    """Алтайский филиал"""

    BURYATIYA = 40
    """Бурятский филиал"""

    IRKUTSK = 41
    """Иркутский филиал"""

    KEMEROVO = 42
    """Кемеровский филиал"""

    KRASNOYARSK = 43
    """Красноярский филиал"""

    OMSK = 44
    """Омский филиал"""

    HAKASIYA = 45
    """Республика Хакасия"""

    RALTAY = 46
    """Республика Алтай"""

    TUVA = 47
    """Республика Тыва"""

    TOMSK = 48
    """Томский филиал"""

    ORENBURG = 49
    """Оренбургская область"""

    BELGOROD = 50
    """Белгородский филиал"""

    SAKHA = 51
    """Саха"""

    EKT = 52
    """Екатеринбургский филиал"""

    VOLGOGRAD = 53
    """Волгоградский филиал"""

    YAMAL = 54
    """Ямало-Ненецкий филиал"""

    CHELYABINSK = 55
    """Челябинский филиал"""

    PERM = 56
    """Пермский филиал ПАО "Ростелеком"""

    MARYEL = 57
    """Республика Марий Эл"""

    PENZA = 58
    """Пензенская область"""

    INGUSHETIA = 59
    """Ингушский филиал"""

    NALCHIK = 60
    """Кабардино-Балкарский филиал"""

    ELISTA = 61
    """Калмыцкий филиал"""

    ROSTOV = 62
    """Ростовский филиал"""

    MAHACHKALA = 63
    """Дагестанский филиал"""

    MORDOVIYA = 64
    """Республика Мордовия"""

    KAZAN = 65
    """Республика Татарстан (Татарстан)"""

    SAMARA = 66
    """Самарская область"""

    SARATOV = 67
    """Саратовская область"""

    UDMURTIYA = 68
    """Удмуртская Республика"""

    ULYANOVSK = 69
    """Ульяновская область"""

    CHUVASHIYA = 70
    """Чувашская Республика - Чувашия"""

    NNOVGOROD = 71
    """Нижегородская область"""

    BRYANSK = 72
    """Брянский филиал"""

    VLADIMIR = 73
    """Владимирский филиал"""

    VORONEZH = 74
    """Воронежский филиал"""

    VLADIKAVKAZ = 75
    """Северо-Осетинский филиал"""

    STAVROPOL = 76
    """Ставропольский филиал"""

    CHERKESSK = 77
    """Республика Карачаево-Черкесская"""

    MAYKOP = 78
    """Республика Адыгея"""

    ASTRAKHAN = 79
    """Астраханский филиал"""

    KRASNODAR = 80
    """Краснодарский филиал"""

    TEST = 81
    """Тестовый"""

    NOVOSIBIRSK = 82
    """Новосибирский филиал"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class CollectorParamsSignType(betterproto.Enum):
    """Справочник типов измерений"""

    SIGN_TYPE_UNKNOWN = 0
    """Значение не указано"""

    ABSOLUTE_DS = 1
    """Абсолютный показатель"""

    ABSOLUTE_RC = 2
    """Абсолютный расход ресурса"""

    INTERVAL_DS = 3
    """Интервальный показатель состояния"""

    INTERVAL_RC = 4
    """Интервальный расход ресурса"""

    CURRENT_DS = 5
    """Текущее состояние"""

    CURRENT_RS = 6
    """Текущее состояние ресурса"""

    VOLUME = 7
    """Объём"""

    PARAMETER = 8
    """Параметр конфигурации"""

    FLAG = 9
    """Флаг состояния"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


class CollectorParamsArchiveType(betterproto.Enum):
    """
    Справочник типа архивности показаний.
     Используется для указания за какой период произошло измерение
    """

    ARCHIVE_TYPE_UNKNOWN = 0
    """Значение не указано"""

    CURRENT = 1
    """Текущие показания"""

    HALFHOUR = 2
    """За 30 мин"""

    HOUR = 3
    """За час"""

    DAY = 4
    """За сутки"""

    MONTH = 5
    """За месяц"""

    YEAR = 6
    """За год"""

    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        from pydantic_core import core_schema

        return core_schema.int_schema(ge=0)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateDeviceRequest(betterproto.Message):
    """Запрос сохранения шаблона ПУ"""

    data: "TemplateDevice" = betterproto.message_field(1)
    """Шаблон ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateDeviceResponse(betterproto.Message):
    """Ответ на запрос сохранения шаблона ПУ"""

    data: "TemplateDevice | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон ПУ"""

    error: "PostTemplateDeviceResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateDeviceResponseError(betterproto.Message):
    """Ошибка запроса сохранения шаблона ПУ"""

    validation: "TemplateDeviceValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteTemplateDeviceRequest(betterproto.Message):
    """Запрос удаления шаблона ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteTemplateDeviceResponse(betterproto.Message):
    """Ответ на запрос удаления шаблона ПУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceRequest(betterproto.Message):
    """Запрос получения шаблона ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор шаблона ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceResponse(betterproto.Message):
    """Ответ на запрос получения шаблона ПУ"""

    data: "TemplateDevice | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон ПУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceListRequest(betterproto.Message):
    """Запрос получения списка шаблонов ПУ"""

    filter: "TemplateDeviceFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "TemplateDevicePaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDevicePaging(betterproto.Message):
    """Пагинация"""

    order_by_type: "TemplateDevicePagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "TemplateDevicePagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано) то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDevicePagingValidationError(betterproto.Message):
    """
    Ошибка валидации постраничной пагинации по шаблонам ПУ.
     Эти проверки выполняются до обращения в базу данных
    """

    limit: "TemplateDevicePagingValidationErrorLimitInvalid | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Количество передано некорректно"""

    offset: "TemplateDevicePagingValidationErrorOffsetInvalid | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Сдвиг передан некорректно"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDevicePagingValidationErrorLimitInvalid(betterproto.Message):
    """
    Причины:
     - Значение количества < 0 или > 100
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDevicePagingValidationErrorOffsetInvalid(betterproto.Message):
    """
    Причины:
     - Значение сдвига < 0
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDeviceFilter(betterproto.Message):
    """
    Фильтр для запроса шаблонов приборов учета.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    metric_types: "list[TemplateDeviceMetricType]" = betterproto.enum_field(1)
    """По типу энергоресурса"""

    model_ids: "list[int]" = betterproto.int32_field(2)
    """По ID модели счетчика"""

    plan_types: "list[TemplateDevicePlanType]" = betterproto.enum_field(3)
    """По типу тарифного плана. Для ПУ электроэнергии"""

    indicator_vendor_types: "list[TemplateIndicatorVendorType]" = (
        betterproto.enum_field(4)
    )
    """По посреднику получения показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDeviceFilterValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceListResponse(betterproto.Message):
    """Ответ на запрос получения списка шаблонов приборов учета"""

    data: "TemplateDevice | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон ПУ"""

    error: "GetTemplateDeviceListResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceListResponseError(betterproto.Message):
    """Ошибка запроса получения списка шаблонов приборов учета"""

    template_device_filter_validation: "TemplateDeviceFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    template_device_paging_validation: "TemplateDevicePagingValidationError | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Ошибка пагинации  по страницам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceCountRequest(betterproto.Message):
    """Запрос получения количества шаблонов приборов учета"""

    filter: "TemplateDeviceFilter" = betterproto.message_field(1)
    """Фильтр по шаблонам приборов учета"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceCountResponse(betterproto.Message):
    """Ответ на запрос получения количества шаблонов приборов учета"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего шаблонов приборов учета"""

    error: "GetTemplateDeviceCountResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateDeviceCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества шаблонов приборов учета"""

    template_device_filter_validation: "TemplateDeviceFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDevice(betterproto.Message):
    """Шаблон ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    created_at: datetime = betterproto.message_field(2)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(3)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении
    """

    metric_type: "TemplateDeviceMetricType" = betterproto.enum_field(4)
    """Тип энергоресурса"""

    model_id: int = betterproto.int32_field(5)
    """ID Модели счетчика"""

    indicator_template_ids: "list[int]" = betterproto.int32_field(6)
    """Шаблоны индикаторов"""

    plan_type: "TemplateDevicePlanType" = betterproto.enum_field(7)
    """
    Тип тарифного плана.
     Для ПУ электроэнергии
    """

    indicator_vendor_type: "TemplateIndicatorVendorType" = betterproto.enum_field(8)
    """Посредник получения показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateDeviceValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorRequest(betterproto.Message):
    """Запрос получения шаблона шаблона индикатора"""

    id: int = betterproto.int32_field(1)
    """Идентификатор шаблона индикатора"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorResponse(betterproto.Message):
    """Ответ на запрос получения шаблона индикатора"""

    data: "TemplateIndicator | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон ндикатора"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorListRequest(betterproto.Message):
    """Запрос получения списка шаблонов индикаторов"""

    filter: "TemplateIndicatorFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "TemplateIndicatorPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorPaging(betterproto.Message):
    """Пагинация"""

    order_by_type: "TemplateIndicatorPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "TemplateIndicatorPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано) то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorPagingValidationError(betterproto.Message):
    """
    Ошибка валидации постраничной пагинации по шаблонам индикатора.
     Эти проверки выполняются до обращения в базу данных
    """

    limit: "TemplateIndicatorPagingValidationErrorLimitInvalid | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Количество передано некорректно"""

    offset: "TemplateIndicatorPagingValidationErrorOffsetInvalid | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Сдвиг передан некорректно"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorPagingValidationErrorLimitInvalid(betterproto.Message):
    """
    Причины:
     - Значение количества < 0 или > 100
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorPagingValidationErrorOffsetInvalid(betterproto.Message):
    """
    Причины:
     - Значение сдвига < 0
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorFilter(betterproto.Message):
    """
    Фильтр для запроса шаблонов индикаторов.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    sign_types: "list[TemplateIndicatorSignType]" = betterproto.enum_field(1)
    """По типу измерений"""

    archive_types: "list[TemplateIndicatorArchiveType]" = betterproto.enum_field(2)
    """По типу архивности показаний"""

    is_individual: "bool | None" = betterproto.message_field(
        3, wraps=betterproto.TYPE_BOOL
    )
    """По флагу видимости индикатора для клиента ФЛ"""

    title: "str | None" = betterproto.message_field(4, wraps=betterproto.TYPE_STRING)
    """
    По шаблонному названию индикатора.
     Поиск производится по подстроке
    """

    indicator_vendor_types: "list[TemplateIndicatorVendorType]" = (
        betterproto.enum_field(5)
    )
    """По посреднику получения показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorFilterValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorListResponse(betterproto.Message):
    """Ответ на запрос получения списка шаблонов индикаторов"""

    data: "TemplateIndicator | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон индикатора"""

    error: "GetTemplateIndicatorListResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorListResponseError(betterproto.Message):
    """Ошибка запроса получения списка шаблонов индикаторов"""

    template_indicator_filter_validation: (
        "TemplateIndicatorFilterValidationError | None"
    ) = betterproto.message_field(1, optional=True, group="reason")
    """Ошибка фильтрации"""

    template_indicator_paging_validation: (
        "TemplateIndicatorPagingValidationError | None"
    ) = betterproto.message_field(2, optional=True, group="reason")
    """Ошибка пагинации  по страницам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorCountRequest(betterproto.Message):
    """Запрос получения количества шаблонов индикаторов"""

    filter: "TemplateIndicatorFilter" = betterproto.message_field(1)
    """Фильтр по шаблонам индикаторов"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorCountResponse(betterproto.Message):
    """Ответ на запрос получения количества шаблонов индикаторов"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего шаблонов индикаторов"""

    error: "GetTemplateIndicatorCountResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetTemplateIndicatorCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества шаблонов индикаторов"""

    template_indicator_filter_validation: (
        "TemplateIndicatorFilterValidationError | None"
    ) = betterproto.message_field(1, optional=True, group="reason")
    """Ошибка фильтрации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateIndicatorRequest(betterproto.Message):
    """Запрос сохранения шаблона индикатора"""

    data: "TemplateIndicator" = betterproto.message_field(1)
    """Шаблон индикатора"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateIndicatorResponse(betterproto.Message):
    """Ответ на запрос сохранения шаблона индикатора"""

    data: "TemplateIndicator | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон индикатора"""

    error: "PostTemplateIndicatorResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostTemplateIndicatorResponseError(betterproto.Message):
    """Ошибка запроса сохранения шаблона индикатора"""

    validation: "TemplateIndicatorValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteTemplateIndicatorRequest(betterproto.Message):
    """Запрос удаления шаблона индикатора"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteTemplateIndicatorResponse(betterproto.Message):
    """Ответ на запрос удаления шаблона индикатора"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicator(betterproto.Message):
    """Шаблон индикатора"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    created_at: datetime = betterproto.message_field(2)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(3)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении
    """

    title: str = betterproto.string_field(4)
    """Шаблонное название индикатора"""

    unit_type: "TemplateIndicatorUnitType" = betterproto.enum_field(5)
    """
    Тип единицы измерения, в которой интерпретировано, получаемое измерение
    """

    sign_type: "TemplateIndicatorSignType" = betterproto.enum_field(6)
    """Тип измерения"""

    archive_type: "TemplateIndicatorArchiveType" = betterproto.enum_field(7)
    """Тип архивности показаний"""

    presentation_unit_type: "TemplateIndicatorUnitType" = betterproto.enum_field(8)
    """
    Тип единицы измерения для отображения измерения.
     При UNIT_TYPE_UNKNOWN отображаемые единицы совпадают с единицами источников значений, преобразования единиц не происходит.
     Применяется после коэффициента
    """

    compatibility_code: "str | None" = betterproto.message_field(
        9, wraps=betterproto.TYPE_STRING
    )
    """Код для совместимости с поставщиком метрик"""

    is_individual: bool = betterproto.bool_field(10)
    """Флаг видимости индикатора для клиента ФЛ"""

    coefficient: "float | None" = betterproto.message_field(
        11, wraps=betterproto.TYPE_FLOAT
    )
    """
    Коэффициент, на который умножается отображаемое значение.
     Применяется перед преобразованием единиц измерений к presentation_unit_type и после применения поправки
    """

    shift: "float | None" = betterproto.message_field(12, wraps=betterproto.TYPE_FLOAT)
    """
    Величина поправки к отображаемому значению.
     Применяется перед применением коэффициента
    """

    round_decimal_digits: "int | None" = betterproto.message_field(
        13, wraps=betterproto.TYPE_INT32
    )
    """
    Количество возвращаемых десятичных знаков при округлении итогового значения.
     При пустом параметре округления не происходит.
     Применяется после преобразования единиц измерения
    """

    metric_expected_freq: int = betterproto.int32_field(14)
    """Ожидаемая частота поступления показаний в днях"""

    indicator_vendor_type: "TemplateIndicatorVendorType" = betterproto.enum_field(15)
    """Посредник получения показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class TemplateIndicatorValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingRequest(betterproto.Message):
    """Запрос сохранения объекта строительства"""

    data: "Building" = betterproto.message_field(1)
    """Объект строительства"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutBuildingGroupAttachRequest(betterproto.Message):
    """
    Запрос сохранения связей объектов строительства и группы пользователя
    """

    building_group: "BuildingGroup" = betterproto.message_field(1)
    """Связь объекта строительства и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingResponse(betterproto.Message):
    """Ответ на запрос сохранения объекта строительства"""

    data: "Building | None" = betterproto.message_field(1, optional=True, group="type")
    """Объект строительства"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutBuildingGroupAttachResponse(betterproto.Message):
    """
    Ответ на запрос сохранения связи объекта строительства и группы пользователя
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingRequest(betterproto.Message):
    """Запрос получения объекта строительства"""

    id: int = betterproto.int32_field(1)
    """Идентификатор объекта строительства"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingResponse(betterproto.Message):
    """Ответ на запрос получения объекта строительства"""

    data: "Building | None" = betterproto.message_field(1, optional=True, group="type")
    """Объект строительства"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "BuildingFilter" = betterproto.message_field(1)
    """Фильтр индикаторов"""

    paging: "BuildingPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация по индикаторам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingGroupListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "BuildingGroupFilter" = betterproto.message_field(1)
    """Фильтр связей объектов строительства и группы пользователя"""

    paging: "BuildingGroupPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class BuildingGroupPaging(betterproto.Message):
    """Пагинация связей объектов строительства и группы пользователя"""

    order_by_type: "BuildingGroupPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "BuildingGroupPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class BuildingPaging(betterproto.Message):
    """Пагинация объектов строительства"""

    order_by_type: "BuildingPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "BuildingPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingListResponse(betterproto.Message):
    """Ответ на запрос получения списка объектов строительства"""

    data: "Building | None" = betterproto.message_field(1, optional=True, group="type")
    """Индикатор"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingGroupListResponse(betterproto.Message):
    """
    Ответ на запрос получения списка связей объектов строительства и группы пользователя
    """

    data: "BuildingGroup | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Связь объекта строительства и группы пользователя"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexResponse(betterproto.Message):
    """Событие создания/изменения объекта строительства на сервера"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    upsert_building_event: (
        "PostBuildingFullDuplexResponseUpsertBuildingEvent | None"
    ) = betterproto.message_field(2, optional=True, group="event")
    """Событие создания/обновления объекта строительства"""

    remove_building_event: (
        "PostBuildingFullDuplexResponseRemoveBuildingEvent | None"
    ) = betterproto.message_field(3, optional=True, group="event")
    """Событие удаления объекта строительства"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexResponseRemoveBuildingEvent(betterproto.Message):
    """Событие удаления объекта строительства"""

    id: int = betterproto.int32_field(1)
    """Идентификатор объекта строительства"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexResponseUpsertBuildingEvent(betterproto.Message):
    """Событие создания/обновления объекта строительства"""

    data: "Building" = betterproto.message_field(1)
    """Объект строительства"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexRequest(betterproto.Message):
    """Запрос создания задачи с клиента на сервере"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    building_async_status: "PostBuildingFullDuplexRequestBuildingAsyncStatus | None" = (
        betterproto.message_field(2, optional=True, group="task")
    )
    """Результат обработки объекта строительства на клиенте"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexRequestBuildingAsyncStatus(betterproto.Message):
    """Результат обработки объекта строительства на клиенте"""

    building_id: int = betterproto.int32_field(1)
    """Идентификатор объекта строительства"""

    data: "PostBuildingFullDuplexRequestBuildingAsyncStatusSuccess | None" = (
        betterproto.message_field(2, optional=True, group="type")
    )
    """Успех"""

    error: "PostBuildingFullDuplexRequestBuildingAsyncStatusError | None" = (
        betterproto.message_field(3, optional=True, group="type")
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexRequestBuildingAsyncStatusSuccess(betterproto.Message):
    """Команда принята"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexRequestBuildingAsyncStatusError(betterproto.Message):
    """Ошибки обработки объекта строительства на клиенте"""

    unknown: (
        "PostBuildingFullDuplexRequestBuildingAsyncStatusErrorUnknownError | None"
    ) = betterproto.message_field(1, optional=True, group="reason")
    """Неизвестная ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostBuildingFullDuplexRequestBuildingAsyncStatusErrorUnknownError(
    betterproto.Message
):
    """Неизвестная ошибка на стороне клиента"""

    message: str = betterproto.string_field(1)
    """
    Произвольный текст ошибки на стороне клиента.
     Отправляется в случае если в спецификации нет подходящей ошибки.
     После анализа таких ошибок в спецификацию добавляется специальный тип под эту ошибку
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class BuildingFilter(betterproto.Message):
    """
    Фильтр для запроса объектов строительства.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    fias_id: "list[str | None]" = betterproto.message_field(
        1, wraps=betterproto.TYPE_STRING
    )
    """По ФИАС"""

    title: "str | None" = betterproto.message_field(2, wraps=betterproto.TYPE_STRING)
    """По заголовку"""

    after_created_at: datetime = betterproto.message_field(3)
    """По нижней границе дате создания"""

    before_created_at: datetime = betterproto.message_field(4)
    """По верхней границе дате создания"""

    mrf_types: "list[BuildingMrfType]" = betterproto.enum_field(5)
    """По МРФ (Макрорегион)"""

    rf_types: "list[BuildingRfType]" = betterproto.enum_field(6)
    """По РФ (Регион)"""

    status_types: "list[BuildingStatusType]" = betterproto.enum_field(7)
    """По статусам объекта строительства"""

    orpons: "list[int]" = betterproto.int64_field(8)
    """По ОРПОНам"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class BuildingGroupFilter(betterproto.Message):
    """
    Фильтр для запроса связей объектов строительства и группы пользователя.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    group_ids: "list[str]" = betterproto.string_field(1)
    """По Идентификатору группы пользователя"""

    building_ids: "list[int]" = betterproto.int32_field(2)
    """По Объекту строительства"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingCountRequest(betterproto.Message):
    """Запрос получения количества объектов строительства"""

    filter: "BuildingFilter" = betterproto.message_field(1)
    """Фильтр по индикаторам"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingGroupCountRequest(betterproto.Message):
    """
    Запрос получения количества связей объектов строительства и группы пользователя
    """

    filter: "BuildingGroupFilter" = betterproto.message_field(1)
    """Фильтр связей объектов строительства и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingCountResponse(betterproto.Message):
    """Ответ на запрос получения количества объектов строительства"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего индикаторов"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetBuildingGroupCountResponse(betterproto.Message):
    """
    Ответ на запрос получения количества связей объектов строительства и группы пользователя
    """

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего связей объектов строительства и группы пользователя"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteBuildingRequest(betterproto.Message):
    """Запрос удаления объекта строительства"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteBuildingResponse(betterproto.Message):
    """Ответ на запрос удаления объекта строительства"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutBuildingGroupDetachRequest(betterproto.Message):
    """Запрос удаления связей объектов строительства и группы пользователя"""

    building_group: "BuildingGroup" = betterproto.message_field(1)
    """Связь объекта строительства и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutBuildingGroupDetachResponse(betterproto.Message):
    """
    Ответ на запрос удаления связи объекта строительства и группы пользователя
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class Building(betterproto.Message):
    """Объект строительства"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    title: str = betterproto.string_field(2)
    """Наименование объекта строительства"""

    created_at: datetime = betterproto.message_field(3)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(4)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении.
     Является версией объекта
    """

    utc_offset: int = betterproto.int32_field(5)
    """Смещение временной зоны объекта строительства от UTC в минутах"""

    fias_id: "str | None" = betterproto.message_field(6, wraps=betterproto.TYPE_STRING)
    """ФИАС"""

    mrf_type: "BuildingMrfType" = betterproto.enum_field(7)
    """Принадлежность объекта строительства к МРФ"""

    rf_type: "BuildingRfType" = betterproto.enum_field(8)
    """Принадлежность объекта строительства к РФ"""

    status_type: "BuildingStatusType" = betterproto.enum_field(9)
    """Статус объекта строительства"""

    full_address: str = betterproto.string_field(10)
    """Адрес объекта строительства"""

    orpon: int = betterproto.int64_field(11)
    """ОРПОН"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class BuildingGroup(betterproto.Message):
    """
    Связка объекта строительства и группы пользователя.
     Задает область ресурсов (resource scope), доступную пользователю.
     Используется для контроля доступа к объекту строительства
    """

    group_id: str = betterproto.string_field(1)
    """
    Идентификатор группы.
     # Тип: Guid
    """

    building_id: int = betterproto.int32_field(2)
    """
    Идентификатор объекта строительства.
     # Диапазон: 0..2147483647
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDeviceRequest(betterproto.Message):
    """Запрос удаления прибора учета"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDeviceResponse(betterproto.Message):
    """Ответ на запрос удаления прибора учета"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceGroupAttachRequest(betterproto.Message):
    """Запрос сохранения связей ПУ и группы пользователя"""

    device_group: "DeviceGroup" = betterproto.message_field(1)
    """Связь ПУ и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceGroupAttachResponse(betterproto.Message):
    """Ответ на запрос сохранения связи ПУ и группы пользователя"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceGroupListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "DeviceGroupFilter" = betterproto.message_field(1)
    """Фильтр связей ПУ и группы пользователя"""

    paging: "DeviceGroupPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceGroupPaging(betterproto.Message):
    """Пагинация связей ПУ и группы пользователя"""

    order_by_type: "DeviceGroupPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: GROUP_ID
    """

    direction_type: "DeviceGroupPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceGroupListResponse(betterproto.Message):
    """Ответ на запрос получения списка связей ПУ и группы пользователя"""

    data: "DeviceGroup | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Связь ПУ и группы пользователя"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceGroupCountRequest(betterproto.Message):
    """Запрос получения количества связей ПУ и группы пользователя"""

    filter: "DeviceGroupFilter" = betterproto.message_field(1)
    """Фильтр связей ПУ и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceGroupFilter(betterproto.Message):
    """
    Фильтр для запроса связей ПУ и группы пользователя.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    group_ids: "list[str]" = betterproto.string_field(1)
    """По Идентификатору группы пользователя"""

    device_ids: "list[int]" = betterproto.int32_field(2)
    """По ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceGroupCountResponse(betterproto.Message):
    """Ответ на запрос получения количества связей ПУ и группы пользователя"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего связей ПУ и группы пользователя"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceGroupDetachRequest(betterproto.Message):
    """Запрос удаления связей ПУ и группы пользователя"""

    device_group: "DeviceGroup" = betterproto.message_field(1)
    """Связь ПУ и группы пользователя"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceGroupDetachResponse(betterproto.Message):
    """Ответ на запрос удаления связи ПУ и группы пользователя"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceGroup(betterproto.Message):
    """
    Связка ПУ и группы пользователя.
     Задает область ресурсов (resource scope), доступную пользователю.
     Используется для контроля доступа к ПУ
    """

    group_id: str = betterproto.string_field(1)
    """
    Идентификатор группы.
     # Тип: Guid
    """

    device_id: int = betterproto.int32_field(2)
    """
    Идентификатор ПУ.
     # Диапазон: 0..2147483647
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceIndicatorRequest(betterproto.Message):
    """Запрос сохранения индикатора"""

    data: "Indicator" = betterproto.message_field(1)
    """Индикатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceIndicatorResponse(betterproto.Message):
    """Ответ на запрос сохранения индикатора"""

    data: "Indicator | None" = betterproto.message_field(1, optional=True, group="type")
    """Индикатор"""

    error: "PostDeviceIndicatorResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceIndicatorResponseError(betterproto.Message):
    """Ошибка запроса сохранения индикатора"""

    validation: "IndicatorValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorRequest(betterproto.Message):
    """Запрос получения индикатора"""

    id: int = betterproto.int32_field(1)
    """Идентификатор индикатора"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorResponse(betterproto.Message):
    """Ответ на запрос получения индикатора"""

    data: "Indicator | None" = betterproto.message_field(1, optional=True, group="type")
    """Индикатор"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceRequest(betterproto.Message):
    """Запрос получения ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceResponse(betterproto.Message):
    """Ответ на запрос получения ПУ"""

    data: "Device | None" = betterproto.message_field(1, optional=True, group="type")
    """Прибор учета"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "IndicatorFilter" = betterproto.message_field(1)
    """Фильтр индикаторов"""

    paging: "IndicatorPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация по индикаторам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorPaging(betterproto.Message):
    """Пагинация индикаторов"""

    order_by_type: "IndicatorPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "IndicatorPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorPagingValidationError(betterproto.Message):
    """
    Ошибка валидации постраничной пагинации по индикаторам.
     Эти проверки выполняются до обращения в базу данных
    """

    limit: "IndicatorPagingValidationErrorLimitInvalid | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Количество передано некорректно"""

    offset: "IndicatorPagingValidationErrorOffsetInvalid | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Сдвиг передан некорректно"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorPagingValidationErrorLimitInvalid(betterproto.Message):
    """
    Причины:
     - Значение количества < 0 или > 100
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorPagingValidationErrorOffsetInvalid(betterproto.Message):
    """
    Причины:
     - Значение сдвига < 0
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorListResponse(betterproto.Message):
    """Ответ на запрос получения списка индикаторов"""

    data: "Indicator | None" = betterproto.message_field(1, optional=True, group="type")
    """Индикатор"""

    error: "GetDeviceIndicatorListResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorListResponseError(betterproto.Message):
    """Ошибка запроса получения списка индикаторов"""

    device_filter_validation: "IndicatorFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    device_paging_validation: "IndicatorPagingValidationError | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Ошибка пагинации  по страницам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorFilter(betterproto.Message):
    """
    Фильтр для запроса индикаторов.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    device_ids: "list[int]" = betterproto.int32_field(1)
    """По списку приборов учета"""

    sign_types: "list[IndicatorSignType]" = betterproto.enum_field(2)
    """По типам измерений"""

    ids: "list[int]" = betterproto.int32_field(3)
    """
    По списку ключей индикаторов.
     Устарело, использовать метод GetDeviceIndicator
    """

    device_serial_numbers: "list[str]" = betterproto.string_field(4)
    """По серийным номерам привязанных ПУ"""

    building_ids: "list[int]" = betterproto.int32_field(5)
    """По идентификаторам объектов строительства, привязанных ТУ"""

    room_numbers: "list[str]" = betterproto.string_field(6)
    """По Номерам помещений, привязанных ТУ"""

    room_labels: "list[str]" = betterproto.string_field(7)
    """По Лейблам помещений, привязанных ТУ"""

    metric_point_ids: "list[str]" = betterproto.string_field(8)
    """По ID привязанных точек учета"""

    indicator_vendor_types: "list[IndicatorVendorType]" = betterproto.enum_field(9)
    """По посреднику получения показаний"""

    def __post_init__(self) -> None:
        super().__post_init__()
        if self.is_set("ids"):
            warnings.warn("IndicatorFilter.ids is deprecated", DeprecationWarning)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorFilterValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorCountRequest(betterproto.Message):
    """Запрос получения количества индикаторов"""

    filter: "IndicatorFilter" = betterproto.message_field(1)
    """Фильтр по индикаторам"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorCountResponse(betterproto.Message):
    """Ответ на запрос получения количества индикаторов"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего индикаторов"""

    error: "GetDeviceIndicatorCountResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества индикаторов"""

    device_filter_validation: "IndicatorFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDeviceIndicatorRequest(betterproto.Message):
    """Запрос удаления индикатора"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDeviceIndicatorResponse(betterproto.Message):
    """Ответ на запрос удаления индикатора"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequest(betterproto.Message):
    """Запрос создания задачи с клиента на сервере"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    post_device_full_duplex_device_async_status: (
        "PostDeviceFullDuplexRequestDeviceAsyncStatus | None"
    ) = betterproto.message_field(2, optional=True, group="task")
    """Результат обработки устройства на клиенте"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatus(betterproto.Message):
    """Результат обработки устройства на клиенте"""

    device_id: int = betterproto.int32_field(1)
    """Идентификатор ПУ"""

    data: "PostDeviceFullDuplexRequestDeviceAsyncStatusSuccess | None" = (
        betterproto.message_field(2, optional=True, group="type")
    )
    """Успех"""

    error: "PostDeviceFullDuplexRequestDeviceAsyncStatusError | None" = (
        betterproto.message_field(3, optional=True, group="type")
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusSuccess(betterproto.Message):
    """Команда принята"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusError(betterproto.Message):
    """Ошибки обработки устройства на клиенте"""

    post_device_request_unknown: (
        "PostDeviceFullDuplexRequestDeviceAsyncStatusErrorUnknownError | None"
    ) = betterproto.message_field(1, optional=True, group="reason")
    """Неизвестная ошибка"""

    post_device_request_ip: (
        "PostDeviceFullDuplexRequestDeviceAsyncStatusErrorIpError | None"
    ) = betterproto.message_field(2, optional=True, group="reason")
    """Неверный IP"""

    post_device_request_port: (
        "PostDeviceFullDuplexRequestDeviceAsyncStatusErrorPortError | None"
    ) = betterproto.message_field(3, optional=True, group="reason")
    """Неверный порт"""

    post_device_request_network_address: (
        "PostDeviceFullDuplexRequestDeviceAsyncStatusErrorNetworkAddressError | None"
    ) = betterproto.message_field(4, optional=True, group="reason")
    """Неверный сетевой адрес"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusErrorUnknownError(
    betterproto.Message
):
    """Неизвестная ошибка на стороне клиента"""

    message: str = betterproto.string_field(1)
    """
    Произвольный текст ошибки на стороне клиента.
     Отправляется в случае если в спецификации нет подходящей ошибки.
     После анализа таких ошибок в спецификацию добавляется специальный тип под эту ошибку
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusErrorIpError(betterproto.Message):
    """
    Причины:
      - Устройство не найденно на данном IP адресе
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusErrorPortError(betterproto.Message):
    """
    Причины:
      - Устройство отсутствует на порту
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexRequestDeviceAsyncStatusErrorNetworkAddressError(
    betterproto.Message
):
    """
    Причины:
      - Неверный сетевой адрес
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceRequest(betterproto.Message):
    """Запрос сохранения ПУ"""

    device: "Device" = betterproto.message_field(1)
    """Прибор учета"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceRequest(betterproto.Message):
    """Запрос замены прибора учета"""

    replace_device_id: int = betterproto.int32_field(1)
    """Идентификатор заменяемого прибора учета"""

    device: "Device" = betterproto.message_field(2)
    """Создаваемый прибор учета"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponse(betterproto.Message):
    """Ответ на замену прибора учета"""

    data: "Device | None" = betterproto.message_field(1, optional=True, group="type")
    """Созданный на замену ПУ"""

    error: "PostDeviceReplaceResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseError(betterproto.Message):
    """Ошибка замены ПУ"""

    validation: "DeviceValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    replace_device_not_found: (
        "PostDeviceReplaceResponseErrorReplaceDeviceNotFound | None"
    ) = betterproto.message_field(2, optional=True, group="reason")
    """Не найден заменяемый ПУ"""

    create_indicators_fail: (
        "PostDeviceReplaceResponseErrorCreateIndicatorsFail | None"
    ) = betterproto.message_field(3, optional=True, group="reason")
    """Не удалось создать индикаторы нового ПУ"""

    multi_linked_metric_point: (
        "PostDeviceReplaceResponseErrorMultiLinkedMetricPoint | None"
    ) = betterproto.message_field(4, optional=True, group="reason")
    """Попытка замены ПУ, привязанного ко многим ТУ"""

    wrong_building: "PostDeviceReplaceResponseErrorWrongBuilding | None" = (
        betterproto.message_field(5, optional=True, group="reason")
    )
    """Заменяющий ПУ не привязан к дому заменяемого ПУ"""

    metric_point_not_found: (
        "PostDeviceReplaceResponseErrorMetricPointNotFound | None"
    ) = betterproto.message_field(6, optional=True, group="reason")
    """Заменяемый ПУ не привязан к ТУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseErrorReplaceDeviceNotFound(betterproto.Message):
    """Не найден заменяемый ПУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseErrorCreateIndicatorsFail(betterproto.Message):
    """Не удалось создать индикаторы нового ПУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseErrorMultiLinkedMetricPoint(betterproto.Message):
    """Попытка замены ПУ, привязанного ко многим ТУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseErrorWrongBuilding(betterproto.Message):
    """Заменяющий ПУ не привязан к дому заменяемого ПУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceReplaceResponseErrorMetricPointNotFound(betterproto.Message):
    """Заменяемый ПУ не привязан к ТУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceFullDuplexResponse(betterproto.Message):
    """Событие изменения ПУ на сервера"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    post_device: "PostDeviceResponse | None" = betterproto.message_field(
        2, optional=True, group="event"
    )
    """Измененние ПУ на сервере"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceResponse(betterproto.Message):
    """Ответ на изменение ПУ на сервере"""

    data: "Device | None" = betterproto.message_field(1, optional=True, group="type")
    """ПУ"""

    error: "PostDeviceResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDeviceResponseError(betterproto.Message):
    """Ошибка запроса сохранения ПУ"""

    validation: "DeviceValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class Indicator(betterproto.Message):
    """Индикатор"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    device_id: int = betterproto.int32_field(2)
    """Идентификатор прибора учета(ПУ)"""

    title: str = betterproto.string_field(3)
    """Название"""

    unit_type: "IndicatorUnitType" = betterproto.enum_field(4)
    """
    Тип единицы измерения, в которой интерпретировано, получаемое измерение
    """

    sign_type: "IndicatorSignType" = betterproto.enum_field(5)
    """Тип измерения"""

    created_at: datetime = betterproto.message_field(6)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(7)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении.
     Является версией объекта
    """

    is_individual: bool = betterproto.bool_field(8)
    """Флаг видимости индикатора для клиента"""

    compatibility_code: "str | None" = betterproto.message_field(
        9, wraps=betterproto.TYPE_STRING
    )
    """Код для совместимости с поставщиком метрик"""

    archive_type: "IndicatorArchiveType" = betterproto.enum_field(10)
    """Тип архивности показаний"""

    presentation_unit_type: "IndicatorUnitType" = betterproto.enum_field(11)
    """
    Тип единицы измерения для отображения измерения.
     При UNIT_TYPE_UNKNOWN отображаемые единицы совпадают с единицами источников значений, преобразования единиц не происходит.
     Применяется после коэффициента
    """

    coefficient: "float | None" = betterproto.message_field(
        12, wraps=betterproto.TYPE_FLOAT
    )
    """
    Коэффициент, на который умножается отображаемое значение.
     Применяется перед преобразованием единиц измерений к presentation_unit_type и после применения поправки
    """

    shift: "float | None" = betterproto.message_field(13, wraps=betterproto.TYPE_FLOAT)
    """
    Величина поправки к отображаемому значению.
     Применяется перед применением коэффициента
    """

    round_decimal_digits: "int | None" = betterproto.message_field(
        14, wraps=betterproto.TYPE_INT32
    )
    """
    Количество возвращаемых десятичных знаков при округлении итогового значения.
     При пустом параметре округления не происходит.
     Применяется после преобразования единиц измерения
    """

    metric_expected_freq: int = betterproto.int32_field(15)
    """Ожидаемая частота поступления показаний в днях"""

    channel_number: "str | None" = betterproto.message_field(
        16, wraps=betterproto.TYPE_STRING
    )
    """Номер канала для многоканального ПУ"""

    channel_order: "int | None" = betterproto.message_field(
        17, wraps=betterproto.TYPE_INT32
    )
    """Порядковый номер канала для многоканального ПУ"""

    vendor_type: "IndicatorVendorType" = betterproto.enum_field(18)
    """Посредник получения показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class IndicatorValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class Device(betterproto.Message):
    """Прибор учёта"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    indicators: "list[Indicator]" = betterproto.message_field(2)
    """Индикаторы"""

    metric_point: "DeviceMetricPoint" = betterproto.message_field(3)
    """Точка учета"""

    created_at: datetime = betterproto.message_field(4)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(5)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении.
     Является версией объекта
    """

    type: "DeviceType" = betterproto.enum_field(6)
    """Тип прибора учёта(ПУ)"""

    serial_number: str = betterproto.string_field(7)
    """Серийный номер"""

    model: str = betterproto.string_field(8)
    """Производитель и модель счетчика"""

    year: int = betterproto.int32_field(9)
    """Год выпуска счётчика"""

    fias_id: str = betterproto.string_field(10)
    """Идентификатор строения ФИАС"""

    resource_owner_id: str = betterproto.string_field(11)
    """
    Идентификатор владельца.
     Заполняется сервером
    """

    status_type: "DeviceStatusType" = betterproto.enum_field(12)
    """Тип статуса"""

    installed_at: datetime = betterproto.message_field(13)
    """Дата установки"""

    removed_at: datetime = betterproto.message_field(14)
    """Дата удаления"""

    check_at: datetime = betterproto.message_field(15)
    """Дата предыдущей поверки счетчика"""

    next_check_at: datetime = betterproto.message_field(16)
    """Дата следующей поверки счетчика"""

    external_id: "str | None" = betterproto.message_field(
        17, wraps=betterproto.TYPE_STRING
    )
    """Внешний дентификатор прибора учёта(ПУ)"""

    plan_type: "DevicePlanType" = betterproto.enum_field(18)
    """Тип тарифного плана"""

    parent_id: "int | None" = betterproto.message_field(
        19, wraps=betterproto.TYPE_INT32
    )
    """Идентификатор хаба"""

    pipe_type: "DevicePipeType" = betterproto.enum_field(20)
    """Тип трубопровода"""

    dev_eui: "str | None" = betterproto.message_field(21, wraps=betterproto.TYPE_STRING)
    """Идентификатор модуля LoraWan"""

    mac: "str | None" = betterproto.message_field(22, wraps=betterproto.TYPE_STRING)
    """MAC-адрес"""

    port: "int | None" = betterproto.message_field(23, wraps=betterproto.TYPE_INT32)
    """Номер порта"""

    network_address: "str | None" = betterproto.message_field(
        24, wraps=betterproto.TYPE_STRING
    )
    """Сетевой адрес"""

    comm_channel: "str | None" = betterproto.message_field(
        25, wraps=betterproto.TYPE_STRING
    )
    """
    Канал связи.
     Для станции LoraWan
    """

    sim_number: "str | None" = betterproto.message_field(
        26, wraps=betterproto.TYPE_STRING
    )
    """
    MSISDN SIM-карты.
     Номер телефона
    """

    sim_serial: "str | None" = betterproto.message_field(
        27, wraps=betterproto.TYPE_STRING
    )
    """Серийный номер SIM-карты"""

    ip_address_sim: "str | None" = betterproto.message_field(
        28, wraps=betterproto.TYPE_STRING
    )
    """IP адрес SIM-карты"""

    placement: "str | None" = betterproto.message_field(
        29, wraps=betterproto.TYPE_STRING
    )
    """Размещение"""

    installation_place: "str | None" = betterproto.message_field(
        30, wraps=betterproto.TYPE_STRING
    )
    """Место установки"""

    appkey: "str | None" = betterproto.message_field(31, wraps=betterproto.TYPE_STRING)
    """
    Kлюч приложения.
     Используется в процессе присоединения к сети для получения сессионных ключей NwkSKey и AppSKey для LoRaWAN [128 бит]
    """

    appeui: "str | None" = betterproto.message_field(32, wraps=betterproto.TYPE_STRING)
    """
    Идентификатор приложения.
     Для LoRaWAN [64 бита]
    """

    protocol_type_label: "str | None" = betterproto.message_field(
        33, wraps=betterproto.TYPE_STRING
    )
    """Тип протокола"""

    channel_number: "int | None" = betterproto.message_field(
        34, wraps=betterproto.TYPE_INT32
    )
    """Номер канала для многоканального ПУ"""

    wire_interface: "str | None" = betterproto.message_field(
        35, wraps=betterproto.TYPE_STRING
    )
    """Тип проводного интерфейса"""

    building_id: int = betterproto.int32_field(36)
    """Идентификатор объекта строительства"""

    manufacture_year: "int | None" = betterproto.message_field(
        37, wraps=betterproto.TYPE_INT32
    )
    """Год выпуска счётчика"""

    indicator_vendor_type: "IndicatorVendorType" = betterproto.enum_field(38)
    """Посредник получения показаний"""

    def __post_init__(self) -> None:
        super().__post_init__()
        if self.is_set("metric_point"):
            warnings.warn("Device.metric_point is deprecated", DeprecationWarning)
        if self.is_set("year"):
            warnings.warn("Device.year is deprecated", DeprecationWarning)
        if self.is_set("fias_id"):
            warnings.warn("Device.fias_id is deprecated", DeprecationWarning)
        if self.is_set("resource_owner_id"):
            warnings.warn("Device.resource_owner_id is deprecated", DeprecationWarning)
        if self.is_set("appkey"):
            warnings.warn("Device.appkey is deprecated", DeprecationWarning)
        if self.is_set("appeui"):
            warnings.warn("Device.appeui is deprecated", DeprecationWarning)
        if self.is_set("channel_number"):
            warnings.warn("Device.channel_number is deprecated", DeprecationWarning)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceMetricPoint(betterproto.Message):
    """Точка учета"""

    id: str = betterproto.string_field(1)
    """Идентификатор"""

    metric_type: "DeviceMetricPointMetricType" = betterproto.enum_field(2)
    """Тип энергоресурса"""

    room_number: str = betterproto.string_field(3)
    """Номер помещения"""

    room_label: str = betterproto.string_field(4)
    """Лейбл помещения"""

    zone_label: "str | None" = betterproto.message_field(
        5, wraps=betterproto.TYPE_STRING
    )
    """Зона"""

    status_type: "DeviceMetricPointStatusType" = betterproto.enum_field(6)
    """Тип статуса"""

    accounting_type: "DeviceMetricPointAccountingType" = betterproto.enum_field(7)
    """Тип учёта"""

    created_at: datetime = betterproto.message_field(8)
    """Дата создания"""

    primary_current_type: "DeviceMetricPointPrimaryCurrentType" = (
        betterproto.enum_field(9)
    )
    """Тип номинала первичного тока"""

    secondary_current_type: "DeviceSecondaryCurrentType" = betterproto.enum_field(10)
    """Тип номинала вторичной обмотки"""

    building_id: int = betterproto.int32_field(11)
    """Идентификатор объекта строительства"""

    changed_at: datetime = betterproto.message_field(12)
    """Дата изменения"""

    building_level: int = betterproto.int32_field(13)
    """Уровень"""

    building_section: int = betterproto.int32_field(14)
    """Секция"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "DeviceFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "DevicePaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DevicePaging(betterproto.Message):
    """Пагинация устройств"""

    order_by_type: "DevicePagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "DevicePagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DevicePagingValidationError(betterproto.Message):
    """
    Ошибка валидации постраничной пагинации по ПУ.
     Эти проверки выполняются до обращения в базу данных
    """

    limit: "DevicePagingValidationErrorLimitInvalid | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Количество передано некорректно"""

    offset: "DevicePagingValidationErrorOffsetInvalid | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Сдвиг передан некорректно"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DevicePagingValidationErrorLimitInvalid(betterproto.Message):
    """
    Причины:
     - Значение количества < 0 или > 100
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DevicePagingValidationErrorOffsetInvalid(betterproto.Message):
    """
    Причины:
     - Значение сдвига < 0
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceListResponse(betterproto.Message):
    """Ответ на запрос получения списка приборов учета"""

    data: "Device | None" = betterproto.message_field(1, optional=True, group="type")
    """Прибор учета"""

    error: "GetDeviceListResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceListResponseError(betterproto.Message):
    """Ошибка запроса получения списка приборов учета"""

    device_filter_validation: "DeviceFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    device_paging_validation: "DevicePagingValidationError | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Ошибка пагинации  по страницам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceFilter(betterproto.Message):
    """
    Фильтр для запроса приборов учета.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    fias_ids: "list[str]" = betterproto.string_field(1)
    """По ФИАС"""

    types: "list[DeviceType]" = betterproto.enum_field(2)
    """По типам приборов учета"""

    status_types: "list[DeviceStatusType]" = betterproto.enum_field(3)
    """По типам статусов"""

    models: "list[str]" = betterproto.string_field(4)
    """По модели счетчика"""

    metric_point_metric_types: "list[DeviceMetricPointMetricType]" = (
        betterproto.enum_field(5)
    )
    """По типам метрик"""

    room_numbers: "list[str]" = betterproto.string_field(6)
    """По номерам помещений точек учета, привязанных через индикаторы"""

    room_labels: "list[str]" = betterproto.string_field(7)
    """По лейблам помещений точек учета, привязанных через индикаторы"""

    parent_ids: "list[int]" = betterproto.int32_field(8)
    """По идентификаторам хабов"""

    ids: "list[int]" = betterproto.int32_field(9)
    """
    По идентификаторам приборов учета.
     Устарело, использовать метод GetDevice
    """

    building_ids: "list[int]" = betterproto.int32_field(10)
    """По идентификатору объекта строительства"""

    serial_numbers: "list[str]" = betterproto.string_field(11)
    """По серийным номерам"""

    metric_point_ids: "list[str]" = betterproto.string_field(12)
    """По ID точек учета, привязанных через индикаторы"""

    serial_ids: "list[str]" = betterproto.string_field(13)
    """
    Смешанный поиск по полям serial_number, dev_eui, MAC-адрес, model, external_id
    """

    orpons: "list[int]" = betterproto.int64_field(14)
    """По ОРПОНам"""

    indicator_vendor_types: "list[IndicatorVendorType]" = betterproto.enum_field(15)
    """По посреднику получения показаний"""

    def __post_init__(self) -> None:
        super().__post_init__()
        if self.is_set("ids"):
            warnings.warn("DeviceFilter.ids is deprecated", DeprecationWarning)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceFilterValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceCountRequest(betterproto.Message):
    """Запрос получения количества устройств"""

    filter: "DeviceFilter" = betterproto.message_field(1)
    """Фильтр по устройствам"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceCountResponse(betterproto.Message):
    """Ответ на запрос получения количества устройств"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего устройств"""

    error: "GetDeviceCountResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества устройств"""

    device_filter_validation: "DeviceFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorMetricPointListRequest(betterproto.Message):
    """Запрос получения списка"""

    filter: "DeviceIndicatorMetricPointFilter" = betterproto.message_field(1)
    """Фильтр связей индикаторов и ТУ"""

    paging: "DeviceIndicatorMetricPointPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceIndicatorMetricPointFilter(betterproto.Message):
    """
    Фильтр для запроса индикаторов и ТУ.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    indicator_id: "list[int]" = betterproto.int32_field(1)
    """По Идентификатору индикатора"""

    metric_point_id: "list[str]" = betterproto.string_field(2)
    """По Идентификатору ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceIndicatorMetricPointPaging(betterproto.Message):
    """Пагинация связей индикаторов и ТУ"""

    order_by_type: "DeviceIndicatorMetricPointPagingOrderByType" = (
        betterproto.enum_field(1)
    )
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "DeviceIndicatorMetricPointPagingDirectionType" = (
        betterproto.enum_field(2)
    )
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано), то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorMetricPointListResponse(betterproto.Message):
    """Ответ на запрос получения списка связей индикаторов и ТУ"""

    data: "DeviceIndicatorMetricPoint | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Связь индикатора и ТУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeviceIndicatorMetricPoint(betterproto.Message):
    """Связка индикатора и ТУ"""

    indicator_id: int = betterproto.int32_field(1)
    """
    Идентификатор индикатора.
     # Диапазон: 0..2147483647
    """

    metric_point_id: str = betterproto.string_field(2)
    """
    Идентификатору ТУ.
     # Тип: Guid
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorMetricPointCountRequest(betterproto.Message):
    """Запрос получения количества связей индикаторов и ТУ"""

    filter: "DeviceIndicatorMetricPointFilter" = betterproto.message_field(1)
    """Фильтр связей индикаторов и ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDeviceIndicatorMetricPointCountResponse(betterproto.Message):
    """Ответ на запрос получения количества связей индикаторов и ТУ"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего связей индикаторов и ТУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceIndicatorMetricPointAttachRequest(betterproto.Message):
    """Запрос сохранения связей индикаторов и ТУ"""

    device_indicator_metric_point: "DeviceIndicatorMetricPoint" = (
        betterproto.message_field(1)
    )
    """Связь индикатора и ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceIndicatorMetricPointAttachResponse(betterproto.Message):
    """Ответ на запрос сохранения связи индикатора и ТУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceIndicatorMetricPointDetachRequest(betterproto.Message):
    """Запрос удаления связей индикаторов и ТУ"""

    device_indicator_metric_point: "DeviceIndicatorMetricPoint" = (
        betterproto.message_field(1)
    )
    """Связь индикатора и ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PutDeviceIndicatorMetricPointDetachResponse(betterproto.Message):
    """Ответ на запрос удаления связи индикатора и ТУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointRequest(betterproto.Message):
    """Запрос получения ТУ"""

    id: str = betterproto.string_field(1)
    """Идентификатор ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointResponse(betterproto.Message):
    """Ответ на запрос получения ТУ"""

    data: "DeviceMetricPoint | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Точка учета"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointListRequest(betterproto.Message):
    """Запрос получения списка ТУ"""

    filter: "MetricPointFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "MetricPointPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointPaging(betterproto.Message):
    """Пагинация"""

    order_by_type: "MetricPointPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "MetricPointPagingDirectionType" = betterproto.enum_field(2)
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано) то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointPagingValidationError(betterproto.Message):
    """
    Ошибка валидации постраничной пагинации по ТУ.
     Эти проверки выполняются до обращения в базу данных
    """

    limit: "MetricPointPagingValidationErrorLimitInvalid | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Количество передано некорректно"""

    offset: "MetricPointPagingValidationErrorOffsetInvalid | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Сдвиг передан некорректно"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointPagingValidationErrorLimitInvalid(betterproto.Message):
    """
    Причины:
     - Значение количества < 0 или > 100
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointPagingValidationErrorOffsetInvalid(betterproto.Message):
    """
    Причины:
     - Значение сдвига < 0
    """

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointFilter(betterproto.Message):
    """
    Фильтр для запроса точек учета.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    device_metric_point_metric_types: "list[DeviceMetricPointMetricType]" = (
        betterproto.enum_field(1)
    )
    """По типу энергоресурса"""

    device_metric_point_status_types: "list[DeviceMetricPointStatusType]" = (
        betterproto.enum_field(2)
    )
    """По типу статуса"""

    room_numbers: "list[str]" = betterproto.string_field(3)
    """По Номеру помещения"""

    room_labels: "list[str]" = betterproto.string_field(4)
    """По Лейблу помещения"""

    building_ids: "list[int]" = betterproto.int32_field(5)
    """По идентификаторам объекта строительства"""

    fias_ids: "list[str]" = betterproto.string_field(6)
    """По ФИАС"""

    device_ids: "list[int]" = betterproto.int32_field(7)
    """По ID привязанных через индикаторы ПУ"""

    device_serial_numbers: "list[str]" = betterproto.string_field(8)
    """По серийным номерам привязанных через индикаторы ПУ"""

    orpons: "list[int]" = betterproto.int64_field(9)
    """По ОРПОНам"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class MetricPointFilterValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointListResponse(betterproto.Message):
    """Ответ на запрос получения списка ТУ"""

    data: "DeviceMetricPoint | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Точка учета"""

    error: "GetMetricPointListResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointListResponseError(betterproto.Message):
    """Ошибка запроса получения списка ТУ"""

    metric_point_filter_validation: "MetricPointFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    metric_point_paging_validation: "MetricPointPagingValidationError | None" = (
        betterproto.message_field(2, optional=True, group="reason")
    )
    """Ошибка пагинации  по страницам"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointCountRequest(betterproto.Message):
    """Запрос получения количества ТУ"""

    filter: "MetricPointFilter" = betterproto.message_field(1)
    """Фильтр по ТУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointCountResponse(betterproto.Message):
    """Ответ на запрос получения количества ТУ"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего ТУ"""

    error: "GetMetricPointCountResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetMetricPointCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества ТУ"""

    metric_point_filter_validation: "MetricPointFilterValidationError | None" = (
        betterproto.message_field(1, optional=True, group="reason")
    )
    """Ошибка фильтрации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostMetricPointRequest(betterproto.Message):
    """Запрос сохранения ТУ"""

    data: "DeviceMetricPoint" = betterproto.message_field(1)
    """Точка учета"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostMetricPointResponse(betterproto.Message):
    """Ответ на запрос сохранения ТУ"""

    data: "DeviceMetricPoint | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Точка учета"""

    error: "PostMetricPointResponseError | None" = betterproto.message_field(
        2, optional=True, group="type"
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostMetricPointResponseError(betterproto.Message):
    """Ошибка запроса сохранения ТУ"""

    validation: "ValidationError | None" = betterproto.message_field(
        1, optional=True, group="reason"
    )
    """Ошибка валидации"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteMetricPointRequest(betterproto.Message):
    """Запрос удаления ТУ"""

    id: str = betterproto.string_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteMetricPointResponse(betterproto.Message):
    """Ответ на запрос удаления ТУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class ValidationError(betterproto.Message):
    """
    Ошибки валидации.
     Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования protobuf"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDictionaryDeviceModelRequest(betterproto.Message):
    """Запрос сохранения модели ПУ"""

    data: "DictionaryDeviceModel" = betterproto.message_field(1)
    """Шаблон ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostDictionaryDeviceModelResponse(betterproto.Message):
    """Ответ на запрос сохранения модели ПУ"""

    data: "DictionaryDeviceModel | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Шаблон ПУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDictionaryDeviceModelRequest(betterproto.Message):
    """Запрос удаления модели ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DeleteDictionaryDeviceModelResponse(betterproto.Message):
    """Ответ на запрос удаления модели ПУ"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelRequest(betterproto.Message):
    """Запрос получения модели ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор модели ПУ"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelResponse(betterproto.Message):
    """Ответ на запрос получения модели ПУ"""

    data: "DictionaryDeviceModel | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Элемент справочника моделей"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelListRequest(betterproto.Message):
    """Запрос получения списка моделей ПУ"""

    filter: "DictionaryDeviceModelFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "DictionaryDeviceModelPaging | None" = betterproto.message_field(
        2, optional=True, group="pagination"
    )
    """Пагинация"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryMrfListRequest(betterproto.Message):
    """Запрос получения элементов справочника Макрорегионы (МРФ)"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryRfListRequest(betterproto.Message):
    """Запрос получения элементов справочника Регионы (РФ)"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryDeviceModelPaging(betterproto.Message):
    """Пагинация"""

    order_by_type: "DictionaryDeviceModelPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки.
     По умолчанию: ID
    """

    direction_type: "DictionaryDeviceModelPagingDirectionType" = betterproto.enum_field(
        2
    )
    """
    Тип направления сортировки.
     По умолчанию: DESC
    """

    limit: int = betterproto.int32_field(3)
    """
    Количество.
     Минимальное значение: 1.
     Максимальное значение: 100.
     По умолчанию: 20.
     Если значение 0 (не передано) то выставляем значение по умолчанию
    """

    offset: int = betterproto.int32_field(4)
    """
    Сдвиг.
     По умолчанию: 0
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryDeviceModelFilter(betterproto.Message):
    """
    Фильтр для запроса моделей приборов учета.
     При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
     При передаче нескольких разных параметров фильтра они работают в выборке через И
    """

    titles: "list[str]" = betterproto.string_field(1)
    """По заголовку элемента"""

    model_kinds: "list[str]" = betterproto.string_field(2)
    """По типам модели"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelListResponse(betterproto.Message):
    """Ответ на запрос получения списка моделей приборов учета"""

    data: "DictionaryDeviceModel | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Элемент справочника моделей ПУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryMrfListResponse(betterproto.Message):
    """Ответ на запрос получения элементов справочника Макрорегионы (МРФ)"""

    data: "DictionaryMrf | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Элемент справочника Макрорегионы (МРФ)"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryMrf(betterproto.Message):
    """Элемент справочника Макрорегионы (МРФ)"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    created_at: datetime = betterproto.message_field(2)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(3)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении
    """

    title: "str | None" = betterproto.message_field(4, wraps=betterproto.TYPE_STRING)
    """Локализованный заголовок элемента"""

    code: "str | None" = betterproto.message_field(5, wraps=betterproto.TYPE_STRING)
    """Техническое наименование элемента"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryRfListResponse(betterproto.Message):
    """Ответ на запрос получения элементов справочника Регионы (РФ)"""

    data: "DictionaryRf | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Элемент справочника Регионы (РФ)"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryPermission(betterproto.Message):
    """Элемент справочника Разрешения Телеметрии"""

    permission_type: "DictionaryPermissionPermissionType" = betterproto.enum_field(1)
    """Элемент справочника Разрешения Телеметрии"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryRf(betterproto.Message):
    """Элемент справочника Регионы (РФ)"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    created_at: datetime = betterproto.message_field(2)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(3)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении
    """

    title: "str | None" = betterproto.message_field(4, wraps=betterproto.TYPE_STRING)
    """Локализованный заголовок элемента"""

    code: "str | None" = betterproto.message_field(5, wraps=betterproto.TYPE_STRING)
    """Техническое наименование элемента"""

    mrf_id: int = betterproto.int32_field(6)
    """Принадлежность региона к Макрорегиону (МРФ)"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelCountRequest(betterproto.Message):
    """Запрос получения количества моделей приборов учета"""

    filter: "DictionaryDeviceModelFilter" = betterproto.message_field(1)
    """Фильтр по моделям приборов учета"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryDeviceModelCountResponse(betterproto.Message):
    """Ответ на запрос получения количества моделей приборов учета"""

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего моделей приборов учета"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryMrfCountRequest(betterproto.Message):
    """Запрос получения количества элементов справочника Макрорегионы (МРФ)"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryMrfCountResponse(betterproto.Message):
    """
    Ответ на запрос получения количества элементов справочника Макрорегионы (МРФ)
    """

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего элементов справочника Макрорегионы (МРФ)"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryRfCountRequest(betterproto.Message):
    """Запрос получения количества элементов справочника Регионы (РФ)"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetDictionaryRfCountResponse(betterproto.Message):
    """
    Ответ на запрос получения количества элементов справочника Регионы (РФ)
    """

    data: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Всего элементов справочника Регионы (РФ)"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class DictionaryDeviceModel(betterproto.Message):
    """Элемент справочника моделей ПУ"""

    id: int = betterproto.int32_field(1)
    """Идентификатор"""

    created_at: datetime = betterproto.message_field(2)
    """Дата создания"""

    changed_at: datetime = betterproto.message_field(3)
    """
    Дата последнего изменения.
     Заполняется и обновляется сервером.
     Заполняется при создании и изменении
    """

    title: "str | None" = betterproto.message_field(4, wraps=betterproto.TYPE_STRING)
    """Модель счетчика"""

    protocol: "str | None" = betterproto.message_field(5, wraps=betterproto.TYPE_STRING)
    """Протокол счетчика"""

    model_kind: "str | None" = betterproto.message_field(
        6, wraps=betterproto.TYPE_STRING
    )
    """Тип модели"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetSystemStatusResponse(betterproto.Message):
    """Ответ на запрос проверки доступности сервиса"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class GetSystemStatusRequest(betterproto.Message):
    """Запрос проверки доступности сервиса"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class CollectorParams(betterproto.Message):
    """Параметры сбора показаний"""

    date: str = betterproto.string_field(1)
    """
    Дата в формате YYYYMMDD.
     При пустой дате запускается на текущую дату
    """

    archive_type: "CollectorParamsArchiveType" = betterproto.enum_field(2)
    """
    Тип архивности.
     При отсутствии переданного значения, будут запрошены показания по всем возможным типам архивности
    """

    sign_type: "CollectorParamsSignType" = betterproto.enum_field(3)
    """
    Tип измерений.
     При отсутствии переданного значения, будут запрошены показания по всем возможным типам измерений
    """


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class EicAllFiasStartTask(betterproto.Message):
    """
    Сигнал на старт сбора показаний Enviro по всем домам, на указанную дату.
     Очередь key.telemetry_control.eic_all_fias_start_task
    """

    collector_params: "CollectorParams" = betterproto.message_field(1)
    """Параметры сбора показаний"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexResponse(betterproto.Message):
    """Событие создания/изменения ресурса"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    upsert_resource_event: (
        "PostResourceFullDuplexResponseUpsertResourceEvent | None"
    ) = betterproto.message_field(2, optional=True, group="event")
    """Событие создания/обновления ресурса"""

    remove_resource_event: (
        "PostResourceFullDuplexResponseRemoveResourceEvent | None"
    ) = betterproto.message_field(3, optional=True, group="event")
    """Событие удаления ресурса"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexResponseRemoveResourceEvent(betterproto.Message):
    """Событие удаления ресурса"""

    resource_id: "ResourceId" = betterproto.message_field(1)
    """Идентификатор ресурса"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexResponseUpsertResourceEvent(betterproto.Message):
    """Событие создания/обновления ресурса"""

    resource: "Resource" = betterproto.message_field(1)
    """Ресурс"""


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class ResourceId(betterproto.Message):
    """Идентификатор ресурса"""

    building_id: "int | None" = betterproto.int32_field(1, optional=True, group="type")
    """Идентификатор объекта строительства"""

    device_id: "int | None" = betterproto.int32_field(2, optional=True, group="type")
    """Идентификатор ПУ"""

    metric_point_id: "str | None" = betterproto.string_field(
        3, optional=True, group="type"
    )
    """Идентификатор ТУ"""

    indicator_id: "int | None" = betterproto.int32_field(4, optional=True, group="type")
    """Идентификатор индикатора"""

    indicator_metric_point: "DeviceIndicatorMetricPoint | None" = (
        betterproto.message_field(5, optional=True, group="type")
    )
    """Связка индикатора и ТУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class Resource(betterproto.Message):
    """Ресурс"""

    building: "Building | None" = betterproto.message_field(
        1, optional=True, group="type"
    )
    """Объект строительства"""

    device: "Device | None" = betterproto.message_field(2, optional=True, group="type")
    """Идентификатор ПУ"""

    metric_point: "DeviceMetricPoint | None" = betterproto.message_field(
        3, optional=True, group="type"
    )
    """Точка учета"""

    indicator: "Indicator | None" = betterproto.message_field(
        4, optional=True, group="type"
    )
    """Индикатор"""

    indicator_metric_point: "DeviceIndicatorMetricPoint | None" = (
        betterproto.message_field(5, optional=True, group="type")
    )
    """Связка индикатора и ТУ"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexRequest(betterproto.Message):
    """Запрос создания задачи с клиента на сервере"""

    request_id: str = betterproto.string_field(1)
    """Идентификатор запроса"""

    resource_async_status: "PostResourceFullDuplexRequestResourceAsyncStatus | None" = (
        betterproto.message_field(2, optional=True, group="task")
    )
    """Результат обработки ресурса на клиенте"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexRequestResourceAsyncStatus(betterproto.Message):
    """Результат обработки ресурса на клиенте"""

    resource_id: "ResourceId" = betterproto.message_field(1)
    """Идентификатор ресурса"""

    data: "PostResourceFullDuplexRequestResourceAsyncStatusSuccess | None" = (
        betterproto.message_field(2, optional=True, group="type")
    )
    """Успех"""

    error: "PostResourceFullDuplexRequestResourceAsyncStatusError | None" = (
        betterproto.message_field(3, optional=True, group="type")
    )
    """Ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexRequestResourceAsyncStatusSuccess(betterproto.Message):
    """Команда принята"""

    pass


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexRequestResourceAsyncStatusError(betterproto.Message):
    """Ошибки обработки ресурса на клиенте"""

    unknown: (
        "PostResourceFullDuplexRequestResourceAsyncStatusErrorUnknownError | None"
    ) = betterproto.message_field(1, optional=True, group="reason")
    """Неизвестная ошибка"""

    @model_validator(mode="after")
    def check_oneof(cls, values):
        return cls._validate_field_groups(values)


@dataclass(eq=False, repr=False, config={"extra": "forbid"})
class PostResourceFullDuplexRequestResourceAsyncStatusErrorUnknownError(
    betterproto.Message
):
    """Неизвестная ошибка на стороне клиента"""

    message: str = betterproto.string_field(1)
    """
    Произвольный текст ошибки на стороне клиента.
     Отправляется в случае если в спецификации нет подходящей ошибки.
     После анализа таких ошибок в спецификацию добавляется специальный тип под эту ошибку
    """


class TemplateServiceStub(betterproto.ServiceStub):
    async def get_template_device(
        self,
        get_template_device_request: "GetTemplateDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetTemplateDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDevice",
            get_template_device_request,
            GetTemplateDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_template_device_list(
        self,
        get_template_device_list_request: "GetTemplateDeviceListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetTemplateDeviceListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDeviceList",
            get_template_device_list_request,
            GetTemplateDeviceListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_template_device_count(
        self,
        get_template_device_count_request: "GetTemplateDeviceCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetTemplateDeviceCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDeviceCount",
            get_template_device_count_request,
            GetTemplateDeviceCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_template_device(
        self,
        post_template_device_request: "PostTemplateDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostTemplateDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/PostTemplateDevice",
            post_template_device_request,
            PostTemplateDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_template_device(
        self,
        delete_template_device_request: "DeleteTemplateDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteTemplateDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/DeleteTemplateDevice",
            delete_template_device_request,
            DeleteTemplateDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_template_indicator(
        self,
        get_template_indicator_request: "GetTemplateIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetTemplateIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicator",
            get_template_indicator_request,
            GetTemplateIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_template_indicator_list(
        self,
        get_template_indicator_list_request: "GetTemplateIndicatorListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetTemplateIndicatorListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicatorList",
            get_template_indicator_list_request,
            GetTemplateIndicatorListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_template_indicator_count(
        self,
        get_template_indicator_count_request: "GetTemplateIndicatorCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetTemplateIndicatorCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicatorCount",
            get_template_indicator_count_request,
            GetTemplateIndicatorCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_template_indicator(
        self,
        post_template_indicator_request: "PostTemplateIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostTemplateIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/PostTemplateIndicator",
            post_template_indicator_request,
            PostTemplateIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_template_indicator(
        self,
        delete_template_indicator_request: "DeleteTemplateIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteTemplateIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.TemplateService/DeleteTemplateIndicator",
            delete_template_indicator_request,
            DeleteTemplateIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class BuildingServiceStub(betterproto.ServiceStub):
    async def get_building(
        self,
        get_building_request: "GetBuildingRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetBuildingResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/GetBuilding",
            get_building_request,
            GetBuildingResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_building_list(
        self,
        get_building_list_request: "GetBuildingListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetBuildingListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingList",
            get_building_list_request,
            GetBuildingListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_building_count(
        self,
        get_building_count_request: "GetBuildingCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetBuildingCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingCount",
            get_building_count_request,
            GetBuildingCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_building(
        self,
        post_building_request: "PostBuildingRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostBuildingResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/PostBuilding",
            post_building_request,
            PostBuildingResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_building_full_duplex(
        self,
        post_building_full_duplex_request_iterator: "AsyncIterable[PostBuildingFullDuplexRequest] | Iterable[PostBuildingFullDuplexRequest]",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[PostBuildingFullDuplexResponse]":
        async for response in self._stream_stream(
            "/keyapis.telemetry_control.v1.BuildingService/PostBuildingFullDuplex",
            post_building_full_duplex_request_iterator,
            PostBuildingFullDuplexRequest,
            PostBuildingFullDuplexResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def delete_building(
        self,
        delete_building_request: "DeleteBuildingRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteBuildingResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/DeleteBuilding",
            delete_building_request,
            DeleteBuildingResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_building_group_list(
        self,
        get_building_group_list_request: "GetBuildingGroupListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetBuildingGroupListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingGroupList",
            get_building_group_list_request,
            GetBuildingGroupListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_building_group_count(
        self,
        get_building_group_count_request: "GetBuildingGroupCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetBuildingGroupCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingGroupCount",
            get_building_group_count_request,
            GetBuildingGroupCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_building_group_attach(
        self,
        put_building_group_attach_request: "PutBuildingGroupAttachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutBuildingGroupAttachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/PutBuildingGroupAttach",
            put_building_group_attach_request,
            PutBuildingGroupAttachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_building_group_detach(
        self,
        put_building_group_detach_request: "PutBuildingGroupDetachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutBuildingGroupDetachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.BuildingService/PutBuildingGroupDetach",
            put_building_group_detach_request,
            PutBuildingGroupDetachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class DeviceServiceStub(betterproto.ServiceStub):
    async def post_device_full_duplex(
        self,
        post_device_full_duplex_request_iterator: "AsyncIterable[PostDeviceFullDuplexRequest] | Iterable[PostDeviceFullDuplexRequest]",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[PostDeviceFullDuplexResponse]":
        async for response in self._stream_stream(
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceFullDuplex",
            post_device_full_duplex_request_iterator,
            PostDeviceFullDuplexRequest,
            PostDeviceFullDuplexResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_device(
        self,
        get_device_request: "GetDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDevice",
            get_device_request,
            GetDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_device_list(
        self,
        get_device_list_request: "GetDeviceListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDeviceListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceList",
            get_device_list_request,
            GetDeviceListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_device_count(
        self,
        get_device_count_request: "GetDeviceCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceCount",
            get_device_count_request,
            GetDeviceCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_device_replace(
        self,
        post_device_replace_request: "PostDeviceReplaceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostDeviceReplaceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceReplace",
            post_device_replace_request,
            PostDeviceReplaceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_device(
        self,
        post_device_request: "PostDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PostDevice",
            post_device_request,
            PostDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_device(
        self,
        delete_device_request: "DeleteDeviceRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteDeviceResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/DeleteDevice",
            delete_device_request,
            DeleteDeviceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_device_indicator(
        self,
        post_device_indicator_request: "PostDeviceIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostDeviceIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceIndicator",
            post_device_indicator_request,
            PostDeviceIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_device_indicator(
        self,
        get_device_indicator_request: "GetDeviceIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicator",
            get_device_indicator_request,
            GetDeviceIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_device_indicator_list(
        self,
        get_device_indicator_list_request: "GetDeviceIndicatorListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDeviceIndicatorListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorList",
            get_device_indicator_list_request,
            GetDeviceIndicatorListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_device_indicator_count(
        self,
        get_device_indicator_count_request: "GetDeviceIndicatorCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceIndicatorCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorCount",
            get_device_indicator_count_request,
            GetDeviceIndicatorCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_device_indicator(
        self,
        delete_device_indicator_request: "DeleteDeviceIndicatorRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteDeviceIndicatorResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/DeleteDeviceIndicator",
            delete_device_indicator_request,
            DeleteDeviceIndicatorResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_device_indicator_metric_point_list(
        self,
        get_device_indicator_metric_point_list_request: "GetDeviceIndicatorMetricPointListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDeviceIndicatorMetricPointListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorMetricPointList",
            get_device_indicator_metric_point_list_request,
            GetDeviceIndicatorMetricPointListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_device_indicator_metric_point_count(
        self,
        get_device_indicator_metric_point_count_request: "GetDeviceIndicatorMetricPointCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceIndicatorMetricPointCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorMetricPointCount",
            get_device_indicator_metric_point_count_request,
            GetDeviceIndicatorMetricPointCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_device_indicator_metric_point_attach(
        self,
        put_device_indicator_metric_point_attach_request: "PutDeviceIndicatorMetricPointAttachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutDeviceIndicatorMetricPointAttachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceIndicatorMetricPointAttach",
            put_device_indicator_metric_point_attach_request,
            PutDeviceIndicatorMetricPointAttachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_device_indicator_metric_point_detach(
        self,
        put_device_indicator_metric_point_detach_request: "PutDeviceIndicatorMetricPointDetachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutDeviceIndicatorMetricPointDetachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceIndicatorMetricPointDetach",
            put_device_indicator_metric_point_detach_request,
            PutDeviceIndicatorMetricPointDetachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_device_group_list(
        self,
        get_device_group_list_request: "GetDeviceGroupListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDeviceGroupListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceGroupList",
            get_device_group_list_request,
            GetDeviceGroupListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_device_group_count(
        self,
        get_device_group_count_request: "GetDeviceGroupCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDeviceGroupCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceGroupCount",
            get_device_group_count_request,
            GetDeviceGroupCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_device_group_attach(
        self,
        put_device_group_attach_request: "PutDeviceGroupAttachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutDeviceGroupAttachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceGroupAttach",
            put_device_group_attach_request,
            PutDeviceGroupAttachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def put_device_group_detach(
        self,
        put_device_group_detach_request: "PutDeviceGroupDetachRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PutDeviceGroupDetachResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceGroupDetach",
            put_device_group_detach_request,
            PutDeviceGroupDetachResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class MetricPointServiceStub(betterproto.ServiceStub):
    async def get_metric_point(
        self,
        get_metric_point_request: "GetMetricPointRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetMetricPointResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPoint",
            get_metric_point_request,
            GetMetricPointResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_metric_point_list(
        self,
        get_metric_point_list_request: "GetMetricPointListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetMetricPointListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPointList",
            get_metric_point_list_request,
            GetMetricPointListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_metric_point_count(
        self,
        get_metric_point_count_request: "GetMetricPointCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetMetricPointCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPointCount",
            get_metric_point_count_request,
            GetMetricPointCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_metric_point(
        self,
        post_metric_point_request: "PostMetricPointRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostMetricPointResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.MetricPointService/PostMetricPoint",
            post_metric_point_request,
            PostMetricPointResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_metric_point(
        self,
        delete_metric_point_request: "DeleteMetricPointRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteMetricPointResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.MetricPointService/DeleteMetricPoint",
            delete_metric_point_request,
            DeleteMetricPointResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class DictionaryServiceStub(betterproto.ServiceStub):
    async def get_dictionary_device_model_list(
        self,
        get_dictionary_device_model_list_request: "GetDictionaryDeviceModelListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDictionaryDeviceModelListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryDeviceModelList",
            get_dictionary_device_model_list_request,
            GetDictionaryDeviceModelListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_dictionary_device_model_count(
        self,
        get_dictionary_device_model_count_request: "GetDictionaryDeviceModelCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDictionaryDeviceModelCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryDeviceModelCount",
            get_dictionary_device_model_count_request,
            GetDictionaryDeviceModelCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_dictionary_device_model(
        self,
        post_dictionary_device_model_request: "PostDictionaryDeviceModelRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "PostDictionaryDeviceModelResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DictionaryService/PostDictionaryDeviceModel",
            post_dictionary_device_model_request,
            PostDictionaryDeviceModelResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_dictionary_device_model(
        self,
        delete_dictionary_device_model_request: "DeleteDictionaryDeviceModelRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "DeleteDictionaryDeviceModelResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DictionaryService/DeleteDictionaryDeviceModel",
            delete_dictionary_device_model_request,
            DeleteDictionaryDeviceModelResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_dictionary_mrf_list(
        self,
        get_dictionary_mrf_list_request: "GetDictionaryMrfListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDictionaryMrfListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryMrfList",
            get_dictionary_mrf_list_request,
            GetDictionaryMrfListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_dictionary_mrf_count(
        self,
        get_dictionary_mrf_count_request: "GetDictionaryMrfCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDictionaryMrfCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryMrfCount",
            get_dictionary_mrf_count_request,
            GetDictionaryMrfCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_dictionary_rf_list(
        self,
        get_dictionary_rf_list_request: "GetDictionaryRfListRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[GetDictionaryRfListResponse]":
        async for response in self._unary_stream(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryRfList",
            get_dictionary_rf_list_request,
            GetDictionaryRfListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_dictionary_rf_count(
        self,
        get_dictionary_rf_count_request: "GetDictionaryRfCountRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetDictionaryRfCountResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryRfCount",
            get_dictionary_rf_count_request,
            GetDictionaryRfCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class SystemServiceStub(betterproto.ServiceStub):
    async def get_system_status(
        self,
        get_system_status_request: "GetSystemStatusRequest",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "GetSystemStatusResponse":
        return await self._unary_unary(
            "/keyapis.telemetry_control.v1.SystemService/GetSystemStatus",
            get_system_status_request,
            GetSystemStatusResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class StreamServiceStub(betterproto.ServiceStub):
    async def post_resource_full_duplex(
        self,
        post_resource_full_duplex_request_iterator: "AsyncIterable[PostResourceFullDuplexRequest] | Iterable[PostResourceFullDuplexRequest]",
        *,
        timeout: "float | None" = None,
        deadline: "Deadline | None" = None,
        metadata: "MetadataLike | None" = None
    ) -> "AsyncIterator[PostResourceFullDuplexResponse]":
        async for response in self._stream_stream(
            "/keyapis.telemetry_control.v1.StreamService/PostResourceFullDuplex",
            post_resource_full_duplex_request_iterator,
            PostResourceFullDuplexRequest,
            PostResourceFullDuplexResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response


class TemplateServiceBase(ServiceBase):

    async def get_template_device(
        self, get_template_device_request: "GetTemplateDeviceRequest"
    ) -> "GetTemplateDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_template_device_list(
        self, get_template_device_list_request: "GetTemplateDeviceListRequest"
    ) -> "AsyncIterator[GetTemplateDeviceListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetTemplateDeviceListResponse()

    async def get_template_device_count(
        self, get_template_device_count_request: "GetTemplateDeviceCountRequest"
    ) -> "GetTemplateDeviceCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_template_device(
        self, post_template_device_request: "PostTemplateDeviceRequest"
    ) -> "PostTemplateDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_template_device(
        self, delete_template_device_request: "DeleteTemplateDeviceRequest"
    ) -> "DeleteTemplateDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_template_indicator(
        self, get_template_indicator_request: "GetTemplateIndicatorRequest"
    ) -> "GetTemplateIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_template_indicator_list(
        self, get_template_indicator_list_request: "GetTemplateIndicatorListRequest"
    ) -> "AsyncIterator[GetTemplateIndicatorListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetTemplateIndicatorListResponse()

    async def get_template_indicator_count(
        self, get_template_indicator_count_request: "GetTemplateIndicatorCountRequest"
    ) -> "GetTemplateIndicatorCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_template_indicator(
        self, post_template_indicator_request: "PostTemplateIndicatorRequest"
    ) -> "PostTemplateIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_template_indicator(
        self, delete_template_indicator_request: "DeleteTemplateIndicatorRequest"
    ) -> "DeleteTemplateIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_template_device(
        self,
        stream: "grpclib.server.Stream[GetTemplateDeviceRequest, GetTemplateDeviceResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_template_device(request)
        await stream.send_message(response)

    async def __rpc_get_template_device_list(
        self,
        stream: "grpclib.server.Stream[GetTemplateDeviceListRequest, GetTemplateDeviceListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_template_device_list,
            stream,
            request,
        )

    async def __rpc_get_template_device_count(
        self,
        stream: "grpclib.server.Stream[GetTemplateDeviceCountRequest, GetTemplateDeviceCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_template_device_count(request)
        await stream.send_message(response)

    async def __rpc_post_template_device(
        self,
        stream: "grpclib.server.Stream[PostTemplateDeviceRequest, PostTemplateDeviceResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_template_device(request)
        await stream.send_message(response)

    async def __rpc_delete_template_device(
        self,
        stream: "grpclib.server.Stream[DeleteTemplateDeviceRequest, DeleteTemplateDeviceResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_template_device(request)
        await stream.send_message(response)

    async def __rpc_get_template_indicator(
        self,
        stream: "grpclib.server.Stream[GetTemplateIndicatorRequest, GetTemplateIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_template_indicator(request)
        await stream.send_message(response)

    async def __rpc_get_template_indicator_list(
        self,
        stream: "grpclib.server.Stream[GetTemplateIndicatorListRequest, GetTemplateIndicatorListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_template_indicator_list,
            stream,
            request,
        )

    async def __rpc_get_template_indicator_count(
        self,
        stream: "grpclib.server.Stream[GetTemplateIndicatorCountRequest, GetTemplateIndicatorCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_template_indicator_count(request)
        await stream.send_message(response)

    async def __rpc_post_template_indicator(
        self,
        stream: "grpclib.server.Stream[PostTemplateIndicatorRequest, PostTemplateIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_template_indicator(request)
        await stream.send_message(response)

    async def __rpc_delete_template_indicator(
        self,
        stream: "grpclib.server.Stream[DeleteTemplateIndicatorRequest, DeleteTemplateIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_template_indicator(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDevice": grpclib.const.Handler(
                self.__rpc_get_template_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetTemplateDeviceRequest,
                GetTemplateDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDeviceList": grpclib.const.Handler(
                self.__rpc_get_template_device_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetTemplateDeviceListRequest,
                GetTemplateDeviceListResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateDeviceCount": grpclib.const.Handler(
                self.__rpc_get_template_device_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetTemplateDeviceCountRequest,
                GetTemplateDeviceCountResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/PostTemplateDevice": grpclib.const.Handler(
                self.__rpc_post_template_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostTemplateDeviceRequest,
                PostTemplateDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/DeleteTemplateDevice": grpclib.const.Handler(
                self.__rpc_delete_template_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteTemplateDeviceRequest,
                DeleteTemplateDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicator": grpclib.const.Handler(
                self.__rpc_get_template_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetTemplateIndicatorRequest,
                GetTemplateIndicatorResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicatorList": grpclib.const.Handler(
                self.__rpc_get_template_indicator_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetTemplateIndicatorListRequest,
                GetTemplateIndicatorListResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/GetTemplateIndicatorCount": grpclib.const.Handler(
                self.__rpc_get_template_indicator_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetTemplateIndicatorCountRequest,
                GetTemplateIndicatorCountResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/PostTemplateIndicator": grpclib.const.Handler(
                self.__rpc_post_template_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostTemplateIndicatorRequest,
                PostTemplateIndicatorResponse,
            ),
            "/keyapis.telemetry_control.v1.TemplateService/DeleteTemplateIndicator": grpclib.const.Handler(
                self.__rpc_delete_template_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteTemplateIndicatorRequest,
                DeleteTemplateIndicatorResponse,
            ),
        }


class BuildingServiceBase(ServiceBase):

    async def get_building(
        self, get_building_request: "GetBuildingRequest"
    ) -> "GetBuildingResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_building_list(
        self, get_building_list_request: "GetBuildingListRequest"
    ) -> "AsyncIterator[GetBuildingListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetBuildingListResponse()

    async def get_building_count(
        self, get_building_count_request: "GetBuildingCountRequest"
    ) -> "GetBuildingCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_building(
        self, post_building_request: "PostBuildingRequest"
    ) -> "PostBuildingResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_building_full_duplex(
        self,
        post_building_full_duplex_request_iterator: "AsyncIterator[PostBuildingFullDuplexRequest]",
    ) -> "AsyncIterator[PostBuildingFullDuplexResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield PostBuildingFullDuplexResponse()

    async def delete_building(
        self, delete_building_request: "DeleteBuildingRequest"
    ) -> "DeleteBuildingResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_building_group_list(
        self, get_building_group_list_request: "GetBuildingGroupListRequest"
    ) -> "AsyncIterator[GetBuildingGroupListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetBuildingGroupListResponse()

    async def get_building_group_count(
        self, get_building_group_count_request: "GetBuildingGroupCountRequest"
    ) -> "GetBuildingGroupCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_building_group_attach(
        self, put_building_group_attach_request: "PutBuildingGroupAttachRequest"
    ) -> "PutBuildingGroupAttachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_building_group_detach(
        self, put_building_group_detach_request: "PutBuildingGroupDetachRequest"
    ) -> "PutBuildingGroupDetachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_building(
        self, stream: "grpclib.server.Stream[GetBuildingRequest, GetBuildingResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_building(request)
        await stream.send_message(response)

    async def __rpc_get_building_list(
        self,
        stream: "grpclib.server.Stream[GetBuildingListRequest, GetBuildingListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_building_list,
            stream,
            request,
        )

    async def __rpc_get_building_count(
        self,
        stream: "grpclib.server.Stream[GetBuildingCountRequest, GetBuildingCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_building_count(request)
        await stream.send_message(response)

    async def __rpc_post_building(
        self, stream: "grpclib.server.Stream[PostBuildingRequest, PostBuildingResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_building(request)
        await stream.send_message(response)

    async def __rpc_post_building_full_duplex(
        self,
        stream: "grpclib.server.Stream[PostBuildingFullDuplexRequest, PostBuildingFullDuplexResponse]",
    ) -> None:
        request = stream.__aiter__()
        await self._call_rpc_handler_server_stream(
            self.post_building_full_duplex,
            stream,
            request,
        )

    async def __rpc_delete_building(
        self,
        stream: "grpclib.server.Stream[DeleteBuildingRequest, DeleteBuildingResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_building(request)
        await stream.send_message(response)

    async def __rpc_get_building_group_list(
        self,
        stream: "grpclib.server.Stream[GetBuildingGroupListRequest, GetBuildingGroupListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_building_group_list,
            stream,
            request,
        )

    async def __rpc_get_building_group_count(
        self,
        stream: "grpclib.server.Stream[GetBuildingGroupCountRequest, GetBuildingGroupCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_building_group_count(request)
        await stream.send_message(response)

    async def __rpc_put_building_group_attach(
        self,
        stream: "grpclib.server.Stream[PutBuildingGroupAttachRequest, PutBuildingGroupAttachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_building_group_attach(request)
        await stream.send_message(response)

    async def __rpc_put_building_group_detach(
        self,
        stream: "grpclib.server.Stream[PutBuildingGroupDetachRequest, PutBuildingGroupDetachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_building_group_detach(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.BuildingService/GetBuilding": grpclib.const.Handler(
                self.__rpc_get_building,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBuildingRequest,
                GetBuildingResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingList": grpclib.const.Handler(
                self.__rpc_get_building_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetBuildingListRequest,
                GetBuildingListResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingCount": grpclib.const.Handler(
                self.__rpc_get_building_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBuildingCountRequest,
                GetBuildingCountResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/PostBuilding": grpclib.const.Handler(
                self.__rpc_post_building,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostBuildingRequest,
                PostBuildingResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/PostBuildingFullDuplex": grpclib.const.Handler(
                self.__rpc_post_building_full_duplex,
                grpclib.const.Cardinality.STREAM_STREAM,
                PostBuildingFullDuplexRequest,
                PostBuildingFullDuplexResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/DeleteBuilding": grpclib.const.Handler(
                self.__rpc_delete_building,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteBuildingRequest,
                DeleteBuildingResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingGroupList": grpclib.const.Handler(
                self.__rpc_get_building_group_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetBuildingGroupListRequest,
                GetBuildingGroupListResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/GetBuildingGroupCount": grpclib.const.Handler(
                self.__rpc_get_building_group_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBuildingGroupCountRequest,
                GetBuildingGroupCountResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/PutBuildingGroupAttach": grpclib.const.Handler(
                self.__rpc_put_building_group_attach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutBuildingGroupAttachRequest,
                PutBuildingGroupAttachResponse,
            ),
            "/keyapis.telemetry_control.v1.BuildingService/PutBuildingGroupDetach": grpclib.const.Handler(
                self.__rpc_put_building_group_detach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutBuildingGroupDetachRequest,
                PutBuildingGroupDetachResponse,
            ),
        }


class DeviceServiceBase(ServiceBase):

    async def post_device_full_duplex(
        self,
        post_device_full_duplex_request_iterator: "AsyncIterator[PostDeviceFullDuplexRequest]",
    ) -> "AsyncIterator[PostDeviceFullDuplexResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield PostDeviceFullDuplexResponse()

    async def get_device(
        self, get_device_request: "GetDeviceRequest"
    ) -> "GetDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_device_list(
        self, get_device_list_request: "GetDeviceListRequest"
    ) -> "AsyncIterator[GetDeviceListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDeviceListResponse()

    async def get_device_count(
        self, get_device_count_request: "GetDeviceCountRequest"
    ) -> "GetDeviceCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_device_replace(
        self, post_device_replace_request: "PostDeviceReplaceRequest"
    ) -> "PostDeviceReplaceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_device(
        self, post_device_request: "PostDeviceRequest"
    ) -> "PostDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_device(
        self, delete_device_request: "DeleteDeviceRequest"
    ) -> "DeleteDeviceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_device_indicator(
        self, post_device_indicator_request: "PostDeviceIndicatorRequest"
    ) -> "PostDeviceIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_device_indicator(
        self, get_device_indicator_request: "GetDeviceIndicatorRequest"
    ) -> "GetDeviceIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_device_indicator_list(
        self, get_device_indicator_list_request: "GetDeviceIndicatorListRequest"
    ) -> "AsyncIterator[GetDeviceIndicatorListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDeviceIndicatorListResponse()

    async def get_device_indicator_count(
        self, get_device_indicator_count_request: "GetDeviceIndicatorCountRequest"
    ) -> "GetDeviceIndicatorCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_device_indicator(
        self, delete_device_indicator_request: "DeleteDeviceIndicatorRequest"
    ) -> "DeleteDeviceIndicatorResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_device_indicator_metric_point_list(
        self,
        get_device_indicator_metric_point_list_request: "GetDeviceIndicatorMetricPointListRequest",
    ) -> "AsyncIterator[GetDeviceIndicatorMetricPointListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDeviceIndicatorMetricPointListResponse()

    async def get_device_indicator_metric_point_count(
        self,
        get_device_indicator_metric_point_count_request: "GetDeviceIndicatorMetricPointCountRequest",
    ) -> "GetDeviceIndicatorMetricPointCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_device_indicator_metric_point_attach(
        self,
        put_device_indicator_metric_point_attach_request: "PutDeviceIndicatorMetricPointAttachRequest",
    ) -> "PutDeviceIndicatorMetricPointAttachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_device_indicator_metric_point_detach(
        self,
        put_device_indicator_metric_point_detach_request: "PutDeviceIndicatorMetricPointDetachRequest",
    ) -> "PutDeviceIndicatorMetricPointDetachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_device_group_list(
        self, get_device_group_list_request: "GetDeviceGroupListRequest"
    ) -> "AsyncIterator[GetDeviceGroupListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDeviceGroupListResponse()

    async def get_device_group_count(
        self, get_device_group_count_request: "GetDeviceGroupCountRequest"
    ) -> "GetDeviceGroupCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_device_group_attach(
        self, put_device_group_attach_request: "PutDeviceGroupAttachRequest"
    ) -> "PutDeviceGroupAttachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def put_device_group_detach(
        self, put_device_group_detach_request: "PutDeviceGroupDetachRequest"
    ) -> "PutDeviceGroupDetachResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_post_device_full_duplex(
        self,
        stream: "grpclib.server.Stream[PostDeviceFullDuplexRequest, PostDeviceFullDuplexResponse]",
    ) -> None:
        request = stream.__aiter__()
        await self._call_rpc_handler_server_stream(
            self.post_device_full_duplex,
            stream,
            request,
        )

    async def __rpc_get_device(
        self, stream: "grpclib.server.Stream[GetDeviceRequest, GetDeviceResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device(request)
        await stream.send_message(response)

    async def __rpc_get_device_list(
        self,
        stream: "grpclib.server.Stream[GetDeviceListRequest, GetDeviceListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_device_list,
            stream,
            request,
        )

    async def __rpc_get_device_count(
        self,
        stream: "grpclib.server.Stream[GetDeviceCountRequest, GetDeviceCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device_count(request)
        await stream.send_message(response)

    async def __rpc_post_device_replace(
        self,
        stream: "grpclib.server.Stream[PostDeviceReplaceRequest, PostDeviceReplaceResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_device_replace(request)
        await stream.send_message(response)

    async def __rpc_post_device(
        self, stream: "grpclib.server.Stream[PostDeviceRequest, PostDeviceResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_device(request)
        await stream.send_message(response)

    async def __rpc_delete_device(
        self, stream: "grpclib.server.Stream[DeleteDeviceRequest, DeleteDeviceResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_device(request)
        await stream.send_message(response)

    async def __rpc_post_device_indicator(
        self,
        stream: "grpclib.server.Stream[PostDeviceIndicatorRequest, PostDeviceIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_device_indicator(request)
        await stream.send_message(response)

    async def __rpc_get_device_indicator(
        self,
        stream: "grpclib.server.Stream[GetDeviceIndicatorRequest, GetDeviceIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device_indicator(request)
        await stream.send_message(response)

    async def __rpc_get_device_indicator_list(
        self,
        stream: "grpclib.server.Stream[GetDeviceIndicatorListRequest, GetDeviceIndicatorListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_device_indicator_list,
            stream,
            request,
        )

    async def __rpc_get_device_indicator_count(
        self,
        stream: "grpclib.server.Stream[GetDeviceIndicatorCountRequest, GetDeviceIndicatorCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device_indicator_count(request)
        await stream.send_message(response)

    async def __rpc_delete_device_indicator(
        self,
        stream: "grpclib.server.Stream[DeleteDeviceIndicatorRequest, DeleteDeviceIndicatorResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_device_indicator(request)
        await stream.send_message(response)

    async def __rpc_get_device_indicator_metric_point_list(
        self,
        stream: "grpclib.server.Stream[GetDeviceIndicatorMetricPointListRequest, GetDeviceIndicatorMetricPointListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_device_indicator_metric_point_list,
            stream,
            request,
        )

    async def __rpc_get_device_indicator_metric_point_count(
        self,
        stream: "grpclib.server.Stream[GetDeviceIndicatorMetricPointCountRequest, GetDeviceIndicatorMetricPointCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device_indicator_metric_point_count(request)
        await stream.send_message(response)

    async def __rpc_put_device_indicator_metric_point_attach(
        self,
        stream: "grpclib.server.Stream[PutDeviceIndicatorMetricPointAttachRequest, PutDeviceIndicatorMetricPointAttachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_device_indicator_metric_point_attach(request)
        await stream.send_message(response)

    async def __rpc_put_device_indicator_metric_point_detach(
        self,
        stream: "grpclib.server.Stream[PutDeviceIndicatorMetricPointDetachRequest, PutDeviceIndicatorMetricPointDetachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_device_indicator_metric_point_detach(request)
        await stream.send_message(response)

    async def __rpc_get_device_group_list(
        self,
        stream: "grpclib.server.Stream[GetDeviceGroupListRequest, GetDeviceGroupListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_device_group_list,
            stream,
            request,
        )

    async def __rpc_get_device_group_count(
        self,
        stream: "grpclib.server.Stream[GetDeviceGroupCountRequest, GetDeviceGroupCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_device_group_count(request)
        await stream.send_message(response)

    async def __rpc_put_device_group_attach(
        self,
        stream: "grpclib.server.Stream[PutDeviceGroupAttachRequest, PutDeviceGroupAttachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_device_group_attach(request)
        await stream.send_message(response)

    async def __rpc_put_device_group_detach(
        self,
        stream: "grpclib.server.Stream[PutDeviceGroupDetachRequest, PutDeviceGroupDetachResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.put_device_group_detach(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceFullDuplex": grpclib.const.Handler(
                self.__rpc_post_device_full_duplex,
                grpclib.const.Cardinality.STREAM_STREAM,
                PostDeviceFullDuplexRequest,
                PostDeviceFullDuplexResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDevice": grpclib.const.Handler(
                self.__rpc_get_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceRequest,
                GetDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceList": grpclib.const.Handler(
                self.__rpc_get_device_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDeviceListRequest,
                GetDeviceListResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceCount": grpclib.const.Handler(
                self.__rpc_get_device_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceCountRequest,
                GetDeviceCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceReplace": grpclib.const.Handler(
                self.__rpc_post_device_replace,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostDeviceReplaceRequest,
                PostDeviceReplaceResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PostDevice": grpclib.const.Handler(
                self.__rpc_post_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostDeviceRequest,
                PostDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/DeleteDevice": grpclib.const.Handler(
                self.__rpc_delete_device,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteDeviceRequest,
                DeleteDeviceResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PostDeviceIndicator": grpclib.const.Handler(
                self.__rpc_post_device_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostDeviceIndicatorRequest,
                PostDeviceIndicatorResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicator": grpclib.const.Handler(
                self.__rpc_get_device_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceIndicatorRequest,
                GetDeviceIndicatorResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorList": grpclib.const.Handler(
                self.__rpc_get_device_indicator_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDeviceIndicatorListRequest,
                GetDeviceIndicatorListResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorCount": grpclib.const.Handler(
                self.__rpc_get_device_indicator_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceIndicatorCountRequest,
                GetDeviceIndicatorCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/DeleteDeviceIndicator": grpclib.const.Handler(
                self.__rpc_delete_device_indicator,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteDeviceIndicatorRequest,
                DeleteDeviceIndicatorResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorMetricPointList": grpclib.const.Handler(
                self.__rpc_get_device_indicator_metric_point_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDeviceIndicatorMetricPointListRequest,
                GetDeviceIndicatorMetricPointListResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceIndicatorMetricPointCount": grpclib.const.Handler(
                self.__rpc_get_device_indicator_metric_point_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceIndicatorMetricPointCountRequest,
                GetDeviceIndicatorMetricPointCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceIndicatorMetricPointAttach": grpclib.const.Handler(
                self.__rpc_put_device_indicator_metric_point_attach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutDeviceIndicatorMetricPointAttachRequest,
                PutDeviceIndicatorMetricPointAttachResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceIndicatorMetricPointDetach": grpclib.const.Handler(
                self.__rpc_put_device_indicator_metric_point_detach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutDeviceIndicatorMetricPointDetachRequest,
                PutDeviceIndicatorMetricPointDetachResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceGroupList": grpclib.const.Handler(
                self.__rpc_get_device_group_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDeviceGroupListRequest,
                GetDeviceGroupListResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/GetDeviceGroupCount": grpclib.const.Handler(
                self.__rpc_get_device_group_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDeviceGroupCountRequest,
                GetDeviceGroupCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceGroupAttach": grpclib.const.Handler(
                self.__rpc_put_device_group_attach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutDeviceGroupAttachRequest,
                PutDeviceGroupAttachResponse,
            ),
            "/keyapis.telemetry_control.v1.DeviceService/PutDeviceGroupDetach": grpclib.const.Handler(
                self.__rpc_put_device_group_detach,
                grpclib.const.Cardinality.UNARY_UNARY,
                PutDeviceGroupDetachRequest,
                PutDeviceGroupDetachResponse,
            ),
        }


class MetricPointServiceBase(ServiceBase):

    async def get_metric_point(
        self, get_metric_point_request: "GetMetricPointRequest"
    ) -> "GetMetricPointResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_metric_point_list(
        self, get_metric_point_list_request: "GetMetricPointListRequest"
    ) -> "AsyncIterator[GetMetricPointListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetMetricPointListResponse()

    async def get_metric_point_count(
        self, get_metric_point_count_request: "GetMetricPointCountRequest"
    ) -> "GetMetricPointCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_metric_point(
        self, post_metric_point_request: "PostMetricPointRequest"
    ) -> "PostMetricPointResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_metric_point(
        self, delete_metric_point_request: "DeleteMetricPointRequest"
    ) -> "DeleteMetricPointResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_metric_point(
        self,
        stream: "grpclib.server.Stream[GetMetricPointRequest, GetMetricPointResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_metric_point(request)
        await stream.send_message(response)

    async def __rpc_get_metric_point_list(
        self,
        stream: "grpclib.server.Stream[GetMetricPointListRequest, GetMetricPointListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_metric_point_list,
            stream,
            request,
        )

    async def __rpc_get_metric_point_count(
        self,
        stream: "grpclib.server.Stream[GetMetricPointCountRequest, GetMetricPointCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_metric_point_count(request)
        await stream.send_message(response)

    async def __rpc_post_metric_point(
        self,
        stream: "grpclib.server.Stream[PostMetricPointRequest, PostMetricPointResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_metric_point(request)
        await stream.send_message(response)

    async def __rpc_delete_metric_point(
        self,
        stream: "grpclib.server.Stream[DeleteMetricPointRequest, DeleteMetricPointResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_metric_point(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPoint": grpclib.const.Handler(
                self.__rpc_get_metric_point,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetMetricPointRequest,
                GetMetricPointResponse,
            ),
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPointList": grpclib.const.Handler(
                self.__rpc_get_metric_point_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetMetricPointListRequest,
                GetMetricPointListResponse,
            ),
            "/keyapis.telemetry_control.v1.MetricPointService/GetMetricPointCount": grpclib.const.Handler(
                self.__rpc_get_metric_point_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetMetricPointCountRequest,
                GetMetricPointCountResponse,
            ),
            "/keyapis.telemetry_control.v1.MetricPointService/PostMetricPoint": grpclib.const.Handler(
                self.__rpc_post_metric_point,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostMetricPointRequest,
                PostMetricPointResponse,
            ),
            "/keyapis.telemetry_control.v1.MetricPointService/DeleteMetricPoint": grpclib.const.Handler(
                self.__rpc_delete_metric_point,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteMetricPointRequest,
                DeleteMetricPointResponse,
            ),
        }


class DictionaryServiceBase(ServiceBase):

    async def get_dictionary_device_model_list(
        self,
        get_dictionary_device_model_list_request: "GetDictionaryDeviceModelListRequest",
    ) -> "AsyncIterator[GetDictionaryDeviceModelListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDictionaryDeviceModelListResponse()

    async def get_dictionary_device_model_count(
        self,
        get_dictionary_device_model_count_request: "GetDictionaryDeviceModelCountRequest",
    ) -> "GetDictionaryDeviceModelCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_dictionary_device_model(
        self, post_dictionary_device_model_request: "PostDictionaryDeviceModelRequest"
    ) -> "PostDictionaryDeviceModelResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_dictionary_device_model(
        self,
        delete_dictionary_device_model_request: "DeleteDictionaryDeviceModelRequest",
    ) -> "DeleteDictionaryDeviceModelResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_dictionary_mrf_list(
        self, get_dictionary_mrf_list_request: "GetDictionaryMrfListRequest"
    ) -> "AsyncIterator[GetDictionaryMrfListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDictionaryMrfListResponse()

    async def get_dictionary_mrf_count(
        self, get_dictionary_mrf_count_request: "GetDictionaryMrfCountRequest"
    ) -> "GetDictionaryMrfCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_dictionary_rf_list(
        self, get_dictionary_rf_list_request: "GetDictionaryRfListRequest"
    ) -> "AsyncIterator[GetDictionaryRfListResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetDictionaryRfListResponse()

    async def get_dictionary_rf_count(
        self, get_dictionary_rf_count_request: "GetDictionaryRfCountRequest"
    ) -> "GetDictionaryRfCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_dictionary_device_model_list(
        self,
        stream: "grpclib.server.Stream[GetDictionaryDeviceModelListRequest, GetDictionaryDeviceModelListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_dictionary_device_model_list,
            stream,
            request,
        )

    async def __rpc_get_dictionary_device_model_count(
        self,
        stream: "grpclib.server.Stream[GetDictionaryDeviceModelCountRequest, GetDictionaryDeviceModelCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_dictionary_device_model_count(request)
        await stream.send_message(response)

    async def __rpc_post_dictionary_device_model(
        self,
        stream: "grpclib.server.Stream[PostDictionaryDeviceModelRequest, PostDictionaryDeviceModelResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_dictionary_device_model(request)
        await stream.send_message(response)

    async def __rpc_delete_dictionary_device_model(
        self,
        stream: "grpclib.server.Stream[DeleteDictionaryDeviceModelRequest, DeleteDictionaryDeviceModelResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_dictionary_device_model(request)
        await stream.send_message(response)

    async def __rpc_get_dictionary_mrf_list(
        self,
        stream: "grpclib.server.Stream[GetDictionaryMrfListRequest, GetDictionaryMrfListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_dictionary_mrf_list,
            stream,
            request,
        )

    async def __rpc_get_dictionary_mrf_count(
        self,
        stream: "grpclib.server.Stream[GetDictionaryMrfCountRequest, GetDictionaryMrfCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_dictionary_mrf_count(request)
        await stream.send_message(response)

    async def __rpc_get_dictionary_rf_list(
        self,
        stream: "grpclib.server.Stream[GetDictionaryRfListRequest, GetDictionaryRfListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_dictionary_rf_list,
            stream,
            request,
        )

    async def __rpc_get_dictionary_rf_count(
        self,
        stream: "grpclib.server.Stream[GetDictionaryRfCountRequest, GetDictionaryRfCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_dictionary_rf_count(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryDeviceModelList": grpclib.const.Handler(
                self.__rpc_get_dictionary_device_model_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDictionaryDeviceModelListRequest,
                GetDictionaryDeviceModelListResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryDeviceModelCount": grpclib.const.Handler(
                self.__rpc_get_dictionary_device_model_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDictionaryDeviceModelCountRequest,
                GetDictionaryDeviceModelCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/PostDictionaryDeviceModel": grpclib.const.Handler(
                self.__rpc_post_dictionary_device_model,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostDictionaryDeviceModelRequest,
                PostDictionaryDeviceModelResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/DeleteDictionaryDeviceModel": grpclib.const.Handler(
                self.__rpc_delete_dictionary_device_model,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteDictionaryDeviceModelRequest,
                DeleteDictionaryDeviceModelResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryMrfList": grpclib.const.Handler(
                self.__rpc_get_dictionary_mrf_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDictionaryMrfListRequest,
                GetDictionaryMrfListResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryMrfCount": grpclib.const.Handler(
                self.__rpc_get_dictionary_mrf_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDictionaryMrfCountRequest,
                GetDictionaryMrfCountResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryRfList": grpclib.const.Handler(
                self.__rpc_get_dictionary_rf_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetDictionaryRfListRequest,
                GetDictionaryRfListResponse,
            ),
            "/keyapis.telemetry_control.v1.DictionaryService/GetDictionaryRfCount": grpclib.const.Handler(
                self.__rpc_get_dictionary_rf_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetDictionaryRfCountRequest,
                GetDictionaryRfCountResponse,
            ),
        }


class SystemServiceBase(ServiceBase):

    async def get_system_status(
        self, get_system_status_request: "GetSystemStatusRequest"
    ) -> "GetSystemStatusResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_system_status(
        self,
        stream: "grpclib.server.Stream[GetSystemStatusRequest, GetSystemStatusResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_system_status(request)
        await stream.send_message(response)

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.SystemService/GetSystemStatus": grpclib.const.Handler(
                self.__rpc_get_system_status,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetSystemStatusRequest,
                GetSystemStatusResponse,
            ),
        }


class StreamServiceBase(ServiceBase):

    async def post_resource_full_duplex(
        self,
        post_resource_full_duplex_request_iterator: "AsyncIterator[PostResourceFullDuplexRequest]",
    ) -> "AsyncIterator[PostResourceFullDuplexResponse]":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield PostResourceFullDuplexResponse()

    async def __rpc_post_resource_full_duplex(
        self,
        stream: "grpclib.server.Stream[PostResourceFullDuplexRequest, PostResourceFullDuplexResponse]",
    ) -> None:
        request = stream.__aiter__()
        await self._call_rpc_handler_server_stream(
            self.post_resource_full_duplex,
            stream,
            request,
        )

    def __mapping__(self) -> "dict[str, grpclib.const.Handler]":
        return {
            "/keyapis.telemetry_control.v1.StreamService/PostResourceFullDuplex": grpclib.const.Handler(
                self.__rpc_post_resource_full_duplex,
                grpclib.const.Cardinality.STREAM_STREAM,
                PostResourceFullDuplexRequest,
                PostResourceFullDuplexResponse,
            ),
        }


rebuild_dataclass(PostTemplateDeviceRequest)  # type: ignore
rebuild_dataclass(PostTemplateDeviceResponse)  # type: ignore
rebuild_dataclass(PostTemplateDeviceResponseError)  # type: ignore
rebuild_dataclass(GetTemplateDeviceResponse)  # type: ignore
rebuild_dataclass(GetTemplateDeviceListRequest)  # type: ignore
rebuild_dataclass(TemplateDevicePaging)  # type: ignore
rebuild_dataclass(TemplateDevicePagingValidationError)  # type: ignore
rebuild_dataclass(TemplateDeviceFilter)  # type: ignore
rebuild_dataclass(GetTemplateDeviceListResponse)  # type: ignore
rebuild_dataclass(GetTemplateDeviceListResponseError)  # type: ignore
rebuild_dataclass(GetTemplateDeviceCountRequest)  # type: ignore
rebuild_dataclass(GetTemplateDeviceCountResponse)  # type: ignore
rebuild_dataclass(GetTemplateDeviceCountResponseError)  # type: ignore
rebuild_dataclass(TemplateDevice)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorResponse)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorListRequest)  # type: ignore
rebuild_dataclass(TemplateIndicatorPaging)  # type: ignore
rebuild_dataclass(TemplateIndicatorPagingValidationError)  # type: ignore
rebuild_dataclass(TemplateIndicatorFilter)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorListResponse)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorListResponseError)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorCountRequest)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorCountResponse)  # type: ignore
rebuild_dataclass(GetTemplateIndicatorCountResponseError)  # type: ignore
rebuild_dataclass(PostTemplateIndicatorRequest)  # type: ignore
rebuild_dataclass(PostTemplateIndicatorResponse)  # type: ignore
rebuild_dataclass(PostTemplateIndicatorResponseError)  # type: ignore
rebuild_dataclass(TemplateIndicator)  # type: ignore
rebuild_dataclass(PostBuildingRequest)  # type: ignore
rebuild_dataclass(PutBuildingGroupAttachRequest)  # type: ignore
rebuild_dataclass(PostBuildingResponse)  # type: ignore
rebuild_dataclass(GetBuildingResponse)  # type: ignore
rebuild_dataclass(GetBuildingListRequest)  # type: ignore
rebuild_dataclass(GetBuildingGroupListRequest)  # type: ignore
rebuild_dataclass(BuildingGroupPaging)  # type: ignore
rebuild_dataclass(BuildingPaging)  # type: ignore
rebuild_dataclass(GetBuildingListResponse)  # type: ignore
rebuild_dataclass(GetBuildingGroupListResponse)  # type: ignore
rebuild_dataclass(PostBuildingFullDuplexResponse)  # type: ignore
rebuild_dataclass(PostBuildingFullDuplexResponseUpsertBuildingEvent)  # type: ignore
rebuild_dataclass(PostBuildingFullDuplexRequest)  # type: ignore
rebuild_dataclass(PostBuildingFullDuplexRequestBuildingAsyncStatus)  # type: ignore
rebuild_dataclass(PostBuildingFullDuplexRequestBuildingAsyncStatusError)  # type: ignore
rebuild_dataclass(BuildingFilter)  # type: ignore
rebuild_dataclass(GetBuildingCountRequest)  # type: ignore
rebuild_dataclass(GetBuildingGroupCountRequest)  # type: ignore
rebuild_dataclass(PutBuildingGroupDetachRequest)  # type: ignore
rebuild_dataclass(Building)  # type: ignore
rebuild_dataclass(PutDeviceGroupAttachRequest)  # type: ignore
rebuild_dataclass(GetDeviceGroupListRequest)  # type: ignore
rebuild_dataclass(DeviceGroupPaging)  # type: ignore
rebuild_dataclass(GetDeviceGroupListResponse)  # type: ignore
rebuild_dataclass(GetDeviceGroupCountRequest)  # type: ignore
rebuild_dataclass(PutDeviceGroupDetachRequest)  # type: ignore
rebuild_dataclass(PostDeviceIndicatorRequest)  # type: ignore
rebuild_dataclass(PostDeviceIndicatorResponse)  # type: ignore
rebuild_dataclass(PostDeviceIndicatorResponseError)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorResponse)  # type: ignore
rebuild_dataclass(GetDeviceResponse)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorListRequest)  # type: ignore
rebuild_dataclass(IndicatorPaging)  # type: ignore
rebuild_dataclass(IndicatorPagingValidationError)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorListResponse)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorListResponseError)  # type: ignore
rebuild_dataclass(IndicatorFilter)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorCountRequest)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorCountResponse)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorCountResponseError)  # type: ignore
rebuild_dataclass(PostDeviceFullDuplexRequest)  # type: ignore
rebuild_dataclass(PostDeviceFullDuplexRequestDeviceAsyncStatus)  # type: ignore
rebuild_dataclass(PostDeviceFullDuplexRequestDeviceAsyncStatusError)  # type: ignore
rebuild_dataclass(PostDeviceRequest)  # type: ignore
rebuild_dataclass(PostDeviceReplaceRequest)  # type: ignore
rebuild_dataclass(PostDeviceReplaceResponse)  # type: ignore
rebuild_dataclass(PostDeviceReplaceResponseError)  # type: ignore
rebuild_dataclass(PostDeviceFullDuplexResponse)  # type: ignore
rebuild_dataclass(PostDeviceResponse)  # type: ignore
rebuild_dataclass(PostDeviceResponseError)  # type: ignore
rebuild_dataclass(Indicator)  # type: ignore
rebuild_dataclass(Device)  # type: ignore
rebuild_dataclass(DeviceMetricPoint)  # type: ignore
rebuild_dataclass(GetDeviceListRequest)  # type: ignore
rebuild_dataclass(DevicePaging)  # type: ignore
rebuild_dataclass(DevicePagingValidationError)  # type: ignore
rebuild_dataclass(GetDeviceListResponse)  # type: ignore
rebuild_dataclass(GetDeviceListResponseError)  # type: ignore
rebuild_dataclass(DeviceFilter)  # type: ignore
rebuild_dataclass(GetDeviceCountRequest)  # type: ignore
rebuild_dataclass(GetDeviceCountResponse)  # type: ignore
rebuild_dataclass(GetDeviceCountResponseError)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorMetricPointListRequest)  # type: ignore
rebuild_dataclass(DeviceIndicatorMetricPointPaging)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorMetricPointListResponse)  # type: ignore
rebuild_dataclass(GetDeviceIndicatorMetricPointCountRequest)  # type: ignore
rebuild_dataclass(PutDeviceIndicatorMetricPointAttachRequest)  # type: ignore
rebuild_dataclass(PutDeviceIndicatorMetricPointDetachRequest)  # type: ignore
rebuild_dataclass(GetMetricPointResponse)  # type: ignore
rebuild_dataclass(GetMetricPointListRequest)  # type: ignore
rebuild_dataclass(MetricPointPaging)  # type: ignore
rebuild_dataclass(MetricPointPagingValidationError)  # type: ignore
rebuild_dataclass(MetricPointFilter)  # type: ignore
rebuild_dataclass(GetMetricPointListResponse)  # type: ignore
rebuild_dataclass(GetMetricPointListResponseError)  # type: ignore
rebuild_dataclass(GetMetricPointCountRequest)  # type: ignore
rebuild_dataclass(GetMetricPointCountResponse)  # type: ignore
rebuild_dataclass(GetMetricPointCountResponseError)  # type: ignore
rebuild_dataclass(PostMetricPointRequest)  # type: ignore
rebuild_dataclass(PostMetricPointResponse)  # type: ignore
rebuild_dataclass(PostMetricPointResponseError)  # type: ignore
rebuild_dataclass(PostDictionaryDeviceModelRequest)  # type: ignore
rebuild_dataclass(PostDictionaryDeviceModelResponse)  # type: ignore
rebuild_dataclass(GetDictionaryDeviceModelResponse)  # type: ignore
rebuild_dataclass(GetDictionaryDeviceModelListRequest)  # type: ignore
rebuild_dataclass(DictionaryDeviceModelPaging)  # type: ignore
rebuild_dataclass(GetDictionaryDeviceModelListResponse)  # type: ignore
rebuild_dataclass(GetDictionaryMrfListResponse)  # type: ignore
rebuild_dataclass(DictionaryMrf)  # type: ignore
rebuild_dataclass(GetDictionaryRfListResponse)  # type: ignore
rebuild_dataclass(DictionaryPermission)  # type: ignore
rebuild_dataclass(DictionaryRf)  # type: ignore
rebuild_dataclass(GetDictionaryDeviceModelCountRequest)  # type: ignore
rebuild_dataclass(DictionaryDeviceModel)  # type: ignore
rebuild_dataclass(CollectorParams)  # type: ignore
rebuild_dataclass(EicAllFiasStartTask)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexResponse)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexResponseRemoveResourceEvent)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexResponseUpsertResourceEvent)  # type: ignore
rebuild_dataclass(ResourceId)  # type: ignore
rebuild_dataclass(Resource)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexRequest)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexRequestResourceAsyncStatus)  # type: ignore
rebuild_dataclass(PostResourceFullDuplexRequestResourceAsyncStatusError)  # type: ignore
