Skip to content

Commit

Permalink
Merge branch 'feature/v2'
Browse files Browse the repository at this point in the history
  • Loading branch information
osk2 committed Aug 26, 2021
2 parents 22cf7e6 + 93c0998 commit b8aca50
Show file tree
Hide file tree
Showing 20 changed files with 610 additions and 121 deletions.
31 changes: 19 additions & 12 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,25 @@ _完整的實體清單請見 [可用的實體](#可用的實體)_

### 可用的實體

| 裝置類型 | 實體類型 | 備註 |
| -------- | ------------- | ---------------------- |
| 冷氣 | climate | |
| | number | 定時開機(若裝置支援) |
| | number | 定時關機 |
| | sensor | 室外溫度偵測器 |
| 除濕機 | humidifier | |
| | number | 定時開機(若裝置支援) |
| | number | 定時關機 |
| | sensor | 環境溼度偵測器 |
| | sensor | PM2.5 偵測器 |
| | binary_sensor | 水箱滿水偵測器 |
| 裝置類型 | 實體類型 | 備註 |
| -------- | ------------- | -------------- |
| 冷氣 | climate | |
| | number | 定時開機\* |
| | number | 定時關機 |
| | sensor | 室外溫度偵測器 |
| | switch | nanoe 開關\* |
| | switch | ECONAVI 開關\* |
| | switch | 操控聲音開關\* |
| | switch | 急速模式開關\* |
| 除濕機 | humidifier | |
| | number | 定時開機\* |
| | number | 定時關機 |
| | select | 風量設定 |
| | sensor | 環境溼度偵測器 |
| | sensor | PM2.5 偵測器 |
| | binary_sensor | 水箱滿水偵測器 |

\*僅在裝置支援的情況下可用

更多實體支援請至 [Issue](https://github.com/osk2/panasonic_smart_app/issues) 頁面許願,也歡迎發送 PR 💪

Expand Down
31 changes: 19 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,25 @@ Feel free to report working device by opening an [issue](https://github.com/osk2

### Available Entities

| Device Type | Entity Type | Note |
| ------------ | ------------- | ---------------------------- |
| AC | climate | |
| | number | On timer (Only if supported) |
| | number | Off timer |
| | sensor | Outdoor temperature sensor |
| Dehumidifier | humidifier | |
| | number | On timer (Only if supported) |
| | number | Off timer |
| | sensor | Environment humidity sensor |
| | sensor | PM2.5 sensor |
| | binary_sensor | Water tank status sensor |
| Device Type | Entity Type | Note |
| ------------ | ------------- | --------------------------- |
| AC | climate | |
| | number | On timer\* |
| | number | Off timer |
| | sensor | Outdoor temperature sensor |
| | switch | nanoe switch\* |
| | switch | ECONAVI swtich\* |
| | switch | Buzzer switch\* |
| | switch | Turbo mode switch\* |
| Dehumidifier | humidifier | |
| | number | On timer\* |
| | number | Off timer |
| | select | Fan mode |
| | sensor | Environment humidity sensor |
| | sensor | PM2.5 sensor |
| | binary_sensor | Water tank status sensor |

\*Only available if feature is supported.

For missing entities, open an issue or submit a PR 💪

Expand Down
21 changes: 7 additions & 14 deletions custom_components/panasonic_smart_app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import asyncio
import async_timeout
from datetime import timedelta
import logging

Expand All @@ -14,10 +13,11 @@
from .const import (
DATA_CLIENT,
DATA_COORDINATOR,
DEFAULT_UPDATE_INTERVAL,
DOMAIN,
CONF_UPDATE_INTERVAL,
DEFAULT_NAME,
PLATFORMS,
UPDATE_INTERVAL,
DEVICE_STATUS_CODES,
)

Expand All @@ -44,24 +44,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_update_data():
try:
_LOGGER.info("Updating device info...")
devices = await client.get_devices()
for device in devices:
device_type = int(device["Devices"][0]["DeviceType"])
if device_type in DEVICE_STATUS_CODES.keys():
status_codes = DEVICE_STATUS_CODES[device_type]
device["status"] = await client.get_device_info(
device["auth"], status_codes
)
return devices
except:
raise UpdateFailed("Failed on initialize")
return await client.get_device_with_info(DEVICE_STATUS_CODES)
except BaseException as ex:
_LOGGER.error(ex)
raise UpdateFailed("Failed while updating device status")

coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name=DEFAULT_NAME,
update_method=async_update_data,
update_interval=timedelta(seconds=UPDATE_INTERVAL),
update_interval=timedelta(seconds=entry.data.get(CONF_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL)),
)

await coordinator.async_refresh()
Expand Down
4 changes: 1 addition & 3 deletions custom_components/panasonic_smart_app/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from .entity import PanasonicBaseEntity
from .const import (
DOMAIN,
UPDATE_INTERVAL,
DEVICE_TYPE_DEHUMIDIFIER,
DATA_CLIENT,
DATA_COORDINATOR,
Expand All @@ -14,7 +13,6 @@
)

_LOGGER = logging.getLogger(__package__)
SCAN_INTERVAL = timedelta(seconds=UPDATE_INTERVAL)


async def async_setup_entry(hass, entry, async_add_entities) -> bool:
Expand All @@ -24,7 +22,7 @@ async def async_setup_entry(hass, entry, async_add_entities) -> bool:
sensors = []

for index, device in enumerate(devices):
if int(device["Devices"][0]["DeviceType"]) == DEVICE_TYPE_DEHUMIDIFIER:
if int(device.get("DeviceType")) == DEVICE_TYPE_DEHUMIDIFIER:
sensors.append(
PanasonoicTankSensor(
coordinator,
Expand Down
9 changes: 6 additions & 3 deletions custom_components/panasonic_smart_app/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from .const import (
DOMAIN,
DEVICE_TYPE_AC,
UPDATE_INTERVAL,
DATA_CLIENT,
DATA_COORDINATOR,
CLIMATE_AVAILABLE_MODE,
Expand All @@ -28,7 +27,6 @@
)

_LOGGER = logging.getLogger(__package__)
SCAN_INTERVAL = timedelta(seconds=UPDATE_INTERVAL)


def getKeyFromDict(targetDict, mode_name):
Expand All @@ -46,7 +44,7 @@ async def async_setup_entry(hass, entry, async_add_entities) -> bool:
climate = []

for index, device in enumerate(devices):
if int(device["Devices"][0]["DeviceType"]) == DEVICE_TYPE_AC:
if int(device.get("DeviceType")) == DEVICE_TYPE_AC:
climate.append(
PanasonicClimate(
coordinator,
Expand All @@ -62,6 +60,11 @@ async def async_setup_entry(hass, entry, async_add_entities) -> bool:


class PanasonicClimate(PanasonicBaseEntity, ClimateEntity):
@property
def available(self) -> bool:
status = self.coordinator.data[self.index]["status"]
return status.get("0x00") != None

@property
def label(self) -> str:
return f"{self.nickname} {LABEL_CLIMATE}"
Expand Down
7 changes: 6 additions & 1 deletion custom_components/panasonic_smart_app/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

from .smartApp import SmartApp
from .smartApp.exceptions import PanasonicExceedRateLimit
from .const import DOMAIN
from .const import (
DOMAIN,
CONF_UPDATE_INTERVAL,
DEFAULT_UPDATE_INTERVAL,
)


class SmartAppFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
Expand Down Expand Up @@ -59,6 +63,7 @@ async def _show_config_form(
{
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Optional(CONF_UPDATE_INTERVAL, default=DEFAULT_UPDATE_INTERVAL): int,
}
),
errors=self._errors,
Expand Down
45 changes: 34 additions & 11 deletions custom_components/panasonic_smart_app/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,22 @@
"number",
"binary_sensor",
"climate",
"switch",
"select",
]
MANUFACTURER = "Panasonic"
DEFAULT_NAME = "Panasonic Smart Application"

DEVICE_TYPE_AC = 1
DEVICE_TYPE_WASHING_MACHINE = 3
DEVICE_TYPE_DEHUMIDIFIER = 4

DATA_CLIENT = "client"
DATA_COORDINATOR = "coordinator"

UPDATE_INTERVAL = 90
CONF_UPDATE_INTERVAL = "update_interval"

DEFAULT_UPDATE_INTERVAL = 180

DEVICE_STATUS_CODES = {
DEVICE_TYPE_AC: [
Expand All @@ -39,19 +44,25 @@
"0x21",
"0x0b",
"0x0c",
"0x08",
"0x1b",
"0x1e",
"0x1a",
],
DEVICE_TYPE_DEHUMIDIFIER: [
"0x00",
"0x01",
"0x00", # Dehumidifier online status
"0x01", # Dehumidifier operation mode
"0x02", # Dehumidifier off timer
"0x07", # Dehumidifier humidity sensor
"0x09", # Dehumidifier fan direction
"0x0D", # Dehumidifier nanoe
"0x50",
"0x0a",
"0x04",
"0x0e",
"0x09",
"0x55",
"0x02",
"0x53",
"0x07",
"0x18", # Dehumidifier buzzer
"0x53", # Dehumidifier PM2.5
"0x55", # Dehumidifier on timer
"0x0A", # Dehumidifier tank status
"0x04", # Dehumidifier target humidity
"0x0E", # Dehumidifier fan mode
],
}

Expand Down Expand Up @@ -102,6 +113,12 @@
ICON_OFF_TIMER = "mdi:alarm-snooze"
ICON_THERMOMETER = "mdi:thermometer"
ICON_PM25 = "mdi:dots-hexagon"
ICON_NANOE = "mdi:atom"
ICON_ECONAVI = "mdi:leaf"
ICON_BUZZER = "mdi:volume-high"
ICON_TURBO = "mdi:clock-fast"
ICON_FAN = "mdi:fan"
ICON_ENERGY = "mdi:flash"


LABEL_DEHUMIDIFIER = ""
Expand All @@ -110,11 +127,17 @@
LABEL_HUMIDITY = "環境溼度"
LABEL_DEHUMIDIFIER_ON_TIMER = "定時開機"
LABEL_DEHUMIDIFIER_OFF_TIMER = "定時關機"
LABEL_DEHUMIDIFIER_FAN_MODE = "風量設定"
LABEL_CLIMATE_ON_TIMER = "定時開機(分)"
LABEL_CLIMATE_ON_TIMER = "定時開機"
LABEL_CLIMATE_OFF_TIMER = "定時關機"
LABEL_OUTDOOR_TEMPERATURE = "室外溫度"
LABEL_PM25 = "PM2.5"
LABEL_NANOE = "nanoe"
LABEL_ECONAVI = "ECONAVI"
LABEL_BUZZER = "操作提示音"
LABEL_TURBO = "急速"
LABEL_ENERGY = "本月耗電量"

UNIT_HOUR = "小時"
UNIT_MINUTE = "分鐘"
7 changes: 2 additions & 5 deletions custom_components/panasonic_smart_app/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
from .const import (
DOMAIN,
MANUFACTURER,
UPDATE_INTERVAL,
)

SCAN_INTERVAL = timedelta(seconds=UPDATE_INTERVAL)

class PanasonicBaseEntity(CoordinatorEntity, ABC):
def __init__(
self,
Expand All @@ -31,7 +28,7 @@ def label(self) -> str:

@property
def current_device_info(self) -> dict:
return self.device["Devices"][0]
return self.device

@property
def nickname(self) -> str:
Expand All @@ -57,7 +54,7 @@ def name(self) -> str:

@property
def auth(self) -> str:
return self.device["auth"]
return self.device["Auth"]

@property
def unique_id(self) -> str:
Expand Down
14 changes: 4 additions & 10 deletions custom_components/panasonic_smart_app/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from .entity import PanasonicBaseEntity
from .const import (
DOMAIN,
UPDATE_INTERVAL,
DEVICE_TYPE_DEHUMIDIFIER,
DATA_CLIENT,
DATA_COORDINATOR,
Expand All @@ -20,7 +19,6 @@
)

_LOGGER = logging.getLogger(__package__)
SCAN_INTERVAL = timedelta(seconds=UPDATE_INTERVAL)


def getKeyFromDict(targetDict, mode_name):
Expand All @@ -38,7 +36,7 @@ async def async_setup_entry(hass, entry, async_add_entities) -> bool:
humidifiers = []

for index, device in enumerate(devices):
if int(device["Devices"][0]["DeviceType"]) == DEVICE_TYPE_DEHUMIDIFIER:
if int(device.get("DeviceType")) == DEVICE_TYPE_DEHUMIDIFIER:
humidifiers.append(
PanasonicDehumidifier(
coordinator,
Expand All @@ -54,12 +52,10 @@ async def async_setup_entry(hass, entry, async_add_entities) -> bool:


class PanasonicDehumidifier(PanasonicBaseEntity, HumidifierEntity):

@property
def available(self) -> bool:
status = self.coordinator.data[self.index]["status"]
_is_on_status = bool(int(status.get("0x00") or 0))
return _is_on_status
return status.get("0x00") != None

@property
def label(self) -> str:
Expand All @@ -68,9 +64,7 @@ def label(self) -> str:
@property
def target_humidity(self) -> int:
status = self.coordinator.data[self.index]["status"]
_target_humidity = DEHUMIDIFIER_AVAILABLE_HUMIDITY[
int(status.get("0x04") or 0)
]
_target_humidity = DEHUMIDIFIER_AVAILABLE_HUMIDITY[int(status.get("0x04", 0))]
_LOGGER.debug(f"[{self.label}] target_humidity: {_target_humidity}")
return _target_humidity

Expand All @@ -90,7 +84,7 @@ def mode(self) -> str:
)[0]["Parameters"]
target_mode = list(
filter(lambda m: m[1] == int(status.get("0x01") or 0), raw_mode_list)
)
)[0]
_mode = target_mode[0] if len(target_mode) > 0 else ""
_LOGGER.debug(f"[{self.label}] _mode: {_mode}")
return _mode
Expand Down
Loading

0 comments on commit b8aca50

Please sign in to comment.