Skip to content

Commit

Permalink
Merge pull request #3 from lunDreame/dev
Browse files Browse the repository at this point in the history
Major Update
  • Loading branch information
lunDreame authored Dec 29, 2024
2 parents 593bfe4 + dbcf2ca commit 10e0d11
Show file tree
Hide file tree
Showing 21 changed files with 504 additions and 552 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)

# Kocom WallPad Integration for Home Assistant
Home Assistant를 위한 Kocom WallPad 통합구성요소
# Kocom Wallpad Integration for Home Assistant
Home Assistant를 위한 Kocom Wallpad 통합구성요소

## 기여
문제가 있나요? [Issues](https://github.com/lunDreame/kocom-wallpad/issues) 탭에 작성해 주세요.
Expand Down
44 changes: 8 additions & 36 deletions custom_components/kocom_wallpad/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from .pywallpad.const import STATE, ERROR_CODE, TIME
from .pywallpad.enums import DeviceType
from .pywallpad.packet import (
KocomPacket,
ThermostatPacket,
FanPacket,
MotionPacket
MotionPacket,
)

from .gateway import KocomGateway
Expand All @@ -37,12 +38,8 @@ async def async_setup_entry(
@callback
def async_add_binary_sensor(packet: KocomPacket) -> None:
"""Add new binary sensor entity."""
if isinstance(packet, (ThermostatPacket, FanPacket)):
if isinstance(packet, (ThermostatPacket, FanPacket, MotionPacket)):
async_add_entities([KocomBinarySensorEntity(gateway, packet)])
elif isinstance(packet, MotionPacket):
async_add_entities([KocomMotionEntity(gateway, packet)])
else:
LOGGER.warning(f"Unsupported packet type: {packet}")

for entity in gateway.get_entities(Platform.BINARY_SENSOR):
async_add_binary_sensor(entity)
Expand All @@ -64,40 +61,15 @@ def __init__(
) -> None:
"""Initialize the binary sensor."""
super().__init__(gateway, packet)
self._attr_is_on = self.device.state[STATE]
self._attr_extra_state_attributes = {
DEVICE_TYPE: self.device.device_type,
ROOM_ID: self.device.room_id,
SUB_ID: self.device.sub_id,
ERROR_CODE: self.device.state[ERROR_CODE],
}

@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return self.device.state[STATE]


class KocomMotionEntity(KocomEntity, BinarySensorEntity):
"""Representation of a Kocom binary sensor."""

_attr_device_class = BinarySensorDeviceClass.MOTION

def __init__(
self,
gateway: KocomGateway,
packet: KocomPacket,
) -> None:
"""Initialize the binary sensor."""
super().__init__(gateway, packet)
self._attr_extra_state_attributes = {
DEVICE_TYPE: self.device.device_type,
ROOM_ID: self.device.room_id,
SUB_ID: self.device.sub_id,
TIME: self.device.state[TIME],
}

@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return self.device.state[STATE]

if self.packet.device_type == DeviceType.MOTION:
self._attr_device_class = BinarySensorDeviceClass.MOTION
del self._attr_extra_state_attributes[ERROR_CODE]
self._attr_extra_state_attributes[TIME] = self.device.state[TIME]
222 changes: 99 additions & 123 deletions custom_components/kocom_wallpad/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ def async_add_climate(packet: KocomPacket) -> None:
async_add_entities([KocomThermostatEntity(gateway, packet)])
elif isinstance(packet, AcPacket):
async_add_entities([KocomAcEntity(gateway, packet)])
else:
LOGGER.warning(f"Unsupported packet type: {packet}")

for entity in gateway.get_entities(Platform.CLIMATE):
async_add_climate(entity)
Expand All @@ -62,45 +60,35 @@ def async_add_climate(packet: KocomPacket) -> None:


class KocomThermostatEntity(KocomEntity, ClimateEntity):
"""Representation of a Kocom climate."""
"""Representation of a Kocom thermostat."""

_enable_turn_on_off_backwards_compatibility = False
_attr_hvac_modes = [HVACMode.OFF, HVACMode.HEAT]
_attr_preset_modes = [PRESET_AWAY, PRESET_NONE]
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE |
ClimateEntityFeature.TURN_OFF |
ClimateEntityFeature.TURN_ON |
ClimateEntityFeature.PRESET_MODE
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_OFF
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.PRESET_MODE
)
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_max_temp = 40
_attr_min_temp = 5
_attr_target_temperature_step = 1

def __init__(
self,
gateway: KocomGateway,
packet: KocomPacket,
) -> None:
"""Initialize the climate."""

def __init__(self, gateway: KocomGateway, packet: KocomPacket) -> None:
"""Initialize the thermostat."""
super().__init__(gateway, packet)

@property
def hvac_mode(self) -> HVACMode:
"""Return hvac operation ie. heat, cool mode."""
if self.device.state[POWER]:
return HVACMode.HEAT
else:
return HVACMode.OFF

"""Return the current HVAC mode."""
return HVACMode.HEAT if self.device.state[POWER] else HVACMode.OFF

@property
def preset_mode(self) -> str:
"""Return the current preset mode, e.g., home, away, temp."""
if self.device.state[AWAY_MODE]:
return PRESET_AWAY
else:
return PRESET_NONE
"""Return the current preset mode."""
return PRESET_AWAY if self.device.state[AWAY_MODE] else PRESET_NONE

@property
def current_temperature(self) -> int:
Expand All @@ -109,42 +97,43 @@ def current_temperature(self) -> int:

@property
def target_temperature(self) -> int:
"""Return the temperature we try to reach."""
"""Return the target temperature."""
return self.device.state[TARGET_TEMP]

async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target hvac mode."""
if hvac_mode == HVACMode.OFF:
power = False
elif hvac_mode == HVACMode.HEAT:
power = True
else:
"""Set the HVAC mode."""
hvac_to_power = {
HVACMode.OFF: False,
HVACMode.HEAT: True,
}
power = hvac_to_power.get(hvac_mode)
if power is None:
raise ValueError(f"Unknown HVAC mode: {hvac_mode}")
packet = self.packet.make_status(power=power)
await self.send(packet)

make_packet = self.packet.make_power_status(power)
await self.send_packet(make_packet)

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new target preset mode."""
if preset_mode == PRESET_AWAY:
away_mode = True
elif preset_mode == PRESET_NONE:
away_mode = False
else:
"""Set the preset mode."""
preset_to_away = {
PRESET_AWAY: True,
PRESET_NONE: False,
}
away_mode = preset_to_away.get(preset_mode)
if away_mode is None:
raise ValueError(f"Unknown preset mode: {preset_mode}")
packet = self.packet.make_status(away_mode=away_mode)
await self.send(packet)

make_packet = self.packet.make_away_status(away_mode)
await self.send_packet(make_packet)

async def async_set_temperature(self, **kwargs) -> None:
"""Set new target temperature."""
target_temp = kwargs.get(ATTR_TEMPERATURE)
if target_temp is None:
LOGGER.warning("Missing temperature")
return
"""Set the target temperature."""
if ATTR_TEMPERATURE not in kwargs:
raise ValueError("Missing temperature")

packet = self.packet.make_status(target_temp=target_temp)
await self.send(packet)
target_temp = int(kwargs[ATTR_TEMPERATURE])
make_packet = self.packet.make_target_temp(target_temp)
await self.send_packet(make_packet)


class KocomAcEntity(KocomEntity, ClimateEntity):
Expand All @@ -156,105 +145,92 @@ class KocomAcEntity(KocomEntity, ClimateEntity):
HVACMode.COOL,
HVACMode.FAN_ONLY,
HVACMode.DRY,
HVACMode.AUTO
HVACMode.AUTO,
]
_attr_fan_modes = [FAN_LOW, FAN_MEDIUM, FAN_HIGH]
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE |
ClimateEntityFeature.TURN_OFF |
ClimateEntityFeature.TURN_ON |
ClimateEntityFeature.FAN_MODE
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_OFF
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.FAN_MODE
)
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_max_temp = 30
_attr_min_temp = 18
_attr_target_temperature_step = 1

