completed tilt control
This commit is contained in:
@@ -51,6 +51,9 @@ SHADE_TYPE: Final[dict[int, str]] = {
|
||||
9: "Duette DuoLite, Top Down Bottom Up",
|
||||
33: "Duette Architella, Top Down Bottom Up",
|
||||
47: "Pleated, Top Down Bottom Up",
|
||||
# top down, tilt anywhere
|
||||
51: "Venetian, Tilt Anywhere",
|
||||
62: "Venetian, Tilt Anywhere",
|
||||
}
|
||||
|
||||
OPEN_POSITION: Final[int] = 100
|
||||
@@ -203,21 +206,21 @@ class PowerViewBLE:
|
||||
async def set_position(
|
||||
self,
|
||||
pos1: int,
|
||||
pos2: int = 0x8000,
|
||||
pos3: int = 0x8000,
|
||||
tilt: int = 0x8000,
|
||||
pos2: int | None = None,
|
||||
pos3: int | None = None,
|
||||
tilt: int | None = None,
|
||||
velocity: int = 0x0,
|
||||
disconnect: bool = True,
|
||||
) -> None:
|
||||
"""Set position of device."""
|
||||
LOGGER.debug("%s setting position to %i", self.name, pos1)
|
||||
LOGGER.debug("%s setting position to %i, tilt %i", self.name, pos1, tilt)
|
||||
await self._cmd(
|
||||
(
|
||||
ShadeCmd.SET_POSITION,
|
||||
int.to_bytes(pos1 * 100, 2, byteorder="little")
|
||||
+ int.to_bytes(pos2 * 100, 2, byteorder="little")
|
||||
+ int.to_bytes(pos3 * 100, 2, byteorder="little")
|
||||
+ int.to_bytes(tilt * 100, 2, byteorder="little")
|
||||
int.to_bytes(pos1, 2, byteorder="little")
|
||||
+ int.to_bytes(pos2 if pos2 is not None else 0x8000, 2, byteorder="little")
|
||||
+ int.to_bytes(pos3 if pos3 is not None else 0x8000, 2, byteorder="little")
|
||||
+ int.to_bytes(tilt if tilt is not None else 0x8000, 2, byteorder="little")
|
||||
+ int.to_bytes(velocity, 1),
|
||||
),
|
||||
disconnect,
|
||||
@@ -299,6 +302,9 @@ class PowerViewBLE:
|
||||
.copy()
|
||||
.decode("UTF-8")
|
||||
)
|
||||
except BleakError as ex:
|
||||
LOGGER.debug("%s: querying failed: %s", ex)
|
||||
raise
|
||||
finally:
|
||||
await self.disconnect()
|
||||
LOGGER.debug("%s device data: %s", self.name, data)
|
||||
@@ -315,7 +321,11 @@ class PowerViewBLE:
|
||||
if self._cipher is not None and self._is_encrypted:
|
||||
dec: AEADDecryptionContext = self._cipher.decryptor()
|
||||
self._data = bytearray(dec.update(data) + dec.finalize())
|
||||
LOGGER.debug("%s %s", "decoded data: ".rjust(19+len(self.name)), self._data.hex(" "))
|
||||
LOGGER.debug(
|
||||
"%s %s",
|
||||
"decoded data: ".rjust(19 + len(self.name)),
|
||||
self._data.hex(" "),
|
||||
)
|
||||
|
||||
self._data_event.set()
|
||||
|
||||
|
||||
@@ -33,7 +33,11 @@ async def async_setup_entry(
|
||||
"""Set up the demo cover platform."""
|
||||
|
||||
coordinator: PVCoordinator = config_entry.runtime_data
|
||||
async_add_entities([PowerViewCover(coordinator)])
|
||||
async_add_entities(
|
||||
[PowerViewCoverTilt(coordinator)]
|
||||
if coordinator.dev_details.get("model") in ["51", "62"]
|
||||
else [PowerViewCover(coordinator)]
|
||||
)
|
||||
|
||||
|
||||
class PowerViewCover(PassiveBluetoothCoordinatorEntity[PVCoordinator], CoverEntity): # type: ignore[reportIncompatibleVariableOverride]
|
||||
@@ -53,8 +57,9 @@ class PowerViewCover(PassiveBluetoothCoordinatorEntity[PVCoordinator], CoverEnti
|
||||
coordinator: PVCoordinator,
|
||||
) -> None:
|
||||
"""Initialize the shade."""
|
||||
LOGGER.debug("%s: init() PowerViewCover", coordinator.name)
|
||||
self._attr_name = CoverDeviceClass.SHADE
|
||||
self._coord = coordinator
|
||||
self._coord: PVCoordinator = coordinator
|
||||
self._attr_device_info = self._coord.device_info
|
||||
self._target_position: int | None = round(
|
||||
self._coord.data.get(ATTR_CURRENT_POSITION, OPEN_POSITION)
|
||||
@@ -187,6 +192,13 @@ class PowerViewCoverTilt(PowerViewCover):
|
||||
# | CoverEntityFeature.OPEN_TILT
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: PVCoordinator,
|
||||
) -> None:
|
||||
LOGGER.debug("%s: init() PowerViewCoverTilt", coordinator.name)
|
||||
super().__init__(coordinator)
|
||||
|
||||
@property
|
||||
def current_cover_tilt_position(self) -> int | None: # type: ignore[reportIncompatibleVariableOverride]
|
||||
"""Return current tilt of cover.
|
||||
|
||||
Reference in New Issue
Block a user