Skip to content

Commit

Permalink
Bump hahomematic to 2024.9.3 (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
SukramJ authored Sep 2, 2024
1 parent 5f8af40 commit f5676f4
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 23 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,19 @@ Returns a dict of link partners
Call to `getParamset` on the XML-RPC interface.
Returns a paramset

### `homematicip_local.get_link_paramset`

Call to `getParamset` for links on the XML-RPC interface.
Returns a paramset

### `homematicip_local.put_paramset`

Call to `putParamset` on the XML-RPC interface.

### `homematicip_local.put_link_paramset`

Call to `putParamset` for links on the XML-RPC interface.

### `homematicip_local.set_cover_combined_position`

Move a blind to a specific position and tilt position.
Expand Down
2 changes: 1 addition & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Version 1.66.0 (2024-09-01)

- Bump hahomematic to 2024.9.1
- Bump hahomematic to 2024.9.3
- Add check for link paramsets
- Add getLinkPeers XmlRPC method
- Add paramset_key to entity_key
Expand Down
6 changes: 5 additions & 1 deletion custom_components/homematicip_local/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@
SERVICE_FETCH_SYSTEM_VARIABLES: Final = "fetch_system_variables"
SERVICE_FORCE_DEVICE_AVAILABILITY: Final = "force_device_availability"
SERVICE_GET_DEVICE_VALUE: Final = "get_device_value"
SERVICE_GET_LINK_PARAMSET: Final = "get_link_paramset"
SERVICE_GET_LINK_PEERS: Final = "get_link_peers"
SERVICE_GET_PARAMSET: Final = "get_paramset"
SERVICE_LIGHT_SET_ON_TIME: Final = "light_set_on_time"
SERVICE_PUT_LINK_PARAMSET: Final = "put_link_paramset"
SERVICE_PUT_PARAMSET: Final = "put_paramset"
SERVICE_SET_COVER_COMBINED_POSITION: Final = "set_cover_combined_position"
SERVICE_SET_DEVICE_VALUE: Final = "set_device_value"
Expand All @@ -81,9 +83,11 @@
SERVICE_FETCH_SYSTEM_VARIABLES,
SERVICE_FORCE_DEVICE_AVAILABILITY,
SERVICE_GET_DEVICE_VALUE,
SERVICE_GET_LINK_PARAMSET,
SERVICE_GET_LINK_PEERS,
SERVICE_GET_PARAMSET,
SERVICE_LIGHT_SET_ON_TIME,
SERVICE_GET_LINK_PEERS,
SERVICE_PUT_LINK_PARAMSET,
SERVICE_PUT_PARAMSET,
SERVICE_SET_COVER_COMBINED_POSITION,
SERVICE_SET_DEVICE_VALUE,
Expand Down
2 changes: 1 addition & 1 deletion custom_components/homematicip_local/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"iot_class": "local_push",
"issue_tracker": "https://github.com/danielperna84/hahomematic/issues",
"loggers": ["hahomematic"],
"requirements": ["hahomematic==2024.9.1"],
"requirements": ["hahomematic==2024.9.3"],
"ssdp": [
{
"manufacturer": "EQ3",
Expand Down
119 changes: 105 additions & 14 deletions custom_components/homematicip_local/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from hahomematic.const import ForcedDeviceAvailability, ParamsetKey
from hahomematic.exceptions import ClientException
from hahomematic.platforms.device import HmDevice
from hahomematic.support import to_bool
from hahomematic.support import get_device_address, to_bool
import hahomematic.validator as hmval
import voluptuous as vol

from homeassistant.config_entries import ConfigEntryState
Expand All @@ -35,8 +36,10 @@
SERVICE_FETCH_SYSTEM_VARIABLES,
SERVICE_FORCE_DEVICE_AVAILABILITY,
SERVICE_GET_DEVICE_VALUE,
SERVICE_GET_LINK_PARAMSET,
SERVICE_GET_LINK_PEERS,
SERVICE_GET_PARAMSET,
SERVICE_PUT_LINK_PARAMSET,
SERVICE_PUT_PARAMSET,
SERVICE_SET_DEVICE_VALUE,
SERVICE_SET_INSTALL_MODE,
Expand All @@ -53,7 +56,7 @@

CONF_ADDRESS: Final = "address"
CONF_CHANNEL: Final = "channel"
CONF_TIME: Final = "time"
CONF_CHANNEL_ADDRESS: Final = "channel_address"
CONF_DEVICE_ADDRESS: Final = "device_address"
CONF_ENTRY_ID: Final = "entry_id"
CONF_INTERFACE_ID: Final = "interface_id"
Expand All @@ -62,6 +65,8 @@
CONF_PARAMSET: Final = "paramset"
CONF_PARAMSET_KEY: Final = "paramset_key"
CONF_RX_MODE: Final = "rx_mode"
CONF_SENDER_CHANNEL_ADDRESS: Final = "sender_channel_address"
CONF_TIME: Final = "time"
CONF_VALUE: Final = "value"
CONF_VALUE_TYPE: Final = "value_type"
CONF_WAIT_FOR_CALLBACK: Final = "wait_for_callback"
Expand All @@ -71,7 +76,7 @@
BASE_SCHEMA_DEVICE = vol.Schema(
{
vol.Optional(CONF_DEVICE_ID): cv.string,
vol.Optional(CONF_DEVICE_ADDRESS): cv.string,
vol.Optional(CONF_DEVICE_ADDRESS): hmval.device_address,
}
)

Expand Down Expand Up @@ -105,7 +110,7 @@
cv.has_at_most_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
BASE_SCHEMA_DEVICE.extend(
{
vol.Required(CONF_CHANNEL, default=DEFAULT_CHANNEL): vol.Coerce(int),
vol.Required(CONF_CHANNEL, default=DEFAULT_CHANNEL): hmval.channel_no,
vol.Required(CONF_PARAMETER): vol.All(cv.string, vol.Upper),
}
),
Expand All @@ -116,18 +121,25 @@
cv.has_at_most_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
BASE_SCHEMA_DEVICE.extend(
{
vol.Optional(CONF_CHANNEL): vol.Coerce(int),
vol.Optional(CONF_CHANNEL): hmval.channel_no,
}
),
)

SCHEMA_SERVICE_GET_LINK_PARAMSET = vol.All(
{
vol.Optional(CONF_CHANNEL_ADDRESS): hmval.channel_address,
vol.Optional(CONF_SENDER_CHANNEL_ADDRESS): hmval.channel_address,
}
)

SCHEMA_SERVICE_GET_PARAMSET = vol.All(
cv.has_at_least_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
cv.has_at_most_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
BASE_SCHEMA_DEVICE.extend(
{
vol.Optional(CONF_CHANNEL): vol.Coerce(int),
vol.Required(CONF_PARAMSET_KEY): vol.All(cv.string, vol.Upper),
vol.Optional(CONF_CHANNEL): hmval.channel_no,
vol.Required(CONF_PARAMSET_KEY): vol.In(["MASTER", "VALUES"]),
}
),
)
Expand All @@ -145,7 +157,7 @@
vol.Required(CONF_INTERFACE_ID): cv.string,
vol.Optional(CONF_TIME, default=60): cv.positive_int,
vol.Optional(CONF_MODE, default=1): vol.All(vol.Coerce(int), vol.In([1, 2])),
vol.Optional(CONF_ADDRESS): vol.All(cv.string, vol.Upper),
vol.Optional(CONF_ADDRESS): hmval.device_address,
}
)