def __init__(
self,
gateway: KocomGateway,
packet: KocomPacket,
) -> None:

def __init__(self, gateway: KocomGateway, packet: KocomPacket) -> None:
"""Initialize the climate."""
super().__init__(gateway, packet)

@property
def hvac_mode(self) -> HVACMode:
"""Return hvac operation ie. heat, cool mode."""
if self.device.state[POWER] and (op_mode := self.device.state[OP_MODE]):
if op_mode == OpMode.COOL:
return HVACMode.COOL
elif op_mode == OpMode.FAN_ONLY:
return HVACMode.FAN_ONLY
elif op_mode == OpMode.DRY:
return HVACMode.DRY
elif op_mode == OpMode.AUTO:
return HVACMode.AUTO
else:
return HVACMode.OFF

"""Return current HVAC mode."""
if self.device.state[POWER]:
op_mode = self.device.state[OP_MODE]
return {
OpMode.COOL: HVACMode.COOL,
OpMode.FAN_ONLY: HVACMode.FAN_ONLY,
OpMode.DRY: HVACMode.DRY,
OpMode.AUTO: HVACMode.AUTO,
}.get(op_mode, HVACMode.OFF)
return HVACMode.OFF

@property
def fan_mode(self) -> str:
"""Return the fan setting."""
fan_mode = self.device.state[FAN_MODE]
if fan_mode == FanMode.LOW:
return FAN_LOW
elif fan_mode == FanMode.MEDIUM:
return FAN_MEDIUM
elif fan_mode == FanMode.HIGH:
return FAN_HIGH

