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 icon = 5;
bool optimistic = 6;
}
message ListEntitiesTextSensorResponse {
string object_id = 1;
@ -289,3 +290,32 @@ message SubscribeLogsResponse {
string tag = 2;
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 logging
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
from google.protobuf import message
@ -49,6 +50,10 @@ MESSAGE_TYPE_TO_PROTO = {
31: pb.FanCommandRequest,
32: pb.LightCommandRequest,
33: pb.SwitchCommandRequest,
34: pb.SubscribeServiceCallsRequest,
35: pb.ServiceCallResponse,
36: pb.GetTimeRequest,
37: pb.GetTimeResponse,
}
@ -210,6 +215,7 @@ class SensorState(EntityState):
@attr.s
class SwitchInfo(EntityInfo):
icon = attr.ib(type=str)
optimistic = attr.ib(type=bool)
@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:
def __init__(self, eventloop, address: str, port: int, password: str):
self._eventloop = eventloop # type: asyncio.events.AbstractEventLoop
@ -298,7 +312,7 @@ class APIClient:
self._ping_timer.cancel()
self._ping_timer = None
async def start(self):
async def start(self) -> None:
self._eventloop.create_task(self.run_forever())
await self.running_event.wait()
@ -565,6 +579,19 @@ class APIClient:
req.level = log_level
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,
key: int,
command: int
@ -720,3 +747,7 @@ class APIClient:
await self.on_disconnect()
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)