Expand All @@ -154,10 +166,10 @@
cv.has_at_most_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
BASE_SCHEMA_DEVICE.extend(
{
vol.Required(CONF_CHANNEL, default=DEFAULT_CHANNEL): vol.Coerce(int),
vol.Required(CONF_CHANNEL, default=DEFAULT_CHANNEL): hmval.channel_no,
vol.Required(CONF_PARAMETER): vol.All(cv.string, vol.Upper),
vol.Required(CONF_VALUE): cv.match_all,
vol.Optional(CONF_WAIT_FOR_CALLBACK): cv.positive_int,
vol.Optional(CONF_WAIT_FOR_CALLBACK): hmval.wait_for,
vol.Optional(CONF_VALUE_TYPE): vol.In(
["boolean", "dateTime.iso8601", "double", "int", "string"]
),
Expand All @@ -166,15 +178,24 @@
),
)

SCHEMA_SERVICE_PUT_LINK_PARAMSET = vol.All(
{
vol.Optional(CONF_CHANNEL_ADDRESS): hmval.channel_address,
vol.Optional(CONF_SENDER_CHANNEL_ADDRESS): hmval.channel_address,
vol.Required(CONF_PARAMSET): dict,
vol.Optional(CONF_RX_MODE): vol.All(cv.string, vol.Upper),
}
)

