Skip to content

Commit

Permalink
[fix] fan speed enum
Browse files Browse the repository at this point in the history
[fix] encrypt account
  • Loading branch information
tsutsuku committed Jul 23, 2021
1 parent 3a79a29 commit 9dff1f6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 50 deletions.
5 changes: 3 additions & 2 deletions custom_components/tuya_v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Support for Tuya Smart devices."""

import itertools
import json
import logging
from .aes_cbc import (
AesCBC as Aes,
Expand Down Expand Up @@ -84,7 +85,7 @@ def entry_decrypt(hass: HomeAssistant, entry: ConfigEntry, init_entry_data):
cbc_iv = key_iv[16:32]
decrpyt_str = aes.cbc_decrypt(
cbc_key, cbc_iv, init_entry_data[AES_ACCOUNT_KEY]
).replace("'", '"')
)
# _LOGGER.info(f"tuya.__init__.exist_xor_cache:::decrpyt_str-->{decrpyt_str}")
entry_data = aes.json_to_dict(decrpyt_str)
else:
Expand All @@ -98,7 +99,7 @@ def entry_decrypt(hass: HomeAssistant, entry: ConfigEntry, init_entry_data):
c = cbc_key + cbc_iv
c_xor_entry = aes.xor_encrypt(c, access_id_entry)
# account info encrypted with AES-CBC
user_input_encrpt = aes.cbc_encrypt(cbc_key, cbc_iv, str(init_entry_data))
user_input_encrpt = aes.cbc_encrypt(cbc_key, cbc_iv, json.dumps(init_entry_data))
# udpate old account info
hass.config_entries.async_update_entry(
entry,
Expand Down
3 changes: 2 additions & 1 deletion custom_components/tuya_v2/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Config flow for Tuya."""

