This commit is contained in:
Otto Winter 2018-12-16 18:03:03 +01:00
parent f8ec2684cb
commit 632b002b09
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
4 changed files with 505 additions and 44 deletions

View File

@ -0,0 +1 @@
from .client import *

View File

@ -162,6 +162,7 @@ message ListEntitiesSwitchResponse {
string unique_id = 4; string unique_id = 4;
string icon = 5; string icon = 5;
bool optimistic = 6;
} }
message ListEntitiesTextSensorResponse { message ListEntitiesTextSensorResponse {
string object_id = 1; string object_id = 1;
@ -289,3 +290,32 @@ message SubscribeLogsResponse {
string tag = 2; string tag = 2;
string message = 3; string message = 3;
} }
message SubscribeServiceCallsRequest {
}
message ServiceCallResponse {
string service = 1;
map<string, string> data = 2;
map<string, string> data_template = 3;
map<string, string> variables = 4;
}
message SubscribeHomeAssistantStateRequest {
string entity_id = 1;
}
message SubscribeHomeAssistantStateResponse {
string entity_id = 1;
string state = 2;
}
message GetTimeRequest {
}
message GetTimeResponse {
fixed32 epoch_seconds = 1;
}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,8 @@
import asyncio import asyncio
import logging import logging
import socket import socket
from typing import Any, Callable, List, Optional, Tuple, Union, cast import time
from typing import Any, Callable, List, Optional, Tuple, Union, cast, Dict
import attr import attr
from google.protobuf import message from google.protobuf import message
@ -49,6 +50,10 @@ MESSAGE_TYPE_TO_PROTO = {
31: pb.FanCommandRequest, 31: pb.FanCommandRequest,
32: pb.LightCommandRequest, 32: pb.LightCommandRequest,
33: pb.SwitchCommandRequest, 33: pb.SwitchCommandRequest,
34: pb.SubscribeServiceCallsRequest,
35: pb.ServiceCallResponse,
36: pb.GetTimeRequest,
37: pb.GetTimeResponse,
} }
@ -210,6 +215,7 @@ class SensorState(EntityState):
@attr.s @attr.s
class SwitchInfo(EntityInfo): class SwitchInfo(EntityInfo):
icon = attr.ib(type=str) icon = attr.ib(type=str)
optimistic = attr.ib(type=bool)
@attr.s @attr.s
@ -238,6 +244,14 @@ COMPONENT_TYPE_TO_INFO = {
} }
@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 APIClient: class APIClient:
def __init__(self, eventloop, address: str, port: int, password: str): def __init__(self, eventloop, address: str, port: int, password: str):
self._eventloop = eventloop # type: asyncio.events.AbstractEventLoop self._eventloop = eventloop # type: asyncio.events.AbstractEventLoop
@ -298,7 +312,7 @@ class APIClient:
self._ping_timer.cancel() self._ping_timer.cancel()
self._ping_timer = None self._ping_timer = None
async def start(self): async def start(self) -> None:
self._eventloop.create_task(self.run_forever()) self._eventloop.create_task(self.run_forever())
await self.running_event.wait() await self.running_event.wait()
@ -565,6 +579,19 @@ class APIClient:
req.level = log_level req.level = log_level
await self._send_message(req) await self._send_message(req)
async def subscribe_service_calls(self, on_service_call: Callable[[ServiceCall], None]) -> None:
self._check_authenticated()
def on_msg(msg):
if isinstance(msg, pb.ServiceCallResponse):
kwargs = {}
for key, _ in attr.fields_dict(ServiceCall).items():
kwargs[key] = getattr(msg, key)
on_service_call(ServiceCall(**kwargs))
self._message_handlers.append(on_msg)
await self._send_message(pb.SubscribeServiceCallsRequest())
async def cover_command(self, async def cover_command(self,
key: int, key: int,
command: int command: int
@ -720,3 +747,7 @@ class APIClient:
await self.on_disconnect() await self.on_disconnect()
elif isinstance(msg, pb.PingRequest): elif isinstance(msg, pb.PingRequest):
await self._send_message(pb.PingResponse()) 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)