diff --git a/aioesphomeapi/__init__.py b/aioesphomeapi/__init__.py index 421945b..573689e 100644 --- a/aioesphomeapi/__init__.py +++ b/aioesphomeapi/__init__.py @@ -1 +1,5 @@ from .client import * +from .connection import * +from .core import * +from .model import * +from .util import * diff --git a/aioesphomeapi/api.proto b/aioesphomeapi/api.proto index 7f18e11..4d6f2ac 100644 --- a/aioesphomeapi/api.proto +++ b/aioesphomeapi/api.proto @@ -1,5 +1,8 @@ syntax = "proto3"; + +// ==================== BASE PACKETS ==================== + // The Home Assistant protocol is structured as a simple // TCP socket with short binary messages encoded in the protocol buffers format // First, a message in this protocol has a specific format: @@ -18,6 +21,7 @@ syntax = "proto3"; // Message sent at the beginning of each connection // Can only be sent by the client and only at the beginning of the connection +// ID: 1 message HelloRequest { // Description of client (like User Agent) // For example "Home Assistant" @@ -28,6 +32,7 @@ message HelloRequest { // Confirmation of successful connection request. // Can only be sent by the server and only at the beginning of the connection +// ID: 2 message HelloResponse { // The version of the API to use. The _client_ (for example Home Assistant) needs to check // for compatibility and if necessary adopt to an older API. @@ -44,6 +49,7 @@ message HelloResponse { // Message sent at the beginning of each connection to authenticate the client // Can only be sent by the client and only at the beginning of the connection +// ID: 3 message ConnectRequest { // The password to log in with string password = 1; @@ -51,33 +57,40 @@ message ConnectRequest { // Confirmation of successful connection. After this the connection is available for all traffic. // Can only be sent by the server and only at the beginning of the connection +// ID: 4 message ConnectResponse { bool invalid_password = 1; } // Request to close the connection. // Can be sent by both the client and server +// ID: 5 message DisconnectRequest { // Do not close the connection before the acknowledgement arrives } +// ID: 6 message DisconnectResponse { // Empty - Both parties are required to close the connection after this // message has been received. } +// ID: 7 message PingRequest { // Empty } +// ID: 8 message PingResponse { // Empty } +// ID: 9 message DeviceInfoRequest { // Empty } +// ID: 10 message DeviceInfoResponse { bool uses_password = 1; @@ -101,10 +114,21 @@ message DeviceInfoResponse { bool has_deep_sleep = 7; } +// ID: 11 message ListEntitiesRequest { // Empty } +// ID: 19 +message ListEntitiesDoneResponse { + // Empty +} +// ID: 20 +message SubscribeStatesRequest { + // Empty +} +// ==================== BINARY SENSOR ==================== +// ID: 12 message ListEntitiesBinarySensorResponse { string object_id = 1; fixed32 key = 2; @@ -114,14 +138,69 @@ message ListEntitiesBinarySensorResponse { string device_class = 5; bool is_status_binary_sensor = 6; } +// ID: 21 +message BinarySensorStateResponse { + fixed32 key = 1; + bool state = 2; +} + +// ==================== COVER ==================== +// ID: 13 message ListEntitiesCoverResponse { string object_id = 1; fixed32 key = 2; string name = 3; string unique_id = 4; - bool is_optimistic = 5; + bool assumed_state = 5; + bool supports_position = 6; + bool supports_tilt = 7; + string device_class = 8; } +// ID: 22 +message CoverStateResponse { + fixed32 key = 1; + + // legacy: state has been removed in 1.13 + // clients/servers must still send/accept it until the next protocol change + enum LegacyCoverState { + OPEN = 0; + CLOSED = 1; + } + LegacyCoverState legacy_state = 2; + + float position = 3; + float tilt = 4; + enum CoverOperation { + IDLE = 0; + IS_OPENING = 1; + IS_CLOSING = 2; + } + CoverOperation current_operation = 5; +} +// ID: 30 +message CoverCommandRequest { + fixed32 key = 1; + + // legacy: command has been removed in 1.13 + // clients/servers must still send/accept it until the next protocol change + enum LegacyCoverCommand { + OPEN = 0; + CLOSE = 1; + STOP = 2; + } + bool has_legacy_command = 2; + LegacyCoverCommand legacy_command = 3; + + bool has_position = 4; + float position = 5; + bool has_tilt = 6; + float tilt = 7; + bool stop = 8; +} + +// ==================== FAN ==================== +// ID: 14 message ListEntitiesFanResponse { string object_id = 1; fixed32 key = 2; @@ -131,6 +210,31 @@ message ListEntitiesFanResponse { bool supports_oscillation = 5; bool supports_speed = 6; } +enum FanSpeed { + LOW = 0; + MEDIUM = 1; + HIGH = 2; +} +// ID: 23 +message FanStateResponse { + fixed32 key = 1; + bool state = 2; + bool oscillating = 3; + FanSpeed speed = 4; +} +// ID: 31 +message FanCommandRequest { + fixed32 key = 1; + bool has_state = 2; + bool state = 3; + bool has_speed = 4; + FanSpeed speed = 5; + bool has_oscillating = 6; + bool oscillating = 7; +} + +// ==================== LIGHT ==================== +// ID: 15 message ListEntitiesLightResponse { string object_id = 1; fixed32 key = 2; @@ -145,69 +249,7 @@ message ListEntitiesLightResponse { float max_mireds = 10; repeated string effects = 11; } -message ListEntitiesSensorResponse { - string object_id = 1; - fixed32 key = 2; - string name = 3; - string unique_id = 4; - - string icon = 5; - string unit_of_measurement = 6; - int32 accuracy_decimals = 7; -} -message ListEntitiesSwitchResponse { - string object_id = 1; - fixed32 key = 2; - string name = 3; - string unique_id = 4; - - string icon = 5; - bool optimistic = 6; -} -message ListEntitiesTextSensorResponse { - string object_id = 1; - fixed32 key = 2; - string name = 3; - string unique_id = 4; - - string icon = 5; -} -message ListEntitiesCameraResponse { - string object_id = 1; - fixed32 key = 2; - string name = 3; - string unique_id = 4; -} -message ListEntitiesDoneResponse { - // Empty -} - -message SubscribeStatesRequest { - // Empty -} -message BinarySensorStateResponse { - fixed32 key = 1; - bool state = 2; -} -message CoverStateResponse { - fixed32 key = 1; - enum CoverState { - OPEN = 0; - CLOSED = 1; - } - CoverState state = 2; -} -enum FanSpeed { - LOW = 0; - MEDIUM = 1; - HIGH = 2; -} -message FanStateResponse { - fixed32 key = 1; - bool state = 2; - bool oscillating = 3; - FanSpeed speed = 4; -} +// ID: 24 message LightStateResponse { fixed32 key = 1; bool state = 2; @@ -219,43 +261,7 @@ message LightStateResponse { float color_temperature = 8; string effect = 9; } -message SensorStateResponse { - fixed32 key = 1; - float state = 2; -} -message SwitchStateResponse { - fixed32 key = 1; - bool state = 2; -} -message TextSensorStateResponse { - fixed32 key = 1; - string state = 2; -} -message CameraImageResponse { - fixed32 key = 1; - bytes data = 2; - bool done = 3; -} - -message CoverCommandRequest { - fixed32 key = 1; - enum CoverCommand { - OPEN = 0; - CLOSE = 1; - STOP = 2; - } - bool has_state = 2; - CoverCommand command = 3; -} -message FanCommandRequest { - fixed32 key = 1; - bool has_state = 2; - bool state = 3; - bool has_speed = 4; - FanSpeed speed = 5; - bool has_oscillating = 6; - bool oscillating = 7; -} +// ID: 32 message LightCommandRequest { fixed32 key = 1; bool has_state = 2; @@ -277,11 +283,64 @@ message LightCommandRequest { bool has_effect = 18; string effect = 19; } + +// ==================== SENSOR ==================== +// ID: 16 +message ListEntitiesSensorResponse { + string object_id = 1; + fixed32 key = 2; + string name = 3; + string unique_id = 4; + + string icon = 5; + string unit_of_measurement = 6; + int32 accuracy_decimals = 7; +} +// ID: 25 +message SensorStateResponse { + fixed32 key = 1; + float state = 2; +} + +// ==================== SWITCH ==================== +// ID: 17 +message ListEntitiesSwitchResponse { + string object_id = 1; + fixed32 key = 2; + string name = 3; + string unique_id = 4; + + string icon = 5; + bool assumed_state = 6; +} +// ID: 26 +message SwitchStateResponse { + fixed32 key = 1; + bool state = 2; +} +// ID: 33 message SwitchCommandRequest { fixed32 key = 1; bool state = 2; } +// ==================== TEXT SENSOR ==================== +// ID: 18 +message ListEntitiesTextSensorResponse { + string object_id = 1; + fixed32 key = 2; + string name = 3; + string unique_id = 4; + + string icon = 5; +} +// ID: 27 +message TextSensorStateResponse { + fixed32 key = 1; + string state = 2; +} + +// ==================== SUBSCRIBE LOGS ==================== enum LogLevel { NONE = 0; ERROR = 1; @@ -291,12 +350,12 @@ enum LogLevel { VERBOSE = 5; VERY_VERBOSE = 6; } - +// ID: 28 message SubscribeLogsRequest { LogLevel level = 1; bool dump_config = 2; } - +// ID: 29 message SubscribeLogsResponse { LogLevel level = 1; string tag = 2; @@ -304,10 +363,13 @@ message SubscribeLogsResponse { bool send_failed = 4; } +// ==================== HOMEASSISTANT.SERVICE ==================== +// ID: 34 message SubscribeServiceCallsRequest { } +// ID: 35 message ServiceCallResponse { string service = 1; map data = 2; @@ -315,32 +377,38 @@ message ServiceCallResponse { map variables = 4; } +// ==================== IMPORT HOME ASSISTANT STATES ==================== // 1. Client sends SubscribeHomeAssistantStatesRequest // 2. Server responds with zero or more SubscribeHomeAssistantStateResponse (async) // 3. Client sends HomeAssistantStateResponse for state changes. +// ID: 38 message SubscribeHomeAssistantStatesRequest { } +// ID: 39 message SubscribeHomeAssistantStateResponse { string entity_id = 1; } +// ID: 40 message HomeAssistantStateResponse { string entity_id = 1; string state = 2; } +// ==================== IMPORT TIME ==================== +// ID: 36 message GetTimeRequest { } +// ID: 37 message GetTimeResponse { fixed32 epoch_seconds = 1; } - - +// ==================== USER-DEFINES SERVICES ==================== message ListEntitiesServicesArgument { string name = 1; enum Type { @@ -351,36 +419,53 @@ message ListEntitiesServicesArgument { } Type type = 2; } +// ID: 41 message ListEntitiesServicesResponse { string name = 1; fixed32 key = 2; repeated ListEntitiesServicesArgument args = 3; } - message ExecuteServiceArgument { bool bool_ = 1; int32 int_ = 2; float float_ = 3; string string_ = 4; } - +// ID: 42 message ExecuteServiceRequest { fixed32 key = 1; repeated ExecuteServiceArgument args = 2; } +// ==================== CAMERA ==================== +// ID: 43 +message ListEntitiesCameraResponse { + string object_id = 1; + fixed32 key = 2; + string name = 3; + string unique_id = 4; +} + +// ID: 44 +message CameraImageResponse { + fixed32 key = 1; + bytes data = 2; + bool done = 3; +} +// ID: 45 message CameraImageRequest { bool single = 1; bool stream = 2; } +// ==================== CLIMATE ==================== enum ClimateMode { OFF = 0; AUTO = 1; COOL = 2; HEAT = 3; } - +// ID: 46 message ListEntitiesClimateResponse { string object_id = 1; fixed32 key = 2; @@ -395,7 +480,7 @@ message ListEntitiesClimateResponse { float visual_temperature_step = 10; bool supports_away = 11; } - +// ID: 47 message ClimateStateResponse { fixed32 key = 1; ClimateMode mode = 2; @@ -405,7 +490,7 @@ message ClimateStateResponse { float target_temperature_high = 6; bool away = 7; } - +// ID: 48 message ClimateCommandRequest { fixed32 key = 1; bool has_mode = 2; diff --git a/aioesphomeapi/api_pb2.py b/aioesphomeapi/api_pb2.py index 63f6eb6..8a4a64c 100644 --- a/aioesphomeapi/api_pb2.py +++ b/aioesphomeapi/api_pb2.py @@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='', syntax='proto3', serialized_options=None, - serialized_pb=_b('\n\tapi.proto\"#\n\x0cHelloRequest\x12\x13\n\x0b\x63lient_info\x18\x01 \x01(\t\"Z\n\rHelloResponse\x12\x19\n\x11\x61pi_version_major\x18\x01 \x01(\r\x12\x19\n\x11\x61pi_version_minor\x18\x02 \x01(\r\x12\x13\n\x0bserver_info\x18\x03 \x01(\t\"\"\n\x0e\x43onnectRequest\x12\x10\n\x08password\x18\x01 \x01(\t\"+\n\x0f\x43onnectResponse\x12\x18\n\x10invalid_password\x18\x01 \x01(\x08\"\x13\n\x11\x44isconnectRequest\"\x14\n\x12\x44isconnectResponse\"\r\n\x0bPingRequest\"\x0e\n\x0cPingResponse\"\x13\n\x11\x44\x65viceInfoRequest\"\xad\x01\n\x12\x44\x65viceInfoResponse\x12\x15\n\ruses_password\x18\x01 \x01(\x08\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0bmac_address\x18\x03 \x01(\t\x12\x1c\n\x14\x65sphome_core_version\x18\x04 \x01(\t\x12\x18\n\x10\x63ompilation_time\x18\x05 \x01(\t\x12\r\n\x05model\x18\x06 \x01(\t\x12\x16\n\x0ehas_deep_sleep\x18\x07 \x01(\x08\"\x15\n\x13ListEntitiesRequest\"\x9a\x01\n ListEntitiesBinarySensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x14\n\x0c\x64\x65vice_class\x18\x05 \x01(\t\x12\x1f\n\x17is_status_binary_sensor\x18\x06 \x01(\x08\"s\n\x19ListEntitiesCoverResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x15\n\ris_optimistic\x18\x05 \x01(\x08\"\x90\x01\n\x17ListEntitiesFanResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x1c\n\x14supports_oscillation\x18\x05 \x01(\x08\x12\x16\n\x0esupports_speed\x18\x06 \x01(\x08\"\x8a\x02\n\x19ListEntitiesLightResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x1b\n\x13supports_brightness\x18\x05 \x01(\x08\x12\x14\n\x0csupports_rgb\x18\x06 \x01(\x08\x12\x1c\n\x14supports_white_value\x18\x07 \x01(\x08\x12\"\n\x1asupports_color_temperature\x18\x08 \x01(\x08\x12\x12\n\nmin_mireds\x18\t \x01(\x02\x12\x12\n\nmax_mireds\x18\n \x01(\x02\x12\x0f\n\x07\x65\x66\x66\x65\x63ts\x18\x0b \x03(\t\"\xa3\x01\n\x1aListEntitiesSensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\x12\x1b\n\x13unit_of_measurement\x18\x06 \x01(\t\x12\x19\n\x11\x61\x63\x63uracy_decimals\x18\x07 \x01(\x05\"\x7f\n\x1aListEntitiesSwitchResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\x12\x12\n\noptimistic\x18\x06 \x01(\x08\"o\n\x1eListEntitiesTextSensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\"]\n\x1aListEntitiesCameraResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\"\x1a\n\x18ListEntitiesDoneResponse\"\x18\n\x16SubscribeStatesRequest\"7\n\x19\x42inarySensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"t\n\x12\x43overStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12-\n\x05state\x18\x02 \x01(\x0e\x32\x1e.CoverStateResponse.CoverState\"\"\n\nCoverState\x12\x08\n\x04OPEN\x10\x00\x12\n\n\x06\x43LOSED\x10\x01\"]\n\x10\x46\x61nStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\x12\x13\n\x0boscillating\x18\x03 \x01(\x08\x12\x18\n\x05speed\x18\x04 \x01(\x0e\x32\t.FanSpeed\"\xa8\x01\n\x12LightStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\x12\x12\n\nbrightness\x18\x03 \x01(\x02\x12\x0b\n\x03red\x18\x04 \x01(\x02\x12\r\n\x05green\x18\x05 \x01(\x02\x12\x0c\n\x04\x62lue\x18\x06 \x01(\x02\x12\r\n\x05white\x18\x07 \x01(\x02\x12\x19\n\x11\x63olor_temperature\x18\x08 \x01(\x02\x12\x0e\n\x06\x65\x66\x66\x65\x63t\x18\t \x01(\t\"1\n\x13SensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x02\"1\n\x13SwitchStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"5\n\x17TextSensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\t\">\n\x13\x43\x61meraImageResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\"\x98\x01\n\x13\x43overCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x11\n\thas_state\x18\x02 \x01(\x08\x12\x32\n\x07\x63ommand\x18\x03 \x01(\x0e\x32!.CoverCommandRequest.CoverCommand\"-\n\x0c\x43overCommand\x12\x08\n\x04OPEN\x10\x00\x12\t\n\x05\x43LOSE\x10\x01\x12\x08\n\x04STOP\x10\x02\"\x9d\x01\n\x11\x46\x61nCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x11\n\thas_state\x18\x02 \x01(\x08\x12\r\n\x05state\x18\x03 \x01(\x08\x12\x11\n\thas_speed\x18\x04 \x01(\x08\x12\x18\n\x05speed\x18\x05 \x01(\x0e\x32\t.FanSpeed\x12\x17\n\x0fhas_oscillating\x18\x06 \x01(\x08\x12\x13\n\x0boscillating\x18\x07 \x01(\x08\"\x95\x03\n\x13LightCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x11\n\thas_state\x18\x02 \x01(\x08\x12\r\n\x05state\x18\x03 \x01(\x08\x12\x16\n\x0ehas_brightness\x18\x04 \x01(\x08\x12\x12\n\nbrightness\x18\x05 \x01(\x02\x12\x0f\n\x07has_rgb\x18\x06 \x01(\x08\x12\x0b\n\x03red\x18\x07 \x01(\x02\x12\r\n\x05green\x18\x08 \x01(\x02\x12\x0c\n\x04\x62lue\x18\t \x01(\x02\x12\x11\n\thas_white\x18\n \x01(\x08\x12\r\n\x05white\x18\x0b \x01(\x02\x12\x1d\n\x15has_color_temperature\x18\x0c \x01(\x08\x12\x19\n\x11\x63olor_temperature\x18\r \x01(\x02\x12\x1d\n\x15has_transition_length\x18\x0e \x01(\x08\x12\x19\n\x11transition_length\x18\x0f \x01(\r\x12\x18\n\x10has_flash_length\x18\x10 \x01(\x08\x12\x14\n\x0c\x66lash_length\x18\x11 \x01(\r\x12\x12\n\nhas_effect\x18\x12 \x01(\x08\x12\x0e\n\x06\x65\x66\x66\x65\x63t\x18\x13 \x01(\t\"2\n\x14SwitchCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"E\n\x14SubscribeLogsRequest\x12\x18\n\x05level\x18\x01 \x01(\x0e\x32\t.LogLevel\x12\x13\n\x0b\x64ump_config\x18\x02 \x01(\x08\"d\n\x15SubscribeLogsResponse\x12\x18\n\x05level\x18\x01 \x01(\x0e\x32\t.LogLevel\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12\x0f\n\x07message\x18\x03 \x01(\t\x12\x13\n\x0bsend_failed\x18\x04 \x01(\x08\"\x1e\n\x1cSubscribeServiceCallsRequest\"\xdf\x02\n\x13ServiceCallResponse\x12\x0f\n\x07service\x18\x01 \x01(\t\x12,\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x1e.ServiceCallResponse.DataEntry\x12=\n\rdata_template\x18\x03 \x03(\x0b\x32&.ServiceCallResponse.DataTemplateEntry\x12\x36\n\tvariables\x18\x04 \x03(\x0b\x32#.ServiceCallResponse.VariablesEntry\x1a+\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x33\n\x11\x44\x61taTemplateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x30\n\x0eVariablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"%\n#SubscribeHomeAssistantStatesRequest\"8\n#SubscribeHomeAssistantStateResponse\x12\x11\n\tentity_id\x18\x01 \x01(\t\">\n\x1aHomeAssistantStateResponse\x12\x11\n\tentity_id\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\t\"\x10\n\x0eGetTimeRequest\"(\n\x0fGetTimeResponse\x12\x15\n\repoch_seconds\x18\x01 \x01(\x07\"\x90\x01\n\x1cListEntitiesServicesArgument\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x30\n\x04type\x18\x02 \x01(\x0e\x32\".ListEntitiesServicesArgument.Type\"0\n\x04Type\x12\x08\n\x04\x42OOL\x10\x00\x12\x07\n\x03INT\x10\x01\x12\t\n\x05\x46LOAT\x10\x02\x12\n\n\x06STRING\x10\x03\"f\n\x1cListEntitiesServicesResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12+\n\x04\x61rgs\x18\x03 \x03(\x0b\x32\x1d.ListEntitiesServicesArgument\"V\n\x16\x45xecuteServiceArgument\x12\r\n\x05\x62ool_\x18\x01 \x01(\x08\x12\x0c\n\x04int_\x18\x02 \x01(\x05\x12\x0e\n\x06\x66loat_\x18\x03 \x01(\x02\x12\x0f\n\x07string_\x18\x04 \x01(\t\"K\n\x15\x45xecuteServiceRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.ExecuteServiceArgument\"4\n\x12\x43\x61meraImageRequest\x12\x0e\n\x06single\x18\x01 \x01(\x08\x12\x0e\n\x06stream\x18\x02 \x01(\x08\"\xd2\x02\n\x1bListEntitiesClimateResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12$\n\x1csupports_current_temperature\x18\x05 \x01(\x08\x12-\n%supports_two_point_target_temperature\x18\x06 \x01(\x08\x12%\n\x0fsupported_modes\x18\x07 \x03(\x0e\x32\x0c.ClimateMode\x12\x1e\n\x16visual_min_temperature\x18\x08 \x01(\x02\x12\x1e\n\x16visual_max_temperature\x18\t \x01(\x02\x12\x1f\n\x17visual_temperature_step\x18\n \x01(\x02\x12\x15\n\rsupports_away\x18\x0b \x01(\x08\"\xc7\x01\n\x14\x43limateStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x1a\n\x04mode\x18\x02 \x01(\x0e\x32\x0c.ClimateMode\x12\x1b\n\x13\x63urrent_temperature\x18\x03 \x01(\x02\x12\x1a\n\x12target_temperature\x18\x04 \x01(\x02\x12\x1e\n\x16target_temperature_low\x18\x05 \x01(\x02\x12\x1f\n\x17target_temperature_high\x18\x06 \x01(\x02\x12\x0c\n\x04\x61way\x18\x07 \x01(\x08\"\xb8\x02\n\x15\x43limateCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x10\n\x08has_mode\x18\x02 \x01(\x08\x12\x1a\n\x04mode\x18\x03 \x01(\x0e\x32\x0c.ClimateMode\x12\x1e\n\x16has_target_temperature\x18\x04 \x01(\x08\x12\x1a\n\x12target_temperature\x18\x05 \x01(\x02\x12\"\n\x1ahas_target_temperature_low\x18\x06 \x01(\x08\x12\x1e\n\x16target_temperature_low\x18\x07 \x01(\x02\x12#\n\x1bhas_target_temperature_high\x18\x08 \x01(\x08\x12\x1f\n\x17target_temperature_high\x18\t \x01(\x02\x12\x10\n\x08has_away\x18\n \x01(\x08\x12\x0c\n\x04\x61way\x18\x0b \x01(\x08*)\n\x08\x46\x61nSpeed\x12\x07\n\x03LOW\x10\x00\x12\n\n\x06MEDIUM\x10\x01\x12\x08\n\x04HIGH\x10\x02*]\n\x08LogLevel\x12\x08\n\x04NONE\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x08\n\x04WARN\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\x0b\n\x07VERBOSE\x10\x05\x12\x10\n\x0cVERY_VERBOSE\x10\x06*4\n\x0b\x43limateMode\x12\x07\n\x03OFF\x10\x00\x12\x08\n\x04\x41UTO\x10\x01\x12\x08\n\x04\x43OOL\x10\x02\x12\x08\n\x04HEAT\x10\x03\x62\x06proto3') + serialized_pb=_b('\n\tapi.proto\"#\n\x0cHelloRequest\x12\x13\n\x0b\x63lient_info\x18\x01 \x01(\t\"Z\n\rHelloResponse\x12\x19\n\x11\x61pi_version_major\x18\x01 \x01(\r\x12\x19\n\x11\x61pi_version_minor\x18\x02 \x01(\r\x12\x13\n\x0bserver_info\x18\x03 \x01(\t\"\"\n\x0e\x43onnectRequest\x12\x10\n\x08password\x18\x01 \x01(\t\"+\n\x0f\x43onnectResponse\x12\x18\n\x10invalid_password\x18\x01 \x01(\x08\"\x13\n\x11\x44isconnectRequest\"\x14\n\x12\x44isconnectResponse\"\r\n\x0bPingRequest\"\x0e\n\x0cPingResponse\"\x13\n\x11\x44\x65viceInfoRequest\"\xad\x01\n\x12\x44\x65viceInfoResponse\x12\x15\n\ruses_password\x18\x01 \x01(\x08\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0bmac_address\x18\x03 \x01(\t\x12\x1c\n\x14\x65sphome_core_version\x18\x04 \x01(\t\x12\x18\n\x10\x63ompilation_time\x18\x05 \x01(\t\x12\r\n\x05model\x18\x06 \x01(\t\x12\x16\n\x0ehas_deep_sleep\x18\x07 \x01(\x08\"\x15\n\x13ListEntitiesRequest\"\x1a\n\x18ListEntitiesDoneResponse\"\x18\n\x16SubscribeStatesRequest\"\x9a\x01\n ListEntitiesBinarySensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x14\n\x0c\x64\x65vice_class\x18\x05 \x01(\t\x12\x1f\n\x17is_status_binary_sensor\x18\x06 \x01(\x08\"7\n\x19\x42inarySensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"\xbb\x01\n\x19ListEntitiesCoverResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x15\n\rassumed_state\x18\x05 \x01(\x08\x12\x19\n\x11supports_position\x18\x06 \x01(\x08\x12\x15\n\rsupports_tilt\x18\x07 \x01(\x08\x12\x14\n\x0c\x64\x65vice_class\x18\x08 \x01(\t\"\xb0\x02\n\x12\x43overStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12:\n\x0clegacy_state\x18\x02 \x01(\x0e\x32$.CoverStateResponse.LegacyCoverState\x12\x10\n\x08position\x18\x03 \x01(\x02\x12\x0c\n\x04tilt\x18\x04 \x01(\x02\x12\x44\n\x11\x63urrent_operation\x18\x05 \x01(\x0e\x32).CoverStateResponse.CoverCurrentOperation\"(\n\x10LegacyCoverState\x12\x08\n\x04OPEN\x10\x00\x12\n\n\x06\x43LOSED\x10\x01\"A\n\x15\x43overCurrentOperation\x12\x08\n\x04IDLE\x10\x00\x12\x0e\n\nIS_OPENING\x10\x01\x12\x0e\n\nIS_CLOSING\x10\x02\"\x8a\x02\n\x13\x43overCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x1a\n\x12has_legacy_command\x18\x02 \x01(\x08\x12?\n\x0elegacy_command\x18\x03 \x01(\x0e\x32\'.CoverCommandRequest.LegacyCoverCommand\x12\x14\n\x0chas_position\x18\x04 \x01(\x08\x12\x10\n\x08position\x18\x05 \x01(\x02\x12\x10\n\x08has_tilt\x18\x06 \x01(\x08\x12\x0c\n\x04tilt\x18\x07 \x01(\x02\x12\x0c\n\x04stop\x18\x08 \x01(\x08\"3\n\x12LegacyCoverCommand\x12\x08\n\x04OPEN\x10\x00\x12\t\n\x05\x43LOSE\x10\x01\x12\x08\n\x04STOP\x10\x02\"\x90\x01\n\x17ListEntitiesFanResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x1c\n\x14supports_oscillation\x18\x05 \x01(\x08\x12\x16\n\x0esupports_speed\x18\x06 \x01(\x08\"]\n\x10\x46\x61nStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\x12\x13\n\x0boscillating\x18\x03 \x01(\x08\x12\x18\n\x05speed\x18\x04 \x01(\x0e\x32\t.FanSpeed\"\x9d\x01\n\x11\x46\x61nCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x11\n\thas_state\x18\x02 \x01(\x08\x12\r\n\x05state\x18\x03 \x01(\x08\x12\x11\n\thas_speed\x18\x04 \x01(\x08\x12\x18\n\x05speed\x18\x05 \x01(\x0e\x32\t.FanSpeed\x12\x17\n\x0fhas_oscillating\x18\x06 \x01(\x08\x12\x13\n\x0boscillating\x18\x07 \x01(\x08\"\x8a\x02\n\x19ListEntitiesLightResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x1b\n\x13supports_brightness\x18\x05 \x01(\x08\x12\x14\n\x0csupports_rgb\x18\x06 \x01(\x08\x12\x1c\n\x14supports_white_value\x18\x07 \x01(\x08\x12\"\n\x1asupports_color_temperature\x18\x08 \x01(\x08\x12\x12\n\nmin_mireds\x18\t \x01(\x02\x12\x12\n\nmax_mireds\x18\n \x01(\x02\x12\x0f\n\x07\x65\x66\x66\x65\x63ts\x18\x0b \x03(\t\"\xa8\x01\n\x12LightStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\x12\x12\n\nbrightness\x18\x03 \x01(\x02\x12\x0b\n\x03red\x18\x04 \x01(\x02\x12\r\n\x05green\x18\x05 \x01(\x02\x12\x0c\n\x04\x62lue\x18\x06 \x01(\x02\x12\r\n\x05white\x18\x07 \x01(\x02\x12\x19\n\x11\x63olor_temperature\x18\x08 \x01(\x02\x12\x0e\n\x06\x65\x66\x66\x65\x63t\x18\t \x01(\t\"\x95\x03\n\x13LightCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x11\n\thas_state\x18\x02 \x01(\x08\x12\r\n\x05state\x18\x03 \x01(\x08\x12\x16\n\x0ehas_brightness\x18\x04 \x01(\x08\x12\x12\n\nbrightness\x18\x05 \x01(\x02\x12\x0f\n\x07has_rgb\x18\x06 \x01(\x08\x12\x0b\n\x03red\x18\x07 \x01(\x02\x12\r\n\x05green\x18\x08 \x01(\x02\x12\x0c\n\x04\x62lue\x18\t \x01(\x02\x12\x11\n\thas_white\x18\n \x01(\x08\x12\r\n\x05white\x18\x0b \x01(\x02\x12\x1d\n\x15has_color_temperature\x18\x0c \x01(\x08\x12\x19\n\x11\x63olor_temperature\x18\r \x01(\x02\x12\x1d\n\x15has_transition_length\x18\x0e \x01(\x08\x12\x19\n\x11transition_length\x18\x0f \x01(\r\x12\x18\n\x10has_flash_length\x18\x10 \x01(\x08\x12\x14\n\x0c\x66lash_length\x18\x11 \x01(\r\x12\x12\n\nhas_effect\x18\x12 \x01(\x08\x12\x0e\n\x06\x65\x66\x66\x65\x63t\x18\x13 \x01(\t\"\xa3\x01\n\x1aListEntitiesSensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\x12\x1b\n\x13unit_of_measurement\x18\x06 \x01(\t\x12\x19\n\x11\x61\x63\x63uracy_decimals\x18\x07 \x01(\x05\"1\n\x13SensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x02\"\x82\x01\n\x1aListEntitiesSwitchResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\x12\x15\n\rassumed_state\x18\x06 \x01(\x08\"1\n\x13SwitchStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"2\n\x14SwitchCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\x08\"o\n\x1eListEntitiesTextSensorResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12\x0c\n\x04icon\x18\x05 \x01(\t\"5\n\x17TextSensorStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05state\x18\x02 \x01(\t\"E\n\x14SubscribeLogsRequest\x12\x18\n\x05level\x18\x01 \x01(\x0e\x32\t.LogLevel\x12\x13\n\x0b\x64ump_config\x18\x02 \x01(\x08\"d\n\x15SubscribeLogsResponse\x12\x18\n\x05level\x18\x01 \x01(\x0e\x32\t.LogLevel\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12\x0f\n\x07message\x18\x03 \x01(\t\x12\x13\n\x0bsend_failed\x18\x04 \x01(\x08\"\x1e\n\x1cSubscribeServiceCallsRequest\"\xdf\x02\n\x13ServiceCallResponse\x12\x0f\n\x07service\x18\x01 \x01(\t\x12,\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x1e.ServiceCallResponse.DataEntry\x12=\n\rdata_template\x18\x03 \x03(\x0b\x32&.ServiceCallResponse.DataTemplateEntry\x12\x36\n\tvariables\x18\x04 \x03(\x0b\x32#.ServiceCallResponse.VariablesEntry\x1a+\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x33\n\x11\x44\x61taTemplateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x30\n\x0eVariablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"%\n#SubscribeHomeAssistantStatesRequest\"8\n#SubscribeHomeAssistantStateResponse\x12\x11\n\tentity_id\x18\x01 \x01(\t\">\n\x1aHomeAssistantStateResponse\x12\x11\n\tentity_id\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\t\"\x10\n\x0eGetTimeRequest\"(\n\x0fGetTimeResponse\x12\x15\n\repoch_seconds\x18\x01 \x01(\x07\"\x90\x01\n\x1cListEntitiesServicesArgument\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x30\n\x04type\x18\x02 \x01(\x0e\x32\".ListEntitiesServicesArgument.Type\"0\n\x04Type\x12\x08\n\x04\x42OOL\x10\x00\x12\x07\n\x03INT\x10\x01\x12\t\n\x05\x46LOAT\x10\x02\x12\n\n\x06STRING\x10\x03\"f\n\x1cListEntitiesServicesResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12+\n\x04\x61rgs\x18\x03 \x03(\x0b\x32\x1d.ListEntitiesServicesArgument\"V\n\x16\x45xecuteServiceArgument\x12\r\n\x05\x62ool_\x18\x01 \x01(\x08\x12\x0c\n\x04int_\x18\x02 \x01(\x05\x12\x0e\n\x06\x66loat_\x18\x03 \x01(\x02\x12\x0f\n\x07string_\x18\x04 \x01(\t\"K\n\x15\x45xecuteServiceRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12%\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x17.ExecuteServiceArgument\"]\n\x1aListEntitiesCameraResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\">\n\x13\x43\x61meraImageResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\"4\n\x12\x43\x61meraImageRequest\x12\x0e\n\x06single\x18\x01 \x01(\x08\x12\x0e\n\x06stream\x18\x02 \x01(\x08\"\xd2\x02\n\x1bListEntitiesClimateResponse\x12\x11\n\tobject_id\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x07\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tunique_id\x18\x04 \x01(\t\x12$\n\x1csupports_current_temperature\x18\x05 \x01(\x08\x12-\n%supports_two_point_target_temperature\x18\x06 \x01(\x08\x12%\n\x0fsupported_modes\x18\x07 \x03(\x0e\x32\x0c.ClimateMode\x12\x1e\n\x16visual_min_temperature\x18\x08 \x01(\x02\x12\x1e\n\x16visual_max_temperature\x18\t \x01(\x02\x12\x1f\n\x17visual_temperature_step\x18\n \x01(\x02\x12\x15\n\rsupports_away\x18\x0b \x01(\x08\"\xc7\x01\n\x14\x43limateStateResponse\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x1a\n\x04mode\x18\x02 \x01(\x0e\x32\x0c.ClimateMode\x12\x1b\n\x13\x63urrent_temperature\x18\x03 \x01(\x02\x12\x1a\n\x12target_temperature\x18\x04 \x01(\x02\x12\x1e\n\x16target_temperature_low\x18\x05 \x01(\x02\x12\x1f\n\x17target_temperature_high\x18\x06 \x01(\x02\x12\x0c\n\x04\x61way\x18\x07 \x01(\x08\"\xb8\x02\n\x15\x43limateCommandRequest\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\x10\n\x08has_mode\x18\x02 \x01(\x08\x12\x1a\n\x04mode\x18\x03 \x01(\x0e\x32\x0c.ClimateMode\x12\x1e\n\x16has_target_temperature\x18\x04 \x01(\x08\x12\x1a\n\x12target_temperature\x18\x05 \x01(\x02\x12\"\n\x1ahas_target_temperature_low\x18\x06 \x01(\x08\x12\x1e\n\x16target_temperature_low\x18\x07 \x01(\x02\x12#\n\x1bhas_target_temperature_high\x18\x08 \x01(\x08\x12\x1f\n\x17target_temperature_high\x18\t \x01(\x02\x12\x10\n\x08has_away\x18\n \x01(\x08\x12\x0c\n\x04\x61way\x18\x0b \x01(\x08*)\n\x08\x46\x61nSpeed\x12\x07\n\x03LOW\x10\x00\x12\n\n\x06MEDIUM\x10\x01\x12\x08\n\x04HIGH\x10\x02*]\n\x08LogLevel\x12\x08\n\x04NONE\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x08\n\x04WARN\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\x0b\n\x07VERBOSE\x10\x05\x12\x10\n\x0cVERY_VERBOSE\x10\x06*4\n\x0b\x43limateMode\x12\x07\n\x03OFF\x10\x00\x12\x08\n\x04\x41UTO\x10\x01\x12\x08\n\x04\x43OOL\x10\x02\x12\x08\n\x04HEAT\x10\x03\x62\x06proto3') ) _FANSPEED = _descriptor.EnumDescriptor( @@ -45,8 +45,8 @@ _FANSPEED = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=5309, - serialized_end=5350, + serialized_start=5689, + serialized_end=5730, ) _sym_db.RegisterEnumDescriptor(_FANSPEED) @@ -88,8 +88,8 @@ _LOGLEVEL = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=5352, - serialized_end=5445, + serialized_start=5732, + serialized_end=5825, ) _sym_db.RegisterEnumDescriptor(_LOGLEVEL) @@ -119,8 +119,8 @@ _CLIMATEMODE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=5447, - serialized_end=5499, + serialized_start=5827, + serialized_end=5879, ) _sym_db.RegisterEnumDescriptor(_CLIMATEMODE) @@ -141,9 +141,9 @@ COOL = 2 HEAT = 3 -_COVERSTATERESPONSE_COVERSTATE = _descriptor.EnumDescriptor( - name='CoverState', - full_name='CoverStateResponse.CoverState', +_COVERSTATERESPONSE_LEGACYCOVERSTATE = _descriptor.EnumDescriptor( + name='LegacyCoverState', + full_name='CoverStateResponse.LegacyCoverState', filename=None, file=DESCRIPTOR, values=[ @@ -158,14 +158,40 @@ _COVERSTATERESPONSE_COVERSTATE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=1903, - serialized_end=1937, + serialized_start=1173, + serialized_end=1213, ) -_sym_db.RegisterEnumDescriptor(_COVERSTATERESPONSE_COVERSTATE) +_sym_db.RegisterEnumDescriptor(_COVERSTATERESPONSE_LEGACYCOVERSTATE) -_COVERCOMMANDREQUEST_COVERCOMMAND = _descriptor.EnumDescriptor( - name='CoverCommand', - full_name='CoverCommandRequest.CoverCommand', +_COVERSTATERESPONSE_COVERCURRENTOPERATION = _descriptor.EnumDescriptor( + name='CoverCurrentOperation', + full_name='CoverStateResponse.CoverCurrentOperation', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='IDLE', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_OPENING', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_CLOSING', index=2, number=2, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1215, + serialized_end=1280, +) +_sym_db.RegisterEnumDescriptor(_COVERSTATERESPONSE_COVERCURRENTOPERATION) + +_COVERCOMMANDREQUEST_LEGACYCOVERCOMMAND = _descriptor.EnumDescriptor( + name='LegacyCoverCommand', + full_name='CoverCommandRequest.LegacyCoverCommand', filename=None, file=DESCRIPTOR, values=[ @@ -184,10 +210,10 @@ _COVERCOMMANDREQUEST_COVERCOMMAND = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=2534, - serialized_end=2579, + serialized_start=1498, + serialized_end=1549, ) -_sym_db.RegisterEnumDescriptor(_COVERCOMMANDREQUEST_COVERCOMMAND) +_sym_db.RegisterEnumDescriptor(_COVERCOMMANDREQUEST_LEGACYCOVERCOMMAND) _LISTENTITIESSERVICESARGUMENT_TYPE = _descriptor.EnumDescriptor( name='Type', @@ -214,8 +240,8 @@ _LISTENTITIESSERVICESARGUMENT_TYPE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=4078, - serialized_end=4126, + serialized_start=4299, + serialized_end=4347, ) _sym_db.RegisterEnumDescriptor(_LISTENTITIESSERVICESARGUMENT_TYPE) @@ -575,6 +601,54 @@ _LISTENTITIESREQUEST = _descriptor.Descriptor( ) +_LISTENTITIESDONERESPONSE = _descriptor.Descriptor( + name='ListEntitiesDoneResponse', + full_name='ListEntitiesDoneResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=517, + serialized_end=543, +) + + +_SUBSCRIBESTATESREQUEST = _descriptor.Descriptor( + name='SubscribeStatesRequest', + full_name='SubscribeStatesRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=545, + serialized_end=569, +) + + _LISTENTITIESBINARYSENSORRESPONSE = _descriptor.Descriptor( name='ListEntitiesBinarySensorResponse', full_name='ListEntitiesBinarySensorResponse', @@ -636,8 +710,46 @@ _LISTENTITIESBINARYSENSORRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=518, - serialized_end=672, + serialized_start=572, + serialized_end=726, +) + + +_BINARYSENSORSTATERESPONSE = _descriptor.Descriptor( + name='BinarySensorStateResponse', + full_name='BinarySensorStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='BinarySensorStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='BinarySensorStateResponse.state', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=728, + serialized_end=783, ) @@ -677,12 +789,33 @@ _LISTENTITIESCOVERRESPONSE = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='is_optimistic', full_name='ListEntitiesCoverResponse.is_optimistic', index=4, + name='assumed_state', full_name='ListEntitiesCoverResponse.assumed_state', index=4, number=5, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='supports_position', full_name='ListEntitiesCoverResponse.supports_position', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='supports_tilt', full_name='ListEntitiesCoverResponse.supports_tilt', index=6, + number=7, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='device_class', full_name='ListEntitiesCoverResponse.device_class', index=7, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -695,8 +828,150 @@ _LISTENTITIESCOVERRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=674, - serialized_end=789, + serialized_start=786, + serialized_end=973, +) + + +_COVERSTATERESPONSE = _descriptor.Descriptor( + name='CoverStateResponse', + full_name='CoverStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='CoverStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='legacy_state', full_name='CoverStateResponse.legacy_state', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='position', full_name='CoverStateResponse.position', index=2, + number=3, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='tilt', full_name='CoverStateResponse.tilt', index=3, + number=4, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='current_operation', full_name='CoverStateResponse.current_operation', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _COVERSTATERESPONSE_LEGACYCOVERSTATE, + _COVERSTATERESPONSE_COVERCURRENTOPERATION, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=976, + serialized_end=1280, +) + + +_COVERCOMMANDREQUEST = _descriptor.Descriptor( + name='CoverCommandRequest', + full_name='CoverCommandRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='CoverCommandRequest.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_legacy_command', full_name='CoverCommandRequest.has_legacy_command', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='legacy_command', full_name='CoverCommandRequest.legacy_command', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_position', full_name='CoverCommandRequest.has_position', index=3, + number=4, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='position', full_name='CoverCommandRequest.position', index=4, + number=5, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_tilt', full_name='CoverCommandRequest.has_tilt', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='tilt', full_name='CoverCommandRequest.tilt', index=6, + number=7, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='stop', full_name='CoverCommandRequest.stop', index=7, + number=8, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _COVERCOMMANDREQUEST_LEGACYCOVERCOMMAND, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1283, + serialized_end=1549, ) @@ -761,8 +1036,133 @@ _LISTENTITIESFANRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=792, - serialized_end=936, + serialized_start=1552, + serialized_end=1696, +) + + +_FANSTATERESPONSE = _descriptor.Descriptor( + name='FanStateResponse', + full_name='FanStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='FanStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='FanStateResponse.state', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='oscillating', full_name='FanStateResponse.oscillating', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='speed', full_name='FanStateResponse.speed', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1698, + serialized_end=1791, +) + + +_FANCOMMANDREQUEST = _descriptor.Descriptor( + name='FanCommandRequest', + full_name='FanCommandRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='FanCommandRequest.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_state', full_name='FanCommandRequest.has_state', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='FanCommandRequest.state', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_speed', full_name='FanCommandRequest.has_speed', index=3, + number=4, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='speed', full_name='FanCommandRequest.speed', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='has_oscillating', full_name='FanCommandRequest.has_oscillating', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='oscillating', full_name='FanCommandRequest.oscillating', index=6, + number=7, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1794, + serialized_end=1951, ) @@ -862,435 +1262,8 @@ _LISTENTITIESLIGHTRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=939, - serialized_end=1205, -) - - -_LISTENTITIESSENSORRESPONSE = _descriptor.Descriptor( - name='ListEntitiesSensorResponse', - full_name='ListEntitiesSensorResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='ListEntitiesSensorResponse.object_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='key', full_name='ListEntitiesSensorResponse.key', index=1, - number=2, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='ListEntitiesSensorResponse.name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unique_id', full_name='ListEntitiesSensorResponse.unique_id', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='icon', full_name='ListEntitiesSensorResponse.icon', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unit_of_measurement', full_name='ListEntitiesSensorResponse.unit_of_measurement', index=5, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='accuracy_decimals', full_name='ListEntitiesSensorResponse.accuracy_decimals', index=6, - number=7, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1208, - serialized_end=1371, -) - - -_LISTENTITIESSWITCHRESPONSE = _descriptor.Descriptor( - name='ListEntitiesSwitchResponse', - full_name='ListEntitiesSwitchResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='ListEntitiesSwitchResponse.object_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='key', full_name='ListEntitiesSwitchResponse.key', index=1, - number=2, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='ListEntitiesSwitchResponse.name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unique_id', full_name='ListEntitiesSwitchResponse.unique_id', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='icon', full_name='ListEntitiesSwitchResponse.icon', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='optimistic', full_name='ListEntitiesSwitchResponse.optimistic', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1373, - serialized_end=1500, -) - - -_LISTENTITIESTEXTSENSORRESPONSE = _descriptor.Descriptor( - name='ListEntitiesTextSensorResponse', - full_name='ListEntitiesTextSensorResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='ListEntitiesTextSensorResponse.object_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='key', full_name='ListEntitiesTextSensorResponse.key', index=1, - number=2, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='ListEntitiesTextSensorResponse.name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unique_id', full_name='ListEntitiesTextSensorResponse.unique_id', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='icon', full_name='ListEntitiesTextSensorResponse.icon', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1502, - serialized_end=1613, -) - - -_LISTENTITIESCAMERARESPONSE = _descriptor.Descriptor( - name='ListEntitiesCameraResponse', - full_name='ListEntitiesCameraResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='object_id', full_name='ListEntitiesCameraResponse.object_id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='key', full_name='ListEntitiesCameraResponse.key', index=1, - number=2, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='ListEntitiesCameraResponse.name', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unique_id', full_name='ListEntitiesCameraResponse.unique_id', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1615, - serialized_end=1708, -) - - -_LISTENTITIESDONERESPONSE = _descriptor.Descriptor( - name='ListEntitiesDoneResponse', - full_name='ListEntitiesDoneResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1710, - serialized_end=1736, -) - - -_SUBSCRIBESTATESREQUEST = _descriptor.Descriptor( - name='SubscribeStatesRequest', - full_name='SubscribeStatesRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1738, - serialized_end=1762, -) - - -_BINARYSENSORSTATERESPONSE = _descriptor.Descriptor( - name='BinarySensorStateResponse', - full_name='BinarySensorStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='BinarySensorStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='BinarySensorStateResponse.state', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1764, - serialized_end=1819, -) - - -_COVERSTATERESPONSE = _descriptor.Descriptor( - name='CoverStateResponse', - full_name='CoverStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='CoverStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='CoverStateResponse.state', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _COVERSTATERESPONSE_COVERSTATE, - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1821, - serialized_end=1937, -) - - -_FANSTATERESPONSE = _descriptor.Descriptor( - name='FanStateResponse', - full_name='FanStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='FanStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='FanStateResponse.state', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='oscillating', full_name='FanStateResponse.oscillating', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='speed', full_name='FanStateResponse.speed', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1939, - serialized_end=2032, + serialized_start=1954, + serialized_end=2220, ) @@ -1376,286 +1349,8 @@ _LIGHTSTATERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2035, - serialized_end=2203, -) - - -_SENSORSTATERESPONSE = _descriptor.Descriptor( - name='SensorStateResponse', - full_name='SensorStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='SensorStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='SensorStateResponse.state', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2205, - serialized_end=2254, -) - - -_SWITCHSTATERESPONSE = _descriptor.Descriptor( - name='SwitchStateResponse', - full_name='SwitchStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='SwitchStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='SwitchStateResponse.state', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2256, - serialized_end=2305, -) - - -_TEXTSENSORSTATERESPONSE = _descriptor.Descriptor( - name='TextSensorStateResponse', - full_name='TextSensorStateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='TextSensorStateResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='TextSensorStateResponse.state', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2307, - serialized_end=2360, -) - - -_CAMERAIMAGERESPONSE = _descriptor.Descriptor( - name='CameraImageResponse', - full_name='CameraImageResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='CameraImageResponse.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='data', full_name='CameraImageResponse.data', index=1, - number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='done', full_name='CameraImageResponse.done', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2362, - serialized_end=2424, -) - - -_COVERCOMMANDREQUEST = _descriptor.Descriptor( - name='CoverCommandRequest', - full_name='CoverCommandRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='CoverCommandRequest.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='has_state', full_name='CoverCommandRequest.has_state', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='command', full_name='CoverCommandRequest.command', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _COVERCOMMANDREQUEST_COVERCOMMAND, - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2427, - serialized_end=2579, -) - - -_FANCOMMANDREQUEST = _descriptor.Descriptor( - name='FanCommandRequest', - full_name='FanCommandRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='FanCommandRequest.key', index=0, - number=1, type=7, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='has_state', full_name='FanCommandRequest.has_state', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='state', full_name='FanCommandRequest.state', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='has_speed', full_name='FanCommandRequest.has_speed', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='speed', full_name='FanCommandRequest.speed', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='has_oscillating', full_name='FanCommandRequest.has_oscillating', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='oscillating', full_name='FanCommandRequest.oscillating', index=6, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2582, - serialized_end=2739, + serialized_start=2223, + serialized_end=2391, ) @@ -1811,8 +1506,223 @@ _LIGHTCOMMANDREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2742, - serialized_end=3147, + serialized_start=2394, + serialized_end=2799, +) + + +_LISTENTITIESSENSORRESPONSE = _descriptor.Descriptor( + name='ListEntitiesSensorResponse', + full_name='ListEntitiesSensorResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='object_id', full_name='ListEntitiesSensorResponse.object_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='ListEntitiesSensorResponse.key', index=1, + number=2, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='ListEntitiesSensorResponse.name', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='unique_id', full_name='ListEntitiesSensorResponse.unique_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='icon', full_name='ListEntitiesSensorResponse.icon', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='unit_of_measurement', full_name='ListEntitiesSensorResponse.unit_of_measurement', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='accuracy_decimals', full_name='ListEntitiesSensorResponse.accuracy_decimals', index=6, + number=7, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2802, + serialized_end=2965, +) + + +_SENSORSTATERESPONSE = _descriptor.Descriptor( + name='SensorStateResponse', + full_name='SensorStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='SensorStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='SensorStateResponse.state', index=1, + number=2, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2967, + serialized_end=3016, +) + + +_LISTENTITIESSWITCHRESPONSE = _descriptor.Descriptor( + name='ListEntitiesSwitchResponse', + full_name='ListEntitiesSwitchResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='object_id', full_name='ListEntitiesSwitchResponse.object_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='ListEntitiesSwitchResponse.key', index=1, + number=2, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='ListEntitiesSwitchResponse.name', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='unique_id', full_name='ListEntitiesSwitchResponse.unique_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='icon', full_name='ListEntitiesSwitchResponse.icon', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='assumed_state', full_name='ListEntitiesSwitchResponse.assumed_state', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3019, + serialized_end=3149, +) + + +_SWITCHSTATERESPONSE = _descriptor.Descriptor( + name='SwitchStateResponse', + full_name='SwitchStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='SwitchStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='SwitchStateResponse.state', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3151, + serialized_end=3200, ) @@ -1849,8 +1759,105 @@ _SWITCHCOMMANDREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3149, - serialized_end=3199, + serialized_start=3202, + serialized_end=3252, +) + + +_LISTENTITIESTEXTSENSORRESPONSE = _descriptor.Descriptor( + name='ListEntitiesTextSensorResponse', + full_name='ListEntitiesTextSensorResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='object_id', full_name='ListEntitiesTextSensorResponse.object_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='ListEntitiesTextSensorResponse.key', index=1, + number=2, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='ListEntitiesTextSensorResponse.name', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='unique_id', full_name='ListEntitiesTextSensorResponse.unique_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='icon', full_name='ListEntitiesTextSensorResponse.icon', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3254, + serialized_end=3365, +) + + +_TEXTSENSORSTATERESPONSE = _descriptor.Descriptor( + name='TextSensorStateResponse', + full_name='TextSensorStateResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='TextSensorStateResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='state', full_name='TextSensorStateResponse.state', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3367, + serialized_end=3420, ) @@ -1887,8 +1894,8 @@ _SUBSCRIBELOGSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3201, - serialized_end=3270, + serialized_start=3422, + serialized_end=3491, ) @@ -1939,8 +1946,8 @@ _SUBSCRIBELOGSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3272, - serialized_end=3372, + serialized_start=3493, + serialized_end=3593, ) @@ -1963,8 +1970,8 @@ _SUBSCRIBESERVICECALLSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3374, - serialized_end=3404, + serialized_start=3595, + serialized_end=3625, ) @@ -2001,8 +2008,8 @@ _SERVICECALLRESPONSE_DATAENTRY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3612, - serialized_end=3655, + serialized_start=3833, + serialized_end=3876, ) _SERVICECALLRESPONSE_DATATEMPLATEENTRY = _descriptor.Descriptor( @@ -2038,8 +2045,8 @@ _SERVICECALLRESPONSE_DATATEMPLATEENTRY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3657, - serialized_end=3708, + serialized_start=3878, + serialized_end=3929, ) _SERVICECALLRESPONSE_VARIABLESENTRY = _descriptor.Descriptor( @@ -2075,8 +2082,8 @@ _SERVICECALLRESPONSE_VARIABLESENTRY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3710, - serialized_end=3758, + serialized_start=3931, + serialized_end=3979, ) _SERVICECALLRESPONSE = _descriptor.Descriptor( @@ -2126,8 +2133,8 @@ _SERVICECALLRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3407, - serialized_end=3758, + serialized_start=3628, + serialized_end=3979, ) @@ -2150,8 +2157,8 @@ _SUBSCRIBEHOMEASSISTANTSTATESREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3760, - serialized_end=3797, + serialized_start=3981, + serialized_end=4018, ) @@ -2181,8 +2188,8 @@ _SUBSCRIBEHOMEASSISTANTSTATERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3799, - serialized_end=3855, + serialized_start=4020, + serialized_end=4076, ) @@ -2219,8 +2226,8 @@ _HOMEASSISTANTSTATERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3857, - serialized_end=3919, + serialized_start=4078, + serialized_end=4140, ) @@ -2243,8 +2250,8 @@ _GETTIMEREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3921, - serialized_end=3937, + serialized_start=4142, + serialized_end=4158, ) @@ -2274,8 +2281,8 @@ _GETTIMERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3939, - serialized_end=3979, + serialized_start=4160, + serialized_end=4200, ) @@ -2313,8 +2320,8 @@ _LISTENTITIESSERVICESARGUMENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3982, - serialized_end=4126, + serialized_start=4203, + serialized_end=4347, ) @@ -2358,8 +2365,8 @@ _LISTENTITIESSERVICESRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4128, - serialized_end=4230, + serialized_start=4349, + serialized_end=4451, ) @@ -2410,8 +2417,8 @@ _EXECUTESERVICEARGUMENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4232, - serialized_end=4318, + serialized_start=4453, + serialized_end=4539, ) @@ -2448,8 +2455,105 @@ _EXECUTESERVICEREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4320, - serialized_end=4395, + serialized_start=4541, + serialized_end=4616, +) + + +_LISTENTITIESCAMERARESPONSE = _descriptor.Descriptor( + name='ListEntitiesCameraResponse', + full_name='ListEntitiesCameraResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='object_id', full_name='ListEntitiesCameraResponse.object_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key', full_name='ListEntitiesCameraResponse.key', index=1, + number=2, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='ListEntitiesCameraResponse.name', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='unique_id', full_name='ListEntitiesCameraResponse.unique_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=4618, + serialized_end=4711, +) + + +_CAMERAIMAGERESPONSE = _descriptor.Descriptor( + name='CameraImageResponse', + full_name='CameraImageResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='CameraImageResponse.key', index=0, + number=1, type=7, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='data', full_name='CameraImageResponse.data', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='done', full_name='CameraImageResponse.done', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=4713, + serialized_end=4775, ) @@ -2486,8 +2590,8 @@ _CAMERAIMAGEREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4397, - serialized_end=4449, + serialized_start=4777, + serialized_end=4829, ) @@ -2587,8 +2691,8 @@ _LISTENTITIESCLIMATERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4452, - serialized_end=4790, + serialized_start=4832, + serialized_end=5170, ) @@ -2660,8 +2764,8 @@ _CLIMATESTATERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4793, - serialized_end=4992, + serialized_start=5173, + serialized_end=5372, ) @@ -2761,15 +2865,17 @@ _CLIMATECOMMANDREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4995, - serialized_end=5307, + serialized_start=5375, + serialized_end=5687, ) -_COVERSTATERESPONSE.fields_by_name['state'].enum_type = _COVERSTATERESPONSE_COVERSTATE -_COVERSTATERESPONSE_COVERSTATE.containing_type = _COVERSTATERESPONSE +_COVERSTATERESPONSE.fields_by_name['legacy_state'].enum_type = _COVERSTATERESPONSE_LEGACYCOVERSTATE +_COVERSTATERESPONSE.fields_by_name['current_operation'].enum_type = _COVERSTATERESPONSE_COVERCURRENTOPERATION +_COVERSTATERESPONSE_LEGACYCOVERSTATE.containing_type = _COVERSTATERESPONSE +_COVERSTATERESPONSE_COVERCURRENTOPERATION.containing_type = _COVERSTATERESPONSE +_COVERCOMMANDREQUEST.fields_by_name['legacy_command'].enum_type = _COVERCOMMANDREQUEST_LEGACYCOVERCOMMAND +_COVERCOMMANDREQUEST_LEGACYCOVERCOMMAND.containing_type = _COVERCOMMANDREQUEST _FANSTATERESPONSE.fields_by_name['speed'].enum_type = _FANSPEED -_COVERCOMMANDREQUEST.fields_by_name['command'].enum_type = _COVERCOMMANDREQUEST_COVERCOMMAND -_COVERCOMMANDREQUEST_COVERCOMMAND.containing_type = _COVERCOMMANDREQUEST _FANCOMMANDREQUEST.fields_by_name['speed'].enum_type = _FANSPEED _SUBSCRIBELOGSREQUEST.fields_by_name['level'].enum_type = _LOGLEVEL _SUBSCRIBELOGSRESPONSE.fields_by_name['level'].enum_type = _LOGLEVEL @@ -2797,28 +2903,26 @@ DESCRIPTOR.message_types_by_name['PingResponse'] = _PINGRESPONSE DESCRIPTOR.message_types_by_name['DeviceInfoRequest'] = _DEVICEINFOREQUEST DESCRIPTOR.message_types_by_name['DeviceInfoResponse'] = _DEVICEINFORESPONSE DESCRIPTOR.message_types_by_name['ListEntitiesRequest'] = _LISTENTITIESREQUEST -DESCRIPTOR.message_types_by_name['ListEntitiesBinarySensorResponse'] = _LISTENTITIESBINARYSENSORRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesCoverResponse'] = _LISTENTITIESCOVERRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesFanResponse'] = _LISTENTITIESFANRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesLightResponse'] = _LISTENTITIESLIGHTRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesSensorResponse'] = _LISTENTITIESSENSORRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesSwitchResponse'] = _LISTENTITIESSWITCHRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesTextSensorResponse'] = _LISTENTITIESTEXTSENSORRESPONSE -DESCRIPTOR.message_types_by_name['ListEntitiesCameraResponse'] = _LISTENTITIESCAMERARESPONSE DESCRIPTOR.message_types_by_name['ListEntitiesDoneResponse'] = _LISTENTITIESDONERESPONSE DESCRIPTOR.message_types_by_name['SubscribeStatesRequest'] = _SUBSCRIBESTATESREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesBinarySensorResponse'] = _LISTENTITIESBINARYSENSORRESPONSE DESCRIPTOR.message_types_by_name['BinarySensorStateResponse'] = _BINARYSENSORSTATERESPONSE +DESCRIPTOR.message_types_by_name['ListEntitiesCoverResponse'] = _LISTENTITIESCOVERRESPONSE DESCRIPTOR.message_types_by_name['CoverStateResponse'] = _COVERSTATERESPONSE -DESCRIPTOR.message_types_by_name['FanStateResponse'] = _FANSTATERESPONSE -DESCRIPTOR.message_types_by_name['LightStateResponse'] = _LIGHTSTATERESPONSE -DESCRIPTOR.message_types_by_name['SensorStateResponse'] = _SENSORSTATERESPONSE -DESCRIPTOR.message_types_by_name['SwitchStateResponse'] = _SWITCHSTATERESPONSE -DESCRIPTOR.message_types_by_name['TextSensorStateResponse'] = _TEXTSENSORSTATERESPONSE -DESCRIPTOR.message_types_by_name['CameraImageResponse'] = _CAMERAIMAGERESPONSE DESCRIPTOR.message_types_by_name['CoverCommandRequest'] = _COVERCOMMANDREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesFanResponse'] = _LISTENTITIESFANRESPONSE +DESCRIPTOR.message_types_by_name['FanStateResponse'] = _FANSTATERESPONSE DESCRIPTOR.message_types_by_name['FanCommandRequest'] = _FANCOMMANDREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesLightResponse'] = _LISTENTITIESLIGHTRESPONSE +DESCRIPTOR.message_types_by_name['LightStateResponse'] = _LIGHTSTATERESPONSE DESCRIPTOR.message_types_by_name['LightCommandRequest'] = _LIGHTCOMMANDREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesSensorResponse'] = _LISTENTITIESSENSORRESPONSE +DESCRIPTOR.message_types_by_name['SensorStateResponse'] = _SENSORSTATERESPONSE +DESCRIPTOR.message_types_by_name['ListEntitiesSwitchResponse'] = _LISTENTITIESSWITCHRESPONSE +DESCRIPTOR.message_types_by_name['SwitchStateResponse'] = _SWITCHSTATERESPONSE DESCRIPTOR.message_types_by_name['SwitchCommandRequest'] = _SWITCHCOMMANDREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesTextSensorResponse'] = _LISTENTITIESTEXTSENSORRESPONSE +DESCRIPTOR.message_types_by_name['TextSensorStateResponse'] = _TEXTSENSORSTATERESPONSE DESCRIPTOR.message_types_by_name['SubscribeLogsRequest'] = _SUBSCRIBELOGSREQUEST DESCRIPTOR.message_types_by_name['SubscribeLogsResponse'] = _SUBSCRIBELOGSRESPONSE DESCRIPTOR.message_types_by_name['SubscribeServiceCallsRequest'] = _SUBSCRIBESERVICECALLSREQUEST @@ -2832,6 +2936,8 @@ DESCRIPTOR.message_types_by_name['ListEntitiesServicesArgument'] = _LISTENTITIES DESCRIPTOR.message_types_by_name['ListEntitiesServicesResponse'] = _LISTENTITIESSERVICESRESPONSE DESCRIPTOR.message_types_by_name['ExecuteServiceArgument'] = _EXECUTESERVICEARGUMENT DESCRIPTOR.message_types_by_name['ExecuteServiceRequest'] = _EXECUTESERVICEREQUEST +DESCRIPTOR.message_types_by_name['ListEntitiesCameraResponse'] = _LISTENTITIESCAMERARESPONSE +DESCRIPTOR.message_types_by_name['CameraImageResponse'] = _CAMERAIMAGERESPONSE DESCRIPTOR.message_types_by_name['CameraImageRequest'] = _CAMERAIMAGEREQUEST DESCRIPTOR.message_types_by_name['ListEntitiesClimateResponse'] = _LISTENTITIESCLIMATERESPONSE DESCRIPTOR.message_types_by_name['ClimateStateResponse'] = _CLIMATESTATERESPONSE @@ -2918,62 +3024,6 @@ ListEntitiesRequest = _reflection.GeneratedProtocolMessageType('ListEntitiesRequ )) _sym_db.RegisterMessage(ListEntitiesRequest) -ListEntitiesBinarySensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesBinarySensorResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESBINARYSENSORRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesBinarySensorResponse) - )) -_sym_db.RegisterMessage(ListEntitiesBinarySensorResponse) - -ListEntitiesCoverResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesCoverResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESCOVERRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesCoverResponse) - )) -_sym_db.RegisterMessage(ListEntitiesCoverResponse) - -ListEntitiesFanResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesFanResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESFANRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesFanResponse) - )) -_sym_db.RegisterMessage(ListEntitiesFanResponse) - -ListEntitiesLightResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesLightResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESLIGHTRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesLightResponse) - )) -_sym_db.RegisterMessage(ListEntitiesLightResponse) - -ListEntitiesSensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesSensorResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESSENSORRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesSensorResponse) - )) -_sym_db.RegisterMessage(ListEntitiesSensorResponse) - -ListEntitiesSwitchResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesSwitchResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESSWITCHRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesSwitchResponse) - )) -_sym_db.RegisterMessage(ListEntitiesSwitchResponse) - -ListEntitiesTextSensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesTextSensorResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESTEXTSENSORRESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesTextSensorResponse) - )) -_sym_db.RegisterMessage(ListEntitiesTextSensorResponse) - -ListEntitiesCameraResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesCameraResponse', (_message.Message,), dict( - DESCRIPTOR = _LISTENTITIESCAMERARESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:ListEntitiesCameraResponse) - )) -_sym_db.RegisterMessage(ListEntitiesCameraResponse) - ListEntitiesDoneResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesDoneResponse', (_message.Message,), dict( DESCRIPTOR = _LISTENTITIESDONERESPONSE, __module__ = 'api_pb2' @@ -2988,6 +3038,13 @@ SubscribeStatesRequest = _reflection.GeneratedProtocolMessageType('SubscribeStat )) _sym_db.RegisterMessage(SubscribeStatesRequest) +ListEntitiesBinarySensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesBinarySensorResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESBINARYSENSORRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesBinarySensorResponse) + )) +_sym_db.RegisterMessage(ListEntitiesBinarySensorResponse) + BinarySensorStateResponse = _reflection.GeneratedProtocolMessageType('BinarySensorStateResponse', (_message.Message,), dict( DESCRIPTOR = _BINARYSENSORSTATERESPONSE, __module__ = 'api_pb2' @@ -2995,6 +3052,13 @@ BinarySensorStateResponse = _reflection.GeneratedProtocolMessageType('BinarySens )) _sym_db.RegisterMessage(BinarySensorStateResponse) +ListEntitiesCoverResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesCoverResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESCOVERRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesCoverResponse) + )) +_sym_db.RegisterMessage(ListEntitiesCoverResponse) + CoverStateResponse = _reflection.GeneratedProtocolMessageType('CoverStateResponse', (_message.Message,), dict( DESCRIPTOR = _COVERSTATERESPONSE, __module__ = 'api_pb2' @@ -3002,48 +3066,6 @@ CoverStateResponse = _reflection.GeneratedProtocolMessageType('CoverStateRespons )) _sym_db.RegisterMessage(CoverStateResponse) -FanStateResponse = _reflection.GeneratedProtocolMessageType('FanStateResponse', (_message.Message,), dict( - DESCRIPTOR = _FANSTATERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:FanStateResponse) - )) -_sym_db.RegisterMessage(FanStateResponse) - -LightStateResponse = _reflection.GeneratedProtocolMessageType('LightStateResponse', (_message.Message,), dict( - DESCRIPTOR = _LIGHTSTATERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:LightStateResponse) - )) -_sym_db.RegisterMessage(LightStateResponse) - -SensorStateResponse = _reflection.GeneratedProtocolMessageType('SensorStateResponse', (_message.Message,), dict( - DESCRIPTOR = _SENSORSTATERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:SensorStateResponse) - )) -_sym_db.RegisterMessage(SensorStateResponse) - -SwitchStateResponse = _reflection.GeneratedProtocolMessageType('SwitchStateResponse', (_message.Message,), dict( - DESCRIPTOR = _SWITCHSTATERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:SwitchStateResponse) - )) -_sym_db.RegisterMessage(SwitchStateResponse) - -TextSensorStateResponse = _reflection.GeneratedProtocolMessageType('TextSensorStateResponse', (_message.Message,), dict( - DESCRIPTOR = _TEXTSENSORSTATERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:TextSensorStateResponse) - )) -_sym_db.RegisterMessage(TextSensorStateResponse) - -CameraImageResponse = _reflection.GeneratedProtocolMessageType('CameraImageResponse', (_message.Message,), dict( - DESCRIPTOR = _CAMERAIMAGERESPONSE, - __module__ = 'api_pb2' - # @@protoc_insertion_point(class_scope:CameraImageResponse) - )) -_sym_db.RegisterMessage(CameraImageResponse) - CoverCommandRequest = _reflection.GeneratedProtocolMessageType('CoverCommandRequest', (_message.Message,), dict( DESCRIPTOR = _COVERCOMMANDREQUEST, __module__ = 'api_pb2' @@ -3051,6 +3073,20 @@ CoverCommandRequest = _reflection.GeneratedProtocolMessageType('CoverCommandRequ )) _sym_db.RegisterMessage(CoverCommandRequest) +ListEntitiesFanResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesFanResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESFANRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesFanResponse) + )) +_sym_db.RegisterMessage(ListEntitiesFanResponse) + +FanStateResponse = _reflection.GeneratedProtocolMessageType('FanStateResponse', (_message.Message,), dict( + DESCRIPTOR = _FANSTATERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:FanStateResponse) + )) +_sym_db.RegisterMessage(FanStateResponse) + FanCommandRequest = _reflection.GeneratedProtocolMessageType('FanCommandRequest', (_message.Message,), dict( DESCRIPTOR = _FANCOMMANDREQUEST, __module__ = 'api_pb2' @@ -3058,6 +3094,20 @@ FanCommandRequest = _reflection.GeneratedProtocolMessageType('FanCommandRequest' )) _sym_db.RegisterMessage(FanCommandRequest) +ListEntitiesLightResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesLightResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESLIGHTRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesLightResponse) + )) +_sym_db.RegisterMessage(ListEntitiesLightResponse) + +LightStateResponse = _reflection.GeneratedProtocolMessageType('LightStateResponse', (_message.Message,), dict( + DESCRIPTOR = _LIGHTSTATERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:LightStateResponse) + )) +_sym_db.RegisterMessage(LightStateResponse) + LightCommandRequest = _reflection.GeneratedProtocolMessageType('LightCommandRequest', (_message.Message,), dict( DESCRIPTOR = _LIGHTCOMMANDREQUEST, __module__ = 'api_pb2' @@ -3065,6 +3115,34 @@ LightCommandRequest = _reflection.GeneratedProtocolMessageType('LightCommandRequ )) _sym_db.RegisterMessage(LightCommandRequest) +ListEntitiesSensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesSensorResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESSENSORRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesSensorResponse) + )) +_sym_db.RegisterMessage(ListEntitiesSensorResponse) + +SensorStateResponse = _reflection.GeneratedProtocolMessageType('SensorStateResponse', (_message.Message,), dict( + DESCRIPTOR = _SENSORSTATERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:SensorStateResponse) + )) +_sym_db.RegisterMessage(SensorStateResponse) + +ListEntitiesSwitchResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesSwitchResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESSWITCHRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesSwitchResponse) + )) +_sym_db.RegisterMessage(ListEntitiesSwitchResponse) + +SwitchStateResponse = _reflection.GeneratedProtocolMessageType('SwitchStateResponse', (_message.Message,), dict( + DESCRIPTOR = _SWITCHSTATERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:SwitchStateResponse) + )) +_sym_db.RegisterMessage(SwitchStateResponse) + SwitchCommandRequest = _reflection.GeneratedProtocolMessageType('SwitchCommandRequest', (_message.Message,), dict( DESCRIPTOR = _SWITCHCOMMANDREQUEST, __module__ = 'api_pb2' @@ -3072,6 +3150,20 @@ SwitchCommandRequest = _reflection.GeneratedProtocolMessageType('SwitchCommandRe )) _sym_db.RegisterMessage(SwitchCommandRequest) +ListEntitiesTextSensorResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesTextSensorResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESTEXTSENSORRESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesTextSensorResponse) + )) +_sym_db.RegisterMessage(ListEntitiesTextSensorResponse) + +TextSensorStateResponse = _reflection.GeneratedProtocolMessageType('TextSensorStateResponse', (_message.Message,), dict( + DESCRIPTOR = _TEXTSENSORSTATERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:TextSensorStateResponse) + )) +_sym_db.RegisterMessage(TextSensorStateResponse) + SubscribeLogsRequest = _reflection.GeneratedProtocolMessageType('SubscribeLogsRequest', (_message.Message,), dict( DESCRIPTOR = _SUBSCRIBELOGSREQUEST, __module__ = 'api_pb2' @@ -3187,6 +3279,20 @@ ExecuteServiceRequest = _reflection.GeneratedProtocolMessageType('ExecuteService )) _sym_db.RegisterMessage(ExecuteServiceRequest) +ListEntitiesCameraResponse = _reflection.GeneratedProtocolMessageType('ListEntitiesCameraResponse', (_message.Message,), dict( + DESCRIPTOR = _LISTENTITIESCAMERARESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:ListEntitiesCameraResponse) + )) +_sym_db.RegisterMessage(ListEntitiesCameraResponse) + +CameraImageResponse = _reflection.GeneratedProtocolMessageType('CameraImageResponse', (_message.Message,), dict( + DESCRIPTOR = _CAMERAIMAGERESPONSE, + __module__ = 'api_pb2' + # @@protoc_insertion_point(class_scope:CameraImageResponse) + )) +_sym_db.RegisterMessage(CameraImageResponse) + CameraImageRequest = _reflection.GeneratedProtocolMessageType('CameraImageRequest', (_message.Message,), dict( DESCRIPTOR = _CAMERAIMAGEREQUEST, __module__ = 'api_pb2' diff --git a/aioesphomeapi/client.py b/aioesphomeapi/client.py index 0cc2b52..b8ec91b 100644 --- a/aioesphomeapi/client.py +++ b/aioesphomeapi/client.py @@ -1,685 +1,14 @@ -import asyncio import logging -import socket -import time -from typing import Any, Callable, List, Optional, Tuple, Union, cast, Dict - -import attr -from google.protobuf import message +from typing import Any, Callable, Optional, Tuple import aioesphomeapi.api_pb2 as pb +from aioesphomeapi.connection import APIConnection, ConnectionParams +from aioesphomeapi.core import APIConnectionError +from aioesphomeapi.model import * _LOGGER = logging.getLogger(__name__) -class APIConnectionError(Exception): - pass - - -MESSAGE_TYPE_TO_PROTO = { - 1: pb.HelloRequest, - 2: pb.HelloResponse, - 3: pb.ConnectRequest, - 4: pb.ConnectResponse, - 5: pb.DisconnectRequest, - 6: pb.DisconnectResponse, - 7: pb.PingRequest, - 8: pb.PingResponse, - 9: pb.DeviceInfoRequest, - 10: pb.DeviceInfoResponse, - 11: pb.ListEntitiesRequest, - 12: pb.ListEntitiesBinarySensorResponse, - 13: pb.ListEntitiesCoverResponse, - 14: pb.ListEntitiesFanResponse, - 15: pb.ListEntitiesLightResponse, - 16: pb.ListEntitiesSensorResponse, - 17: pb.ListEntitiesSwitchResponse, - 18: pb.ListEntitiesTextSensorResponse, - 19: pb.ListEntitiesDoneResponse, - 20: pb.SubscribeStatesRequest, - 21: pb.BinarySensorStateResponse, - 22: pb.CoverStateResponse, - 23: pb.FanStateResponse, - 24: pb.LightStateResponse, - 25: pb.SensorStateResponse, - 26: pb.SwitchStateResponse, - 27: pb.TextSensorStateResponse, - 28: pb.SubscribeLogsRequest, - 29: pb.SubscribeLogsResponse, - 30: pb.CoverCommandRequest, - 31: pb.FanCommandRequest, - 32: pb.LightCommandRequest, - 33: pb.SwitchCommandRequest, - 34: pb.SubscribeServiceCallsRequest, - 35: pb.ServiceCallResponse, - 36: pb.GetTimeRequest, - 37: pb.GetTimeResponse, - 38: pb.SubscribeHomeAssistantStatesRequest, - 39: pb.SubscribeHomeAssistantStateResponse, - 40: pb.HomeAssistantStateResponse, - 41: pb.ListEntitiesServicesResponse, - 42: pb.ExecuteServiceRequest, - 43: pb.ListEntitiesCameraResponse, - 44: pb.CameraImageResponse, - 45: pb.CameraImageRequest, - 46: pb.ListEntitiesClimateResponse, - 47: pb.ClimateStateResponse, - 48: pb.ClimateCommandRequest, -} - - -def _varuint_to_bytes(value: int) -> bytes: - if value <= 0x7F: - return bytes([value]) - - ret = bytes() - while value: - temp = value & 0x7F - value >>= 7 - if value: - ret += bytes([temp | 0x80]) - else: - ret += bytes([temp]) - - return ret - - -def _bytes_to_varuint(value: bytes) -> Optional[int]: - result = 0 - bitpos = 0 - for val in value: - result |= (val & 0x7F) << bitpos - bitpos += 7 - if (val & 0x80) == 0: - return result - return None - - -async def resolve_ip_address_getaddrinfo(eventloop: asyncio.events.AbstractEventLoop, - host: str, port: int) -> Tuple[Any, ...]: - try: - res = await eventloop.getaddrinfo(host, port, family=socket.AF_INET, - proto=socket.IPPROTO_TCP) - except OSError as err: - raise APIConnectionError("Error resolving IP address: {}".format(err)) - - if not res: - raise APIConnectionError("Error resolving IP address: No matches!") - - _, _, _, _, sockaddr = res[0] - - return sockaddr - - -async def resolve_ip_address(eventloop: asyncio.events.AbstractEventLoop, - host: str, port: int) -> Tuple[Any, ...]: - try: - return await resolve_ip_address_getaddrinfo(eventloop, host, port) - except APIConnectionError as err: - if host.endswith('.local'): - from aioesphomeapi.host_resolver import resolve_host - - return await eventloop.run_in_executor(None, resolve_host, host), port - raise err - - -# Wrap some types in attr classes to make them serializable -@attr.s -class DeviceInfo: - uses_password = attr.ib(type=bool) - name = attr.ib(type=str) - mac_address = attr.ib(type=str) - esphome_core_version = attr.ib(type=str) - compilation_time = attr.ib(type=str) - model = attr.ib(type=str) - has_deep_sleep = attr.ib(type=bool) - - -@attr.s -class EntityInfo: - object_id = attr.ib(type=str) - key = attr.ib(type=int) - name = attr.ib(type=str) - unique_id = attr.ib(type=str) - - -@attr.s -class EntityState: - key = attr.ib(type=int) - - -@attr.s -class BinarySensorInfo(EntityInfo): - device_class = attr.ib(type=str) - is_status_binary_sensor = attr.ib(type=bool) - - -@attr.s -class BinarySensorState(EntityState): - state = attr.ib(type=bool) - - -@attr.s -class CoverInfo(EntityInfo): - is_optimistic = attr.ib(type=bool) - - -COVER_STATE_OPEN = 0 -COVER_SATE_CLOSED = 1 -COVER_STATES = [COVER_STATE_OPEN, COVER_SATE_CLOSED] - -COVER_COMMAND_OPEN = 0 -COVER_COMMAND_CLOSE = 1 -COVER_COMMAND_STOP = 2 -COVER_COMMANDS = [COVER_COMMAND_OPEN, COVER_COMMAND_CLOSE, COVER_COMMAND_STOP] - - -@attr.s -class CoverState(EntityState): - state = attr.ib(type=int, converter=int, - validator=attr.validators.in_(COVER_STATES)) - - -@attr.s -class FanInfo(EntityInfo): - supports_oscillation = attr.ib(type=bool) - supports_speed = attr.ib(type=bool) - - -FAN_SPEED_LOW = 0 -FAN_SPEED_MEDIUM = 1 -FAN_SPEED_HIGH = 2 -FAN_SPEEDS = [FAN_SPEED_LOW, FAN_SPEED_MEDIUM, FAN_SPEED_HIGH] - - -@attr.s -class FanState(EntityState): - state = attr.ib(type=bool) - oscillating = attr.ib(type=bool) - speed = attr.ib(type=int, converter=int, - validator=attr.validators.in_(FAN_SPEEDS)) - - -@attr.s -class LightInfo(EntityInfo): - supports_brightness = attr.ib(type=bool) - supports_rgb = attr.ib(type=bool) - supports_white_value = attr.ib(type=bool) - supports_color_temperature = attr.ib(type=bool) - min_mireds = attr.ib(type=float) - max_mireds = attr.ib(type=float) - effects = attr.ib(type=List[str], converter=list) - - -@attr.s -class LightState(EntityState): - state = attr.ib(type=bool) - brightness = attr.ib(type=float) - red = attr.ib(type=float) - green = attr.ib(type=float) - blue = attr.ib(type=float) - white = attr.ib(type=float) - color_temperature = attr.ib(type=float) - effect = attr.ib(type=str) - - -@attr.s -class SensorInfo(EntityInfo): - icon = attr.ib(type=str) - unit_of_measurement = attr.ib(type=str) - accuracy_decimals = attr.ib(type=int) - - -@attr.s -class SensorState(EntityState): - state = attr.ib(type=float) - - -@attr.s -class SwitchInfo(EntityInfo): - icon = attr.ib(type=str) - optimistic = attr.ib(type=bool) - - -@attr.s -class SwitchState(EntityState): - state = attr.ib(type=bool) - - -@attr.s -class TextSensorInfo(EntityInfo): - icon = attr.ib(type=str) - - -@attr.s -class TextSensorState(EntityState): - state = attr.ib(type=str) - - -@attr.s -class CameraInfo(EntityInfo): - pass - - -@attr.s -class CameraState(EntityState): - image = attr.ib(type=bytes) - - -CLIMATE_MODE_OFF = 0 -CLIMATE_MODE_AUTO = 1 -CLIMATE_MODE_COOL = 2 -CLIMATE_MODE_HEAT = 3 -CLIMATE_MODES = [CLIMATE_MODE_OFF, CLIMATE_MODE_AUTO, CLIMATE_MODE_COOL, CLIMATE_MODE_HEAT] -_validate_climate_mode = attr.validators.in_(CLIMATE_MODES) - - -def _convert_climate_modes(value): - return [int(val) for val in value] - - -@attr.s -class ClimateInfo(EntityInfo): - supports_current_temperature = attr.ib(type=bool) - supports_two_point_target_temperature = attr.ib(type=bool) - supported_modes = attr.ib(type=List[int], converter=_convert_climate_modes) - visual_min_temperature = attr.ib(type=float) - visual_max_temperature = attr.ib(type=float) - visual_temperature_step = attr.ib(type=float) - supports_away = attr.ib(type=bool) - - -@attr.s -class ClimateState(EntityState): - mode = attr.ib(type=int, converter=int, validator=_validate_climate_mode) - current_temperature = attr.ib(type=float) - target_temperature = attr.ib(type=float) - target_temperature_low = attr.ib(type=float) - target_temperature_high = attr.ib(type=float) - away = attr.ib(type=bool) - - -COMPONENT_TYPE_TO_INFO = { - 'binary_sensor': BinarySensorInfo, - 'cover': CoverInfo, - 'fan': FanInfo, - 'light': LightInfo, - 'sensor': SensorInfo, - 'switch': SwitchInfo, - 'text_sensor': TextSensorInfo, - 'camera': CameraInfo, - 'climate': ClimateInfo, -} - - -@attr.s -class ServiceCall: - service = attr.ib(type=str) - data = attr.ib(type=Dict[str, str], converter=dict) - data_template = attr.ib(type=Dict[str, str], converter=dict) - variables = attr.ib(type=Dict[str, str], converter=dict) - - -USER_SERVICE_ARG_BOOL = 0 -USER_SERVICE_ARG_INT = 1 -USER_SERVICE_ARG_FLOAT = 2 -USER_SERVICE_ARG_STRING = 3 -USER_SERVICE_ARG_TYPES = [ - USER_SERVICE_ARG_BOOL, USER_SERVICE_ARG_INT, USER_SERVICE_ARG_FLOAT, USER_SERVICE_ARG_STRING -] - - -def _attr_obj_from_dict(cls, **kwargs): - return cls(**{key: kwargs[key] for key in attr.fields_dict(cls)}) - - -@attr.s -class UserServiceArg: - name = attr.ib(type=str) - type_ = attr.ib(type=int, converter=int, - validator=attr.validators.in_(USER_SERVICE_ARG_TYPES)) - - -@attr.s -class UserService: - name = attr.ib(type=str) - key = attr.ib(type=int) - args = attr.ib(type=List[UserServiceArg], converter=list) - - @staticmethod - def from_dict(dict_): - args = [] - for arg in dict_.get('args', []): - args.append(_attr_obj_from_dict(UserServiceArg, **arg)) - return UserService( - name=dict_.get('name', ''), - key=dict_.get('key', 0), - args=args - ) - - def to_dict(self): - return { - 'name': self.name, - 'key': self.key, - 'args': [attr.asdict(arg) for arg in self.args], - } - - -@attr.s -class ConnectionParams: - eventloop = attr.ib(type=asyncio.events.AbstractEventLoop) - address = attr.ib(type=str) - port = attr.ib(type=int) - password = attr.ib(type=Optional[str]) - client_info = attr.ib(type=str) - keepalive = attr.ib(type=float) - - -class APIConnection: - def __init__(self, params: ConnectionParams, on_stop): - self._params = params - self.on_stop = on_stop - self._stopped = False - self._socket = None # type: Optional[socket.socket] - self._socket_reader = None # type: Optional[asyncio.StreamReader] - self._socket_writer = None # type: Optional[asyncio.StreamWriter] - self._write_lock = asyncio.Lock() - self._connected = False - self._authenticated = False - self._socket_connected = False - self._state_lock = asyncio.Lock() - - self._message_handlers = [] # type: List[Callable[[message], None]] - - self._running_task = None # type: Optional[asyncio.Task] - - def _start_ping(self) -> None: - async def func() -> None: - while self._connected: - await asyncio.sleep(self._params.keepalive) - - if not self._connected: - return - - try: - await self.ping() - except APIConnectionError: - _LOGGER.info("%s: Ping Failed!", self._params.address) - await self._on_error() - return - - self._params.eventloop.create_task(func()) - - async def _close_socket(self) -> None: - if not self._socket_connected: - return - async with self._write_lock: - self._socket_writer.close() - self._socket_writer = None - self._socket_reader = None - if self._socket is not None: - self._socket.close() - self._socket_connected = False - self._connected = False - self._authenticated = False - _LOGGER.debug("%s: Closed socket", self._params.address) - - async def stop(self, force: bool = False) -> None: - if self._stopped: - return - if self._connected and not force: - try: - await self._disconnect() - except APIConnectionError: - pass - self._stopped = True - if self._running_task is not None: - self._running_task.cancel() - await self._close_socket() - await self.on_stop() - - async def _on_error(self) -> None: - await self.stop(force=True) - - async def connect(self) -> None: - if self._stopped: - raise APIConnectionError("Connection is closed!") - if self._connected: - raise APIConnectionError("Already connected!") - - try: - coro = resolve_ip_address(self._params.eventloop, self._params.address, - self._params.port) - sockaddr = await asyncio.wait_for(coro, 30.0) - except APIConnectionError as err: - await self._on_error() - raise err - except asyncio.TimeoutError: - await self._on_error() - raise APIConnectionError("Timeout while resolving IP address") - - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.setblocking(False) - self._socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - - _LOGGER.debug("%s: Connecting to %s:%s (%s)", self._params.address, - self._params.address, self._params.port, sockaddr) - try: - coro = self._params.eventloop.sock_connect(self._socket, sockaddr) - await asyncio.wait_for(coro, 30.0) - except OSError as err: - await self._on_error() - raise APIConnectionError("Error connecting to {}: {}".format(sockaddr, err)) - except asyncio.TimeoutError: - await self._on_error() - raise APIConnectionError("Timeout while connecting to {}".format(sockaddr)) - - _LOGGER.debug("%s: Opened socket for", self._params.address) - self._socket_reader, self._socket_writer = await asyncio.open_connection(sock=self._socket) - self._socket_connected = True - self._params.eventloop.create_task(self.run_forever()) - - hello = pb.HelloRequest() - hello.client_info = self._params.client_info - try: - resp = await self.send_message_await_response(hello, pb.HelloResponse) - except APIConnectionError as err: - await self._on_error() - raise err - _LOGGER.debug("%s: Successfully connected to %s ('%s' API=%s.%s)", - self._params.address, self._params.address, - resp.server_info, resp.api_version_major, resp.api_version_minor) - self._connected = True - - self._start_ping() - - async def login(self) -> None: - self._check_connected() - if self._authenticated: - raise APIConnectionError("Already logged in!") - - connect = pb.ConnectRequest() - if self._params.password is not None: - connect.password = self._params.password - resp = await self.send_message_await_response(connect, pb.ConnectResponse) - if resp.invalid_password: - raise APIConnectionError("Invalid password!") - - self._authenticated = True - - def _check_connected(self) -> None: - if not self._connected: - raise APIConnectionError("Must be connected!") - - @property - def is_connected(self) -> bool: - return self._connected - - @property - def is_authenticated(self) -> bool: - return self._authenticated - - async def _write(self, data: bytes) -> None: - _LOGGER.debug("%s: Write: %s", self._params.address, - ' '.join('{:02X}'.format(x) for x in data)) - if not self._socket_connected: - raise APIConnectionError("Socket is not connected") - try: - async with self._write_lock: - self._socket_writer.write(data) - await self._socket_writer.drain() - except OSError as err: - await self._on_error() - raise APIConnectionError("Error while writing data: {}".format(err)) - - async def send_message(self, msg: message.Message) -> None: - for message_type, klass in MESSAGE_TYPE_TO_PROTO.items(): - if isinstance(msg, klass): - break - else: - raise ValueError - - encoded = msg.SerializeToString() - _LOGGER.debug("%s: Sending %s: %s", self._params.address, type(msg), str(msg)) - req = bytes([0]) - req += _varuint_to_bytes(len(encoded)) - req += _varuint_to_bytes(message_type) - req += encoded - await self._write(req) - - async def send_message_callback_response(self, send_msg: message.Message, - on_message: Callable[[Any], None]) -> None: - self._message_handlers.append(on_message) - await self.send_message(send_msg) - - async def send_message_await_response_complex(self, send_msg: message.Message, - do_append: Callable[[Any], bool], - do_stop: Callable[[Any], bool], - timeout: float = 5.0) -> List[Any]: - fut = self._params.eventloop.create_future() - responses = [] - - def on_message(resp): - if fut.done(): - return - if do_append(resp): - responses.append(resp) - if do_stop(resp): - fut.set_result(responses) - - self._message_handlers.append(on_message) - await self.send_message(send_msg) - - try: - await asyncio.wait_for(fut, timeout) - except asyncio.TimeoutError: - if self._stopped: - raise APIConnectionError("Disconnected while waiting for API response!") - raise APIConnectionError("Timeout while waiting for API response!") - - try: - self._message_handlers.remove(on_message) - except ValueError: - pass - - return responses - - async def send_message_await_response(self, - send_msg: message.Message, - response_type: Any, timeout: float = 5.0) -> Any: - def is_response(msg): - return isinstance(msg, response_type) - - res = await self.send_message_await_response_complex( - send_msg, is_response, is_response, timeout=timeout) - if len(res) != 1: - raise APIConnectionError("Expected one result, got {}".format(len(res))) - - return res[0] - - async def _recv(self, amount: int) -> bytes: - if amount == 0: - return bytes() - - try: - ret = await self._socket_reader.readexactly(amount) - except (asyncio.IncompleteReadError, OSError, TimeoutError) as err: - raise APIConnectionError("Error while receiving data: {}".format(err)) - - return ret - - async def _recv_varint(self) -> int: - raw = bytes() - while not raw or raw[-1] & 0x80: - raw += await self._recv(1) - return cast(int, _bytes_to_varuint(raw)) - - async def _run_once(self) -> None: - preamble = await self._recv(1) - if preamble[0] != 0x00: - raise APIConnectionError("Invalid preamble") - - length = await self._recv_varint() - msg_type = await self._recv_varint() - - raw_msg = await self._recv(length) - if msg_type not in MESSAGE_TYPE_TO_PROTO: - _LOGGER.debug("%s: Skipping message type %s", self._params.address, msg_type) - return - - msg = MESSAGE_TYPE_TO_PROTO[msg_type]() - try: - msg.ParseFromString(raw_msg) - except Exception as e: - raise APIConnectionError("Invalid protobuf message: {}".format(e)) - _LOGGER.debug("%s: Got message of type %s: %s", self._params.address, type(msg), msg) - for msg_handler in self._message_handlers[:]: - msg_handler(msg) - await self._handle_internal_messages(msg) - - async def run_forever(self) -> None: - while True: - try: - await self._run_once() - except APIConnectionError as err: - _LOGGER.info("%s: Error while reading incoming messages: %s", - self._params.address, err) - await self._on_error() - break - except Exception as err: - _LOGGER.info("%s: Unexpected error while reading incoming messages: %s", - self._params.address, err) - await self._on_error() - break - - async def _handle_internal_messages(self, msg: Any) -> None: - if isinstance(msg, pb.DisconnectRequest): - await self.send_message(pb.DisconnectResponse()) - await self.stop(force=True) - elif isinstance(msg, pb.PingRequest): - await self.send_message(pb.PingResponse()) - elif isinstance(msg, pb.GetTimeRequest): - resp = pb.GetTimeResponse() - resp.epoch_seconds = int(time.time()) - await self.send_message(resp) - - async def ping(self) -> None: - self._check_connected() - await self.send_message_await_response(pb.PingRequest(), pb.PingResponse) - - async def _disconnect(self) -> None: - self._check_connected() - - try: - await self.send_message_await_response(pb.DisconnectRequest(), pb.DisconnectResponse) - except APIConnectionError: - pass - - def _check_authenticated(self) -> None: - if not self._authenticated: - raise APIConnectionError("Must login first!") - - class APIClient: def __init__(self, eventloop, address: str, port: int, password: str, *, client_info: str = 'aioesphomeapi', keepalive: float = 15.0): @@ -888,22 +217,37 @@ class APIClient: async def cover_command(self, key: int, - command: int + position: Optional[float] = None, + tilt: Optional[float] = None, + stop: bool = False, ) -> None: self._check_authenticated() req = pb.CoverCommandRequest() req.key = key - req.has_state = True - if command not in COVER_COMMANDS: - raise ValueError - req.command = command + if self.api_version >= APIVersion(1, 1): + if position is not None: + req.has_position = True + req.position = position + if tilt is not None: + req.has_tilt = True + req.tilt = tilt + if stop: + req.stop = stop + else: + req.has_legacy_command = True + if stop: + req.legacy_command = LegacyCoverCommand.STOP + elif position == 1.0: + req.legacy_command = LegacyCoverCommand.OPEN + else: + req.legacy_command = LegacyCoverCommand.CLOSE await self._connection.send_message(req) async def fan_command(self, key: int, state: Optional[bool] = None, - speed: Optional[int] = None, + speed: Optional[FanSpeed] = None, oscillating: Optional[bool] = None ) -> None: self._check_authenticated() @@ -915,8 +259,6 @@ class APIClient: req.state = state if speed is not None: req.has_speed = True - if speed not in FAN_SPEEDS: - raise ValueError req.speed = speed if oscillating is not None: req.has_oscillating = True @@ -979,7 +321,7 @@ class APIClient: async def climate_command(self, key: int, - mode: Optional[int] = None, + mode: Optional[ClimateMode] = None, target_temperature: Optional[float] = None, target_temperature_low: Optional[float] = None, target_temperature_high: Optional[float] = None, @@ -1016,10 +358,10 @@ class APIClient: arg = pb.ExecuteServiceArgument() val = data[arg_desc.name] attr_ = { - USER_SERVICE_ARG_BOOL: 'bool_', - USER_SERVICE_ARG_INT: 'int_', - USER_SERVICE_ARG_FLOAT: 'float_', - USER_SERVICE_ARG_STRING: 'string_', + UserServiceArgType.BOOL: 'bool_', + UserServiceArgType.INT: 'int_', + UserServiceArgType.FLOAT: 'float_', + UserServiceArgType.STRING: 'string_', }[arg_desc.type_] setattr(arg, attr_, val) args.append(arg) @@ -1037,3 +379,9 @@ class APIClient: async def request_image_stream(self): await self._request_image(stream=True) + + @property + def api_version(self) -> Optional[APIVersion]: + if self._connection is None: + return None + return self._connection.api_version diff --git a/aioesphomeapi/connection.py b/aioesphomeapi/connection.py new file mode 100644 index 0000000..36329a7 --- /dev/null +++ b/aioesphomeapi/connection.py @@ -0,0 +1,341 @@ +import asyncio +import logging +import socket +import time +from typing import Any, Callable, List, Optional, cast + +import attr +from google.protobuf import message + +import aioesphomeapi.api_pb2 as pb +from aioesphomeapi.core import APIConnectionError, MESSAGE_TYPE_TO_PROTO +from aioesphomeapi.model import APIVersion +from aioesphomeapi.util import _bytes_to_varuint, _varuint_to_bytes, resolve_ip_address + +_LOGGER = logging.getLogger(__name__) + + +@attr.s +class ConnectionParams: + eventloop = attr.ib(type=asyncio.events.AbstractEventLoop) + address = attr.ib(type=str) + port = attr.ib(type=int) + password = attr.ib(type=Optional[str]) + client_info = attr.ib(type=str) + keepalive = attr.ib(type=float) + + +class APIConnection: + def __init__(self, params: ConnectionParams, on_stop): + self._params = params + self.on_stop = on_stop + self._stopped = False + self._socket = None # type: Optional[socket.socket] + self._socket_reader = None # type: Optional[asyncio.StreamReader] + self._socket_writer = None # type: Optional[asyncio.StreamWriter] + self._write_lock = asyncio.Lock() + self._connected = False + self._authenticated = False + self._socket_connected = False + self._state_lock = asyncio.Lock() + self._api_version = None # type: Optional[APIVersion] + + self._message_handlers = [] # type: List[Callable[[message], None]] + + self._running_task = None # type: Optional[asyncio.Task] + + def _start_ping(self) -> None: + async def func() -> None: + while self._connected: + await asyncio.sleep(self._params.keepalive) + + if not self._connected: + return + + try: + await self.ping() + except APIConnectionError: + _LOGGER.info("%s: Ping Failed!", self._params.address) + await self._on_error() + return + + self._params.eventloop.create_task(func()) + + async def _close_socket(self) -> None: + if not self._socket_connected: + return + async with self._write_lock: + self._socket_writer.close() + self._socket_writer = None + self._socket_reader = None + if self._socket is not None: + self._socket.close() + self._socket_connected = False + self._connected = False + self._authenticated = False + _LOGGER.debug("%s: Closed socket", self._params.address) + + async def stop(self, force: bool = False) -> None: + if self._stopped: + return + if self._connected and not force: + try: + await self._disconnect() + except APIConnectionError: + pass + self._stopped = True + if self._running_task is not None: + self._running_task.cancel() + await self._close_socket() + await self.on_stop() + + async def _on_error(self) -> None: + await self.stop(force=True) + + async def connect(self) -> None: + if self._stopped: + raise APIConnectionError("Connection is closed!") + if self._connected: + raise APIConnectionError("Already connected!") + + try: + coro = resolve_ip_address(self._params.eventloop, self._params.address, + self._params.port) + sockaddr = await asyncio.wait_for(coro, 30.0) + except APIConnectionError as err: + await self._on_error() + raise err + except asyncio.TimeoutError: + await self._on_error() + raise APIConnectionError("Timeout while resolving IP address") + + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.setblocking(False) + self._socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + + _LOGGER.debug("%s: Connecting to %s:%s (%s)", self._params.address, + self._params.address, self._params.port, sockaddr) + try: + coro = self._params.eventloop.sock_connect(self._socket, sockaddr) + await asyncio.wait_for(coro, 30.0) + except OSError as err: + await self._on_error() + raise APIConnectionError("Error connecting to {}: {}".format(sockaddr, err)) + except asyncio.TimeoutError: + await self._on_error() + raise APIConnectionError("Timeout while connecting to {}".format(sockaddr)) + + _LOGGER.debug("%s: Opened socket for", self._params.address) + self._socket_reader, self._socket_writer = await asyncio.open_connection(sock=self._socket) + self._socket_connected = True + self._params.eventloop.create_task(self.run_forever()) + + hello = pb.HelloRequest() + hello.client_info = self._params.client_info + try: + resp = await self.send_message_await_response(hello, pb.HelloResponse) + except APIConnectionError as err: + await self._on_error() + raise err + _LOGGER.debug("%s: Successfully connected ('%s' API=%s.%s)", + self._params.address, resp.server_info, resp.api_version_major, + resp.api_version_minor) + self._api_version = APIVersion(resp.api_version_major, resp.api_version_minor) + if self._api_version.major > 2: + _LOGGER.error("%s: Incompatible version %s! Closing connection", + self._api_version.major) + await self._on_error() + raise APIConnectionError("Incompatible API version.") + self._connected = True + + self._start_ping() + + async def login(self) -> None: + self._check_connected() + if self._authenticated: + raise APIConnectionError("Already logged in!") + + connect = pb.ConnectRequest() + if self._params.password is not None: + connect.password = self._params.password + resp = await self.send_message_await_response(connect, pb.ConnectResponse) + if resp.invalid_password: + raise APIConnectionError("Invalid password!") + + self._authenticated = True + + def _check_connected(self) -> None: + if not self._connected: + raise APIConnectionError("Must be connected!") + + @property + def is_connected(self) -> bool: + return self._connected + + @property + def is_authenticated(self) -> bool: + return self._authenticated + + async def _write(self, data: bytes) -> None: + _LOGGER.debug("%s: Write: %s", self._params.address, + ' '.join('{:02X}'.format(x) for x in data)) + if not self._socket_connected: + raise APIConnectionError("Socket is not connected") + try: + async with self._write_lock: + self._socket_writer.write(data) + await self._socket_writer.drain() + except OSError as err: + await self._on_error() + raise APIConnectionError("Error while writing data: {}".format(err)) + + async def send_message(self, msg: message.Message) -> None: + for message_type, klass in MESSAGE_TYPE_TO_PROTO.items(): + if isinstance(msg, klass): + break + else: + raise ValueError + + encoded = msg.SerializeToString() + _LOGGER.debug("%s: Sending %s: %s", self._params.address, type(msg), str(msg)) + req = bytes([0]) + req += _varuint_to_bytes(len(encoded)) + req += _varuint_to_bytes(message_type) + req += encoded + await self._write(req) + + async def send_message_callback_response(self, send_msg: message.Message, + on_message: Callable[[Any], None]) -> None: + self._message_handlers.append(on_message) + await self.send_message(send_msg) + + async def send_message_await_response_complex(self, send_msg: message.Message, + do_append: Callable[[Any], bool], + do_stop: Callable[[Any], bool], + timeout: float = 5.0) -> List[Any]: + fut = self._params.eventloop.create_future() + responses = [] + + def on_message(resp): + if fut.done(): + return + if do_append(resp): + responses.append(resp) + if do_stop(resp): + fut.set_result(responses) + + self._message_handlers.append(on_message) + await self.send_message(send_msg) + + try: + await asyncio.wait_for(fut, timeout) + except asyncio.TimeoutError: + if self._stopped: + raise APIConnectionError("Disconnected while waiting for API response!") + raise APIConnectionError("Timeout while waiting for API response!") + + try: + self._message_handlers.remove(on_message) + except ValueError: + pass + + return responses + + async def send_message_await_response(self, + send_msg: message.Message, + response_type: Any, timeout: float = 5.0) -> Any: + def is_response(msg): + return isinstance(msg, response_type) + + res = await self.send_message_await_response_complex( + send_msg, is_response, is_response, timeout=timeout) + if len(res) != 1: + raise APIConnectionError("Expected one result, got {}".format(len(res))) + + return res[0] + + async def _recv(self, amount: int) -> bytes: + if amount == 0: + return bytes() + + try: + ret = await self._socket_reader.readexactly(amount) + except (asyncio.IncompleteReadError, OSError, TimeoutError) as err: + raise APIConnectionError("Error while receiving data: {}".format(err)) + + return ret + + async def _recv_varint(self) -> int: + raw = bytes() + while not raw or raw[-1] & 0x80: + raw += await self._recv(1) + return cast(int, _bytes_to_varuint(raw)) + + async def _run_once(self) -> None: + preamble = await self._recv(1) + if preamble[0] != 0x00: + raise APIConnectionError("Invalid preamble") + + length = await self._recv_varint() + msg_type = await self._recv_varint() + + raw_msg = await self._recv(length) + if msg_type not in MESSAGE_TYPE_TO_PROTO: + _LOGGER.debug("%s: Skipping message type %s", self._params.address, msg_type) + return + + msg = MESSAGE_TYPE_TO_PROTO[msg_type]() + try: + msg.ParseFromString(raw_msg) + except Exception as e: + raise APIConnectionError("Invalid protobuf message: {}".format(e)) + _LOGGER.debug("%s: Got message of type %s: %s", self._params.address, type(msg), msg) + for msg_handler in self._message_handlers[:]: + msg_handler(msg) + await self._handle_internal_messages(msg) + + async def run_forever(self) -> None: + while True: + try: + await self._run_once() + except APIConnectionError as err: + _LOGGER.info("%s: Error while reading incoming messages: %s", + self._params.address, err) + await self._on_error() + break + except Exception as err: + _LOGGER.info("%s: Unexpected error while reading incoming messages: %s", + self._params.address, err) + await self._on_error() + break + + async def _handle_internal_messages(self, msg: Any) -> None: + if isinstance(msg, pb.DisconnectRequest): + await self.send_message(pb.DisconnectResponse()) + await self.stop(force=True) + elif isinstance(msg, pb.PingRequest): + await self.send_message(pb.PingResponse()) + elif isinstance(msg, pb.GetTimeRequest): + resp = pb.GetTimeResponse() + resp.epoch_seconds = int(time.time()) + await self.send_message(resp) + + async def ping(self) -> None: + self._check_connected() + await self.send_message_await_response(pb.PingRequest(), pb.PingResponse) + + async def _disconnect(self) -> None: + self._check_connected() + + try: + await self.send_message_await_response(pb.DisconnectRequest(), pb.DisconnectResponse) + except APIConnectionError: + pass + + def _check_authenticated(self) -> None: + if not self._authenticated: + raise APIConnectionError("Must login first!") + + @property + def api_version(self) -> Optional[APIVersion]: + return self._api_version diff --git a/aioesphomeapi/core.py b/aioesphomeapi/core.py new file mode 100644 index 0000000..a20a1a8 --- /dev/null +++ b/aioesphomeapi/core.py @@ -0,0 +1,57 @@ +import aioesphomeapi.api_pb2 as pb + + +class APIConnectionError(Exception): + pass + + +MESSAGE_TYPE_TO_PROTO = { + 1: pb.HelloRequest, + 2: pb.HelloResponse, + 3: pb.ConnectRequest, + 4: pb.ConnectResponse, + 5: pb.DisconnectRequest, + 6: pb.DisconnectResponse, + 7: pb.PingRequest, + 8: pb.PingResponse, + 9: pb.DeviceInfoRequest, + 10: pb.DeviceInfoResponse, + 11: pb.ListEntitiesRequest, + 12: pb.ListEntitiesBinarySensorResponse, + 13: pb.ListEntitiesCoverResponse, + 14: pb.ListEntitiesFanResponse, + 15: pb.ListEntitiesLightResponse, + 16: pb.ListEntitiesSensorResponse, + 17: pb.ListEntitiesSwitchResponse, + 18: pb.ListEntitiesTextSensorResponse, + 19: pb.ListEntitiesDoneResponse, + 20: pb.SubscribeStatesRequest, + 21: pb.BinarySensorStateResponse, + 22: pb.CoverStateResponse, + 23: pb.FanStateResponse, + 24: pb.LightStateResponse, + 25: pb.SensorStateResponse, + 26: pb.SwitchStateResponse, + 27: pb.TextSensorStateResponse, + 28: pb.SubscribeLogsRequest, + 29: pb.SubscribeLogsResponse, + 30: pb.CoverCommandRequest, + 31: pb.FanCommandRequest, + 32: pb.LightCommandRequest, + 33: pb.SwitchCommandRequest, + 34: pb.SubscribeServiceCallsRequest, + 35: pb.ServiceCallResponse, + 36: pb.GetTimeRequest, + 37: pb.GetTimeResponse, + 38: pb.SubscribeHomeAssistantStatesRequest, + 39: pb.SubscribeHomeAssistantStateResponse, + 40: pb.HomeAssistantStateResponse, + 41: pb.ListEntitiesServicesResponse, + 42: pb.ExecuteServiceRequest, + 43: pb.ListEntitiesCameraResponse, + 44: pb.CameraImageResponse, + 45: pb.CameraImageRequest, + 46: pb.ListEntitiesClimateResponse, + 47: pb.ClimateStateResponse, + 48: pb.ClimateCommandRequest, +} diff --git a/aioesphomeapi/model.py b/aioesphomeapi/model.py new file mode 100644 index 0000000..2d3f111 --- /dev/null +++ b/aioesphomeapi/model.py @@ -0,0 +1,273 @@ +import enum +from typing import List, Dict + +import attr + + +@attr.s(cmp=True) +class APIVersion: + major = attr.ib(type=int) + minor = attr.ib(type=int) + + +@attr.s +class DeviceInfo: + uses_password = attr.ib(type=bool) + name = attr.ib(type=str) + mac_address = attr.ib(type=str) + esphome_core_version = attr.ib(type=str) + compilation_time = attr.ib(type=str) + model = attr.ib(type=str) + has_deep_sleep = attr.ib(type=bool) + + +@attr.s +class EntityInfo: + object_id = attr.ib(type=str) + key = attr.ib(type=int) + name = attr.ib(type=str) + unique_id = attr.ib(type=str) + + +@attr.s +class EntityState: + key = attr.ib(type=int) + + +# ==================== BINARY SENSOR ==================== +@attr.s +class BinarySensorInfo(EntityInfo): + device_class = attr.ib(type=str) + is_status_binary_sensor = attr.ib(type=bool) + + +@attr.s +class BinarySensorState(EntityState): + state = attr.ib(type=bool) + + +# ==================== COVER ==================== +@attr.s +class CoverInfo(EntityInfo): + assumed_state = attr.ib(type=bool) + supports_position = attr.ib(type=bool) + supports_tilt = attr.ib(type=bool) + device_class = attr.ib(type=str) + + +class LegacyCoverState(enum.IntEnum): + OPEN = 0 + CLOSED = 1 + + +class LegacyCoverCommand(enum.IntEnum): + OPEN = 0 + CLOSE = 1 + STOP = 2 + + +class CoverOperation(enum.IntEnum): + IDLE = 0 + IS_OPENING = 1 + IS_CLOSING = 2 + + +@attr.s +class CoverState(EntityState): + legacy_state = attr.ib(type=LegacyCoverState, converter=LegacyCoverState) + position = attr.ib(type=float) + tilt = attr.ib(type=float) + current_operation = attr.ib(type=CoverOperation, converter=CoverOperation) + + def is_closed(self, api_version: APIVersion): + if api_version >= APIVersion(1, 1): + return self.position == 0.0 + return self.legacy_state == LegacyCoverState.CLOSED + + +# ==================== FAN ==================== +@attr.s +class FanInfo(EntityInfo): + supports_oscillation = attr.ib(type=bool) + supports_speed = attr.ib(type=bool) + + +class FanSpeed(enum.IntEnum): + LOW = 0 + MEDIUM = 1 + HIGH = 2 + + +@attr.s +class FanState(EntityState): + state = attr.ib(type=bool) + oscillating = attr.ib(type=bool) + speed = attr.ib(type=FanSpeed, converter=FanSpeed) + + +# ==================== LIGHT ==================== +@attr.s +class LightInfo(EntityInfo): + supports_brightness = attr.ib(type=bool) + supports_rgb = attr.ib(type=bool) + supports_white_value = attr.ib(type=bool) + supports_color_temperature = attr.ib(type=bool) + min_mireds = attr.ib(type=float) + max_mireds = attr.ib(type=float) + effects = attr.ib(type=List[str], converter=list) + + +@attr.s +class LightState(EntityState): + state = attr.ib(type=bool) + brightness = attr.ib(type=float) + red = attr.ib(type=float) + green = attr.ib(type=float) + blue = attr.ib(type=float) + white = attr.ib(type=float) + color_temperature = attr.ib(type=float) + effect = attr.ib(type=str) + + +# ==================== SENSOR ==================== +@attr.s +class SensorInfo(EntityInfo): + icon = attr.ib(type=str) + unit_of_measurement = attr.ib(type=str) + accuracy_decimals = attr.ib(type=int) + + +@attr.s +class SensorState(EntityState): + state = attr.ib(type=float) + + +# ==================== SWITCH ==================== +@attr.s +class SwitchInfo(EntityInfo): + icon = attr.ib(type=str) + assumed_state = attr.ib(type=bool) + + +@attr.s +class SwitchState(EntityState): + state = attr.ib(type=bool) + + +# ==================== TEXT SENSOR ==================== +@attr.s +class TextSensorInfo(EntityInfo): + icon = attr.ib(type=str) + + +@attr.s +class TextSensorState(EntityState): + state = attr.ib(type=str) + + +# ==================== CAMERA ==================== +@attr.s +class CameraInfo(EntityInfo): + pass + + +@attr.s +class CameraState(EntityState): + image = attr.ib(type=bytes) + + +# ==================== CLIMATE ==================== +class ClimateMode(enum.IntEnum): + OFF = 0 + AUTO = 1 + COOL = 2 + HEAT = 3 + + +def _convert_climate_modes(value): + return [ClimateMode(val) for val in value] + + +@attr.s +class ClimateInfo(EntityInfo): + supports_current_temperature = attr.ib(type=bool) + supports_two_point_target_temperature = attr.ib(type=bool) + supported_modes = attr.ib(type=List[ClimateMode], converter=_convert_climate_modes) + visual_min_temperature = attr.ib(type=float) + visual_max_temperature = attr.ib(type=float) + visual_temperature_step = attr.ib(type=float) + supports_away = attr.ib(type=bool) + + +@attr.s +class ClimateState(EntityState): + mode = attr.ib(type=ClimateMode, converter=ClimateMode) + current_temperature = attr.ib(type=float) + target_temperature = attr.ib(type=float) + target_temperature_low = attr.ib(type=float) + target_temperature_high = attr.ib(type=float) + away = attr.ib(type=bool) + + +COMPONENT_TYPE_TO_INFO = { + 'binary_sensor': BinarySensorInfo, + 'cover': CoverInfo, + 'fan': FanInfo, + 'light': LightInfo, + 'sensor': SensorInfo, + 'switch': SwitchInfo, + 'text_sensor': TextSensorInfo, + 'camera': CameraInfo, + 'climate': ClimateInfo, +} + + +# ==================== USER-DEFINED SERVICES ==================== +@attr.s +class ServiceCall: + service = attr.ib(type=str) + data = attr.ib(type=Dict[str, str], converter=dict) + data_template = attr.ib(type=Dict[str, str], converter=dict) + variables = attr.ib(type=Dict[str, str], converter=dict) + + +class UserServiceArgType(enum.IntEnum): + BOOL = 0 + INT = 1 + FLOAT = 2 + STRING = 3 + + +def _attr_obj_from_dict(cls, **kwargs): + return cls(**{key: kwargs[key] for key in attr.fields_dict(cls)}) + + +@attr.s +class UserServiceArg: + name = attr.ib(type=str) + type_ = attr.ib(type=UserServiceArgType, converter=UserServiceArgType) + + +@attr.s +class UserService: + name = attr.ib(type=str) + key = attr.ib(type=int) + args = attr.ib(type=List[UserServiceArg], converter=list) + + @staticmethod + def from_dict(dict_): + args = [] + for arg in dict_.get('args', []): + args.append(_attr_obj_from_dict(UserServiceArg, **arg)) + return UserService( + name=dict_.get('name', ''), + key=dict_.get('key', 0), + args=args + ) + + def to_dict(self): + return { + 'name': self.name, + 'key': self.key, + 'args': [attr.asdict(arg) for arg in self.args], + } diff --git a/aioesphomeapi/util.py b/aioesphomeapi/util.py new file mode 100644 index 0000000..43eb82b --- /dev/null +++ b/aioesphomeapi/util.py @@ -0,0 +1,60 @@ +import asyncio +import socket +from typing import Optional, Tuple, Any + +from aioesphomeapi.core import APIConnectionError + + +def _varuint_to_bytes(value: int) -> bytes: + if value <= 0x7F: + return bytes([value]) + + ret = bytes() + while value: + temp = value & 0x7F + value >>= 7 + if value: + ret += bytes([temp | 0x80]) + else: + ret += bytes([temp]) + + return ret + + +def _bytes_to_varuint(value: bytes) -> Optional[int]: + result = 0 + bitpos = 0 + for val in value: + result |= (val & 0x7F) << bitpos + bitpos += 7 + if (val & 0x80) == 0: + return result + return None + + +async def resolve_ip_address_getaddrinfo(eventloop: asyncio.events.AbstractEventLoop, + host: str, port: int) -> Tuple[Any, ...]: + try: + res = await eventloop.getaddrinfo(host, port, family=socket.AF_INET, + proto=socket.IPPROTO_TCP) + except OSError as err: + raise APIConnectionError("Error resolving IP address: {}".format(err)) + + if not res: + raise APIConnectionError("Error resolving IP address: No matches!") + + _, _, _, _, sockaddr = res[0] + + return sockaddr + + +async def resolve_ip_address(eventloop: asyncio.events.AbstractEventLoop, + host: str, port: int) -> Tuple[Any, ...]: + try: + return await resolve_ip_address_getaddrinfo(eventloop, host, port) + except APIConnectionError as err: + if host.endswith('.local'): + from aioesphomeapi.host_resolver import resolve_host + + return await eventloop.run_in_executor(None, resolve_host, host), port + raise err