import json
import logging
from .aes_cbc import (
AesCBC as Aes,
Expand Down Expand Up @@ -147,7 +148,7 @@ async def async_step_user(self, user_input=None):
c = cbc_key + cbc_iv
c_xor_entry = aes.xor_encrypt(c, access_id_entry)
# account info encrypted with AES-CBC
user_input_encrpt = aes.cbc_encrypt(cbc_key, cbc_iv, str(user_input))
user_input_encrpt = aes.cbc_encrypt(cbc_key, cbc_iv, json.dumps(user_input))
# account info encrypted add to cache
return self.async_create_entry(
title=user_input[CONF_USERNAME],
Expand Down
73 changes: 26 additions & 47 deletions custom_components/tuya_v2/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import json
import logging
from typing import Any
from math import ceil

from tuya_iot import TuyaDevice, TuyaDeviceManager
from homeassistant.util.percentage import (
ranged_value_to_percentage,
percentage_to_ranged_value,
ordered_list_item_to_percentage,
percentage_to_ordered_list_item,
)

from homeassistant.components.fan import (
Expand Down Expand Up @@ -64,7 +63,8 @@ async def async_setup_entry(
"""Set up tuya fan dynamically through tuya discovery."""
_LOGGER.info("fan init")

hass.data[DOMAIN][TUYA_HA_TUYA_MAP].update({DEVICE_DOMAIN: TUYA_SUPPORT_TYPE})
hass.data[DOMAIN][TUYA_HA_TUYA_MAP].update(
{DEVICE_DOMAIN: TUYA_SUPPORT_TYPE})

async def async_discover_device(dev_ids):
"""Discover and add a discovered tuya fan."""
Expand Down Expand Up @@ -110,28 +110,22 @@ def __init__(self, device: TuyaDevice, device_manager: TuyaDeviceManager):
# We will always prefer the enumeration if available
# Enum is used for e.g. MEES SmartHIMOX-H06
# Range is used for e.g. Concept CA3000
self.air_purifier_speed_range = (0, 0)
self.air_purifier_speed_range_len = 0
self.air_purifier_speed_range_enum = []
if self.tuya_device.category == "kj":
try:
if DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status:
if DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status\
or DPCODE_AP_FAN_SPEED in self.tuya_device.status:

self.dp_code_speed_enum = DPCODE_AP_FAN_SPEED_ENUM if DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status else DPCODE_AP_FAN_SPEED
data = json.loads(
self.tuya_device.function.get(
DPCODE_AP_FAN_SPEED_ENUM, {}
self.dp_code_speed_enum, {}
).values
).get("range")
if data:
self.air_purifier_speed_range = (1, len(data))
self.air_purifier_speed_range_len = len(data)
self.air_purifier_speed_range_enum = data
elif DPCODE_AP_FAN_SPEED in self.tuya_device.status:
data = json.loads(
self.tuya_device.function.get(DPCODE_AP_FAN_SPEED, {}).values
).get("range")
if data:
self.air_purifier_speed_range = (int(data[0]), int(data[-1]))
self.air_purifier_speed_range_len = len(data)
except Exception:
_LOGGER.error("Cannot parse the air-purifier speed range")

Expand All @@ -141,32 +135,20 @@ def set_preset_mode(self, preset_mode: str) -> None:

def set_direction(self, direction: str) -> None:
"""Set the direction of the fan."""
self._send_command([{"code": DPCODE_FAN_DIRECTION, "value": direction}])
self._send_command(
[{"code": DPCODE_FAN_DIRECTION, "value": direction}])

def set_percentage(self, percentage: int) -> None:
"""Set the speed of the fan, as a percentage."""
if self.tuya_device.category == "kj":
value_in_range = ceil(
percentage_to_ranged_value(self.air_purifier_speed_range, percentage)
)
if not self.air_purifier_speed_range_enum:
# if air-purifier speed enumeration is supported we will prefer it.
self._send_command(
[
{
"code": DPCODE_AP_FAN_SPEED_ENUM,
"value": str(
self.air_purifier_speed_range_enum[value_in_range - 1]
),
}
]
)
else:
self._send_command(
[{"code": DPCODE_AP_FAN_SPEED, "value": str(value_in_range)}]
)
value_in_range = percentage_to_ordered_list_item(
self.air_purifier_speed_range_enum, percentage)
self._send_command([{
"code": self.dp_code_speed_enum,
"value": value_in_range,
}])
else:
super().set_percentage(percentage)
self._send_command([{"code": DPCODE_FAN_SPEED, "value": percentage}])

def turn_off(self, **kwargs: Any) -> None:
"""Turn the fan off."""
Expand All @@ -184,7 +166,8 @@ def turn_on(

def oscillate(self, oscillating: bool) -> None:
"""Oscillate the fan."""
self._send_command([{"code": DPCODE_SWITCH_HORIZONTAL, "value": oscillating}])
self._send_command(
[{"code": DPCODE_SWITCH_HORIZONTAL, "value": oscillating}])

# property
@property
Expand All @@ -209,6 +192,9 @@ def oscillating(self) -> bool:
@property
def preset_modes(self) -> list:
"""Return the list of available preset_modes."""
if DPCODE_MODE not in self.tuya_device.function:
return []

try:
data = json.loads(
self.tuya_device.function.get(DPCODE_MODE, {}).values
Expand All @@ -233,17 +219,10 @@ def percentage(self) -> int:
if self.air_purifier_speed_range_len > 1:
if not self.air_purifier_speed_range_enum:
# if air-purifier speed enumeration is supported we will prefer it.
index = self.air_purifier_speed_range_enum.index(
self.tuya_device.status.get(DPCODE_AP_FAN_SPEED_ENUM, 0)
return ordered_list_item_to_percentage(
self.air_purifier_speed_range_enum, self.tuya_device.status.get(
DPCODE_AP_FAN_SPEED_ENUM, 0)
)
return ranged_value_to_percentage(
self.air_purifier_speed_range, index + 1
)

return ranged_value_to_percentage(
self.air_purifier_speed_range,
int(self.tuya_device.status.get(DPCODE_AP_FAN_SPEED, 0)),
)

return self.tuya_device.status.get(DPCODE_FAN_SPEED, 0)

Expand Down

0 comments on commit 9dff1f6

Please sign in to comment.