SCHEMA_SERVICE_PUT_PARAMSET = vol.All(
cv.has_at_least_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
cv.has_at_most_one_key(CONF_DEVICE_ID, CONF_DEVICE_ADDRESS),
BASE_SCHEMA_DEVICE.extend(
{
vol.Optional(CONF_CHANNEL): vol.Coerce(int),
vol.Required(CONF_PARAMSET_KEY): vol.All(cv.string, vol.Upper),
vol.Optional(CONF_CHANNEL): hmval.channel_no,
vol.Required(CONF_PARAMSET_KEY): vol.In(["MASTER", "VALUES"]),
vol.Required(CONF_PARAMSET): dict,
vol.Optional(CONF_WAIT_FOR_CALLBACK): cv.positive_int,
vol.Optional(CONF_WAIT_FOR_CALLBACK): hmval.wait_for,
vol.Optional(CONF_RX_MODE): vol.All(cv.string, vol.Upper),
}
),
Expand Down Expand Up @@ -207,8 +228,12 @@ async def async_call_hmip_local_service(service: ServiceCall) -> ServiceResponse
return await _async_service_get_device_value(hass=hass, service=service)
elif service_name == SERVICE_GET_LINK_PEERS:
return await _async_service_get_link_peers(hass=hass, service=service)
elif service_name == SERVICE_GET_LINK_PARAMSET:
return await _async_service_get_link_paramset(hass=hass, service=service)
elif service_name == SERVICE_GET_PARAMSET:
return await _async_service_get_paramset(hass=hass, service=service)
elif service_name == SERVICE_PUT_LINK_PARAMSET:
await _async_service_put_link_paramset(hass=hass, service=service)
elif service_name == SERVICE_PUT_PARAMSET:
await _async_service_put_paramset(hass=hass, service=service)
elif service_name == SERVICE_SET_INSTALL_MODE:
Expand Down Expand Up @@ -269,6 +294,14 @@ async def async_call_hmip_local_service(service: ServiceCall) -> ServiceResponse
supports_response=SupportsResponse.OPTIONAL,
)

hass.services.async_register(
domain=DOMAIN,
service=SERVICE_GET_LINK_PARAMSET,
service_func=async_call_hmip_local_service,
schema=SCHEMA_SERVICE_GET_LINK_PARAMSET,
supports_response=SupportsResponse.OPTIONAL,
)

hass.services.async_register(
domain=DOMAIN,
service=SERVICE_GET_PARAMSET,
Expand Down Expand Up @@ -299,6 +332,13 @@ async def async_call_hmip_local_service(service: ServiceCall) -> ServiceResponse
schema=SCHEMA_SERVICE_SET_INSTALL_MODE,
)

hass.services.async_register(
domain=DOMAIN,
service=SERVICE_PUT_LINK_PARAMSET,
service_func=async_call_hmip_local_service,
schema=SCHEMA_SERVICE_PUT_LINK_PARAMSET,
)