"""Return current fan mode."""
return {
FanMode.LOW: FAN_LOW,
FanMode.MEDIUM: FAN_MEDIUM,
FanMode.HIGH: FAN_HIGH,
}.get(self.device.state[FAN_MODE])

@property
def current_temperature(self) -> int:
"""Return the current temperature."""
return self.device.state[CURRENT_TEMP]

@property
def target_temperature(self) -> int:
"""Return the temperature we try to reach."""
"""Return the target temperature."""
return self.device.state[TARGET_TEMP]

async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target hvac mode."""
"""Set a new target HVAC mode."""
if hvac_mode == HVACMode.OFF:
op_mode = OpMode.OFF
elif hvac_mode == HVACMode.COOL:
op_mode = OpMode.COOL
elif hvac_mode == HVACMode.FAN_ONLY:
op_mode = OpMode.FAN_ONLY
elif hvac_mode == HVACMode.DRY:
op_mode = OpMode.DRY
elif hvac_mode == HVACMode.AUTO:
op_mode = OpMode.AUTO
make_packet = self.packet.make_power_status(False)
else:
raise ValueError(f"Unknown HVAC mode: {hvac_mode}")

packet = self.packet.make_status(op_mode=op_mode)
await self.send(packet)
hvac_to_op_mode = {
HVACMode.COOL: OpMode.COOL,
HVACMode.FAN_ONLY: OpMode.FAN_ONLY,
HVACMode.DRY: OpMode.DRY,
HVACMode.AUTO: OpMode.AUTO,
}
op_mode = hvac_to_op_mode.get(hvac_mode)
if op_mode is None:
raise ValueError(f"Unknown HVAC mode: {hvac_mode}")
make_packet = self.packet.make_op_mode(op_mode)

await self.send_packet(make_packet)

async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set new target fan mode."""
if fan_mode == FAN_LOW:
fan_speed = FanMode.LOW
elif fan_mode == FAN_MEDIUM:
fan_speed = FanMode.MEDIUM
elif fan_mode == FAN_HIGH:
fan_speed = FanMode.HIGH
else:
"""Set a new target fan mode."""
fan_speed = {
FAN_LOW: FanMode.LOW,
FAN_MEDIUM: FanMode.MEDIUM,
FAN_HIGH: FanMode.HIGH,
}.get(fan_mode)
if fan_speed is None:
raise ValueError(f"Unknown fan mode: {fan_mode}")

packet = self.packet.make_status(fan_mode=fan_speed)
await self.send(packet)

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new target preset mode."""

make_packet = self.packet.make_fan_mode(fan_speed)
await self.send_packet(make_packet)

async def async_set_temperature(self, **kwargs) -> None:
"""Set new target temperature."""
target_temp = kwargs.get(ATTR_TEMPERATURE)
if target_temp is None:
LOGGER.warning("Missing temperature")
return
"""Set a new target temperature."""
if ATTR_TEMPERATURE not in kwargs:
raise ValueError("Missing temperature")

packet = self.packet.make_status(target_temp=target_temp)
await self.send(packet)
target_temp = int(kwargs[ATTR_TEMPERATURE])
make_packet = self.packet.make_target_temp(target_temp)
await self.send_packet(make_packet)
Loading

0 comments on commit 10e0d11

Please sign in to comment.