mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Fix LCN service calls (invoking coroutines) (#43932)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
84973ec8f7
commit
fec623fb4e
@ -117,7 +117,7 @@ async def async_setup(hass, config):
|
|||||||
("pck", Pck),
|
("pck", Pck),
|
||||||
):
|
):
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN, service_name, service(hass), service.schema
|
DOMAIN, service_name, service(hass).async_call_service, service.schema
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Service calls related dependencies for LCN component."""
|
"""Service calls related dependencies for LCN component."""
|
||||||
|
|
||||||
import pypck
|
import pypck
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
@ -54,11 +55,12 @@ class LcnServiceCall:
|
|||||||
|
|
||||||
def __init__(self, hass):
|
def __init__(self, hass):
|
||||||
"""Initialize service call."""
|
"""Initialize service call."""
|
||||||
|
self.hass = hass
|
||||||
self.connections = hass.data[DATA_LCN][CONF_CONNECTIONS]
|
self.connections = hass.data[DATA_LCN][CONF_CONNECTIONS]
|
||||||
|
|
||||||
def get_address_connection(self, call):
|
def get_device_connection(self, service):
|
||||||
"""Get address connection object."""
|
"""Get device connection object."""
|
||||||
addr, connection_id = call.data[CONF_ADDRESS]
|
addr, connection_id = service.data[CONF_ADDRESS]
|
||||||
addr = pypck.lcn_addr.LcnAddr(*addr)
|
addr = pypck.lcn_addr.LcnAddr(*addr)
|
||||||
if connection_id is None:
|
if connection_id is None:
|
||||||
connection = self.connections[0]
|
connection = self.connections[0]
|
||||||
@ -67,6 +69,10 @@ class LcnServiceCall:
|
|||||||
|
|
||||||
return connection.get_address_conn(addr)
|
return connection.get_address_conn(addr)
|
||||||
|
|
||||||
|
async def async_call_service(self, service):
|
||||||
|
"""Execute service call."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class OutputAbs(LcnServiceCall):
|
class OutputAbs(LcnServiceCall):
|
||||||
"""Set absolute brightness of output port in percent."""
|
"""Set absolute brightness of output port in percent."""
|
||||||
@ -83,16 +89,16 @@ class OutputAbs(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
output = pypck.lcn_defs.OutputPort[call.data[CONF_OUTPUT]]
|
output = pypck.lcn_defs.OutputPort[service.data[CONF_OUTPUT]]
|
||||||
brightness = call.data[CONF_BRIGHTNESS]
|
brightness = service.data[CONF_BRIGHTNESS]
|
||||||
transition = pypck.lcn_defs.time_to_ramp_value(
|
transition = pypck.lcn_defs.time_to_ramp_value(
|
||||||
call.data[CONF_TRANSITION] * 1000
|
service.data[CONF_TRANSITION] * 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.dim_output(output.value, brightness, transition)
|
await device_connection.dim_output(output.value, brightness, transition)
|
||||||
|
|
||||||
|
|
||||||
class OutputRel(LcnServiceCall):
|
class OutputRel(LcnServiceCall):
|
||||||
@ -107,13 +113,13 @@ class OutputRel(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
output = pypck.lcn_defs.OutputPort[call.data[CONF_OUTPUT]]
|
output = pypck.lcn_defs.OutputPort[service.data[CONF_OUTPUT]]
|
||||||
brightness = call.data[CONF_BRIGHTNESS]
|
brightness = service.data[CONF_BRIGHTNESS]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.rel_output(output.value, brightness)
|
await device_connection.rel_output(output.value, brightness)
|
||||||
|
|
||||||
|
|
||||||
class OutputToggle(LcnServiceCall):
|
class OutputToggle(LcnServiceCall):
|
||||||
@ -128,15 +134,15 @@ class OutputToggle(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
output = pypck.lcn_defs.OutputPort[call.data[CONF_OUTPUT]]
|
output = pypck.lcn_defs.OutputPort[service.data[CONF_OUTPUT]]
|
||||||
transition = pypck.lcn_defs.time_to_ramp_value(
|
transition = pypck.lcn_defs.time_to_ramp_value(
|
||||||
call.data[CONF_TRANSITION] * 1000
|
service.data[CONF_TRANSITION] * 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.toggle_output(output.value, transition)
|
await device_connection.toggle_output(output.value, transition)
|
||||||
|
|
||||||
|
|
||||||
class Relays(LcnServiceCall):
|
class Relays(LcnServiceCall):
|
||||||
@ -146,14 +152,15 @@ class Relays(LcnServiceCall):
|
|||||||
{vol.Required(CONF_STATE): is_relays_states_string}
|
{vol.Required(CONF_STATE): is_relays_states_string}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
states = [
|
states = [
|
||||||
pypck.lcn_defs.RelayStateModifier[state] for state in call.data[CONF_STATE]
|
pypck.lcn_defs.RelayStateModifier[state]
|
||||||
|
for state in service.data[CONF_STATE]
|
||||||
]
|
]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.control_relays(states)
|
await device_connection.control_relays(states)
|
||||||
|
|
||||||
|
|
||||||
class Led(LcnServiceCall):
|
class Led(LcnServiceCall):
|
||||||
@ -166,13 +173,13 @@ class Led(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
led = pypck.lcn_defs.LedPort[call.data[CONF_LED]]
|
led = pypck.lcn_defs.LedPort[service.data[CONF_LED]]
|
||||||
led_state = pypck.lcn_defs.LedStatus[call.data[CONF_STATE]]
|
led_state = pypck.lcn_defs.LedStatus[service.data[CONF_STATE]]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.control_led(led, led_state)
|
await device_connection.control_led(led, led_state)
|
||||||
|
|
||||||
|
|
||||||
class VarAbs(LcnServiceCall):
|
class VarAbs(LcnServiceCall):
|
||||||
@ -194,14 +201,14 @@ class VarAbs(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
var = pypck.lcn_defs.Var[call.data[CONF_VARIABLE]]
|
var = pypck.lcn_defs.Var[service.data[CONF_VARIABLE]]
|
||||||
value = call.data[CONF_VALUE]
|
value = service.data[CONF_VALUE]
|
||||||
unit = pypck.lcn_defs.VarUnit.parse(call.data[CONF_UNIT_OF_MEASUREMENT])
|
unit = pypck.lcn_defs.VarUnit.parse(service.data[CONF_UNIT_OF_MEASUREMENT])
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.var_abs(var, value, unit)
|
await device_connection.var_abs(var, value, unit)
|
||||||
|
|
||||||
|
|
||||||
class VarReset(LcnServiceCall):
|
class VarReset(LcnServiceCall):
|
||||||
@ -211,12 +218,12 @@ class VarReset(LcnServiceCall):
|
|||||||
{vol.Required(CONF_VARIABLE): vol.All(vol.Upper, vol.In(VARIABLES + SETPOINTS))}
|
{vol.Required(CONF_VARIABLE): vol.All(vol.Upper, vol.In(VARIABLES + SETPOINTS))}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
var = pypck.lcn_defs.Var[call.data[CONF_VARIABLE]]
|
var = pypck.lcn_defs.Var[service.data[CONF_VARIABLE]]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.var_reset(var)
|
await device_connection.var_reset(var)
|
||||||
|
|
||||||
|
|
||||||
class VarRel(LcnServiceCall):
|
class VarRel(LcnServiceCall):
|
||||||
@ -237,15 +244,15 @@ class VarRel(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
var = pypck.lcn_defs.Var[call.data[CONF_VARIABLE]]
|
var = pypck.lcn_defs.Var[service.data[CONF_VARIABLE]]
|
||||||
value = call.data[CONF_VALUE]
|
value = service.data[CONF_VALUE]
|
||||||
unit = pypck.lcn_defs.VarUnit.parse(call.data[CONF_UNIT_OF_MEASUREMENT])
|
unit = pypck.lcn_defs.VarUnit.parse(service.data[CONF_UNIT_OF_MEASUREMENT])
|
||||||
value_ref = pypck.lcn_defs.RelVarRef[call.data[CONF_RELVARREF]]
|
value_ref = pypck.lcn_defs.RelVarRef[service.data[CONF_RELVARREF]]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.var_rel(var, value, unit, value_ref)
|
await device_connection.var_rel(var, value, unit, value_ref)
|
||||||
|
|
||||||
|
|
||||||
class LockRegulator(LcnServiceCall):
|
class LockRegulator(LcnServiceCall):
|
||||||
@ -258,14 +265,14 @@ class LockRegulator(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
setpoint = pypck.lcn_defs.Var[call.data[CONF_SETPOINT]]
|
setpoint = pypck.lcn_defs.Var[service.data[CONF_SETPOINT]]
|
||||||
state = call.data[CONF_STATE]
|
state = service.data[CONF_STATE]
|
||||||
|
|
||||||
reg_id = pypck.lcn_defs.Var.to_set_point_id(setpoint)
|
reg_id = pypck.lcn_defs.Var.to_set_point_id(setpoint)
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.lock_regulator(reg_id, state)
|
await device_connection.lock_regulator(reg_id, state)
|
||||||
|
|
||||||
|
|
||||||
class SendKeys(LcnServiceCall):
|
class SendKeys(LcnServiceCall):
|
||||||
@ -286,31 +293,31 @@ class SendKeys(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
|
|
||||||
keys = [[False] * 8 for i in range(4)]
|
keys = [[False] * 8 for i in range(4)]
|
||||||
|
|
||||||
key_strings = zip(call.data[CONF_KEYS][::2], call.data[CONF_KEYS][1::2])
|
key_strings = zip(service.data[CONF_KEYS][::2], service.data[CONF_KEYS][1::2])
|
||||||
|
|
||||||
for table, key in key_strings:
|
for table, key in key_strings:
|
||||||
table_id = ord(table) - 65
|
table_id = ord(table) - 65
|
||||||
key_id = int(key) - 1
|
key_id = int(key) - 1
|
||||||
keys[table_id][key_id] = True
|
keys[table_id][key_id] = True
|
||||||
|
|
||||||
delay_time = call.data[CONF_TIME]
|
delay_time = service.data[CONF_TIME]
|
||||||
if delay_time != 0:
|
if delay_time != 0:
|
||||||
hit = pypck.lcn_defs.SendKeyCommand.HIT
|
hit = pypck.lcn_defs.SendKeyCommand.HIT
|
||||||
if pypck.lcn_defs.SendKeyCommand[call.data[CONF_STATE]] != hit:
|
if pypck.lcn_defs.SendKeyCommand[service.data[CONF_STATE]] != hit:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Only hit command is allowed when sending deferred keys."
|
"Only hit command is allowed when sending deferred keys."
|
||||||
)
|
)
|
||||||
delay_unit = pypck.lcn_defs.TimeUnit.parse(call.data[CONF_TIME_UNIT])
|
delay_unit = pypck.lcn_defs.TimeUnit.parse(service.data[CONF_TIME_UNIT])
|
||||||
address_connection.send_keys_hit_deferred(keys, delay_time, delay_unit)
|
await device_connection.send_keys_hit_deferred(keys, delay_time, delay_unit)
|
||||||
else:
|
else:
|
||||||
state = pypck.lcn_defs.SendKeyCommand[call.data[CONF_STATE]]
|
state = pypck.lcn_defs.SendKeyCommand[service.data[CONF_STATE]]
|
||||||
address_connection.send_keys(keys, state)
|
await device_connection.send_keys(keys, state)
|
||||||
|
|
||||||
|
|
||||||
class LockKeys(LcnServiceCall):
|
class LockKeys(LcnServiceCall):
|
||||||
@ -329,28 +336,31 @@ class LockKeys(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
|
|
||||||
states = [
|
states = [
|
||||||
pypck.lcn_defs.KeyLockStateModifier[state]
|
pypck.lcn_defs.KeyLockStateModifier[state]
|
||||||
for state in call.data[CONF_STATE]
|
for state in service.data[CONF_STATE]
|
||||||
]
|
]
|
||||||
table_id = ord(call.data[CONF_TABLE]) - 65
|
table_id = ord(service.data[CONF_TABLE]) - 65
|
||||||
|
|
||||||
delay_time = call.data[CONF_TIME]
|
delay_time = service.data[CONF_TIME]
|
||||||
if delay_time != 0:
|
if delay_time != 0:
|
||||||
if table_id != 0:
|
if table_id != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Only table A is allowed when locking keys for a specific time."
|
"Only table A is allowed when locking keys for a specific time."
|
||||||
)
|
)
|
||||||
delay_unit = pypck.lcn_defs.TimeUnit.parse(call.data[CONF_TIME_UNIT])
|
delay_unit = pypck.lcn_defs.TimeUnit.parse(service.data[CONF_TIME_UNIT])
|
||||||
address_connection.lock_keys_tab_a_temporary(delay_time, delay_unit, states)
|
await device_connection.lock_keys_tab_a_temporary(
|
||||||
|
delay_time, delay_unit, states
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
address_connection.lock_keys(table_id, states)
|
await device_connection.lock_keys(table_id, states)
|
||||||
|
|
||||||
address_connection.request_status_locked_keys_timeout()
|
handler = device_connection.status_request_handler
|
||||||
|
await handler.request_status_locked_keys_timeout()
|
||||||
|
|
||||||
|
|
||||||
class DynText(LcnServiceCall):
|
class DynText(LcnServiceCall):
|
||||||
@ -363,13 +373,13 @@ class DynText(LcnServiceCall):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
row_id = call.data[CONF_ROW] - 1
|
row_id = service.data[CONF_ROW] - 1
|
||||||
text = call.data[CONF_TEXT]
|
text = service.data[CONF_TEXT]
|
||||||
|
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.dyn_text(row_id, text)
|
await device_connection.dyn_text(row_id, text)
|
||||||
|
|
||||||
|
|
||||||
class Pck(LcnServiceCall):
|
class Pck(LcnServiceCall):
|
||||||
@ -377,8 +387,8 @@ class Pck(LcnServiceCall):
|
|||||||
|
|
||||||
schema = LcnServiceCall.schema.extend({vol.Required(CONF_PCK): str})
|
schema = LcnServiceCall.schema.extend({vol.Required(CONF_PCK): str})
|
||||||
|
|
||||||
def __call__(self, call):
|
async def async_call_service(self, service):
|
||||||
"""Execute service call."""
|
"""Execute service call."""
|
||||||
pck = call.data[CONF_PCK]
|
pck = service.data[CONF_PCK]
|
||||||
address_connection = self.get_address_connection(call)
|
device_connection = self.get_device_connection(service)
|
||||||
address_connection.pck(pck)
|
await device_connection.pck(pck)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user