hass.services.async_register(
domain=DOMAIN,
service=SERVICE_PUT_PARAMSET,
Expand Down Expand Up @@ -395,12 +435,33 @@ async def _async_service_get_link_peers(
return None


async def _async_service_get_link_paramset(
hass: HomeAssistant, service: ServiceCall
) -> ServiceResponse:
"""Service to call the getParamset method for links on a Homematic(IP) Local connection."""
channel_address = service.data[CONF_CHANNEL_ADDRESS]
sender_channel_address = service.data[CONF_SENDER_CHANNEL_ADDRESS]

if hm_device := _async_get_hm_device_by_service_data(hass=hass, service=service):
try:
return dict(
await hm_device.client.get_paramset(
address=channel_address,
paramset_key=sender_channel_address,
)
)
except ClientException as cex:
raise HomeAssistantError(cex) from cex

return None


async def _async_service_get_paramset(
hass: HomeAssistant, service: ServiceCall
) -> ServiceResponse:
"""Service to call the getParamset method on a Homematic(IP) Local connection."""
channel_no = service.data.get(CONF_CHANNEL)
paramset_key = ParamsetKey(service.data[CONF_PARAMSET_KEY])
paramset_key = service.data[CONF_PARAMSET_KEY]

if hm_device := _async_get_hm_device_by_service_data(hass=hass, service=service):
address = (
Expand Down Expand Up @@ -493,6 +554,25 @@ async def _async_service_fetch_system_variables(hass: HomeAssistant, service: Se
await control.fetch_all_system_variables()


async def _async_service_put_link_paramset(hass: HomeAssistant, service: ServiceCall) -> None:
"""Service to call the putParamset method for link manipulation on a Homematic(IP) Local connection."""
channel_address = service.data[CONF_CHANNEL_ADDRESS]
sender_channel_address = service.data[CONF_SENDER_CHANNEL_ADDRESS]
# When passing in the paramset from a YAML file we get an OrderedDict
# here instead of a dict, so add this explicit cast.
# The service schema makes sure that this cast works.
values = dict(service.data[CONF_PARAMSET])
rx_mode = service.data.get(CONF_RX_MODE)

if hm_device := _async_get_hm_device_by_service_data(hass=hass, service=service):
await hm_device.client.put_paramset(
channel_address=channel_address,
paramset_key=sender_channel_address,
values=values,
rx_mode=rx_mode,
)


async def _async_service_put_paramset(hass: HomeAssistant, service: ServiceCall) -> None:
"""Service to call the putParamset method on a Homematic(IP) Local connection."""
channel_no = service.data.get(CONF_CHANNEL)
Expand Down Expand Up @@ -564,6 +644,17 @@ def _async_get_hm_device_by_service_data(
service.domain,
service.service,
)
elif channel_address := service.data.get(CONF_CHANNEL_ADDRESS):
hm_device = _async_get_hm_device_by_address(
hass=hass, device_address=get_device_address(address=channel_address)
)
if not hm_device:
_LOGGER.warning(
"No device found by channel_address %s for service %s.%s",
device_address,
service.domain,
service.service,
)

return hm_device

Expand Down
39 changes: 39 additions & 0 deletions custom_components/homematicip_local/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ get_link_peers:
min: 0
max: 99

get_link_paramset:
fields:
channel_address:
example: "0008789453:3"
required: true
selector:
text:
sender_channel_address:
example: "0008789453:3"
required: true
selector:
text:

get_paramset:
fields:
device_id:
Expand All @@ -106,6 +119,7 @@ get_paramset:
options:
- "MASTER"
- "VALUES"

set_variable_value:
fields:
entry_id:
Expand Down Expand Up @@ -200,6 +214,31 @@ set_install_mode:
selector:
text:

put_link_paramset:
fields:
channel_address:
example: "0008789453:3"
required: true
selector:
text:
sender_channel_address:
example: "0008789453:3"
required: true
selector:
text:
paramset:
required: true
example: '{"WEEK_PROGRAM_POINTER": 1}'
selector:
object:
rx_mode:
example: BURST
selector:
select:
options:
- "BURST"
- "WAKEUP"

put_paramset:
fields:
device_id:
Expand Down
Loading

0 comments on commit f5676f4

Please sign in to comment.