def _try_login(user_input): project_type = ProjectType(user_input[CONF_PROJECT_TYPE]) api = TuyaOpenAPI( TUYA_ENDPOINTS[user_input[CONF_ENDPOINT]] if project_type == ProjectType.INDUSTY_SOLUTIONS else "", user_input[CONF_ACCESS_ID], user_input[CONF_ACCESS_SECRET], project_type, ) api.set_dev_channel("hass") if project_type == ProjectType.INDUSTY_SOLUTIONS: response = api.login(user_input[CONF_USERNAME], user_input[CONF_PASSWORD]) else: if user_input[CONF_COUNTRY_CODE] in COUNTRY_CODE_CHINA: api.endpoint = TUYA_ENDPOINT_BASE else: api.endpoint = TUYA_ENDPOINT_OTHER response = api.login( user_input[CONF_USERNAME], user_input[CONF_PASSWORD], user_input[CONF_COUNTRY_CODE], TUYA_APP_TYPES[user_input[CONF_APP_TYPE]], ) if response.get("success", False) and isinstance( api.token_info.platform_url, str): api.endpoint = api.token_info.platform_url user_input[CONF_ENDPOINT] = api.token_info.platform_url return response
def _try_login(cls, user_input): _LOGGER.info( f"TuyaConfigFlow._try_login start, user_input: {user_input}") project_type = ProjectType(user_input[CONF_PROJECT_TYPE]) api = TuyaOpenAPI( user_input[CONF_ENDPOINT] if project_type == ProjectType.INDUSTY_SOLUTIONS else "", user_input[CONF_ACCESS_ID], user_input[CONF_ACCESS_SECRET], project_type, ) api.set_dev_channel("hass") if project_type == ProjectType.INDUSTY_SOLUTIONS: response = api.login(user_input[CONF_USERNAME], user_input[CONF_PASSWORD]) else: if user_input[CONF_COUNTRY_CODE] in COUNTRY_CODE_CHINA: api.endpoint = "https://openapi.tuyacn.com" else: api.endpoint = "https://openapi.tuyaus.com" response = api.login( user_input[CONF_USERNAME], user_input[CONF_PASSWORD], user_input[CONF_COUNTRY_CODE], user_input[CONF_APP_TYPE], ) if response.get("success", False): api.endpoint = api.token_info.platform_url user_input[CONF_ENDPOINT] = api.token_info.platform_url _LOGGER.info( f"TuyaConfigFlow._try_login finish, response:, {response}") return response
async def _init_tuya_sdk(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry_data = entry_decrypt(hass, entry, entry.data) project_type = ProjectType(entry_data[CONF_PROJECT_TYPE]) api = TuyaOpenAPI( entry_data[CONF_ENDPOINT], entry_data[CONF_ACCESS_ID], entry_data[CONF_ACCESS_SECRET], project_type, ) api.set_dev_channel("hass") if project_type == ProjectType.INDUSTY_SOLUTIONS: response = await hass.async_add_executor_job(api.login, entry_data[CONF_USERNAME], entry_data[CONF_PASSWORD]) else: response = await hass.async_add_executor_job( api.login, entry_data[CONF_USERNAME], entry_data[CONF_PASSWORD], entry_data[CONF_COUNTRY_CODE], entry_data[CONF_APP_TYPE], ) if response.get("success", False) is False: _LOGGER.error("Tuya login error response: %s", response) return False tuya_mq = TuyaOpenMQ(api) tuya_mq.start() device_manager = TuyaDeviceManager(api, tuya_mq) # Get device list home_manager = TuyaHomeManager(api, tuya_mq, device_manager) await hass.async_add_executor_job(home_manager.update_device_cache) hass.data[DOMAIN][entry.entry_id][TUYA_HOME_MANAGER] = home_manager listener = DeviceListener(hass, entry) hass.data[DOMAIN][entry.entry_id][TUYA_MQTT_LISTENER] = listener device_manager.add_device_listener(listener) hass.data[DOMAIN][entry.entry_id][TUYA_DEVICE_MANAGER] = device_manager # Clean up device entities await cleanup_device_registry(hass, entry) _LOGGER.debug("init support type->%s", PLATFORMS) hass.config_entries.async_setup_platforms(entry, PLATFORMS) return True
def _try_login(self, user_input): print('TuyaConfigFlow._try_login start, user_input:', user_input) api = TuyaOpenAPI(user_input[CONF_ENDPOINT], user_input[CONF_ACCESS_ID], user_input[CONF_ACCESS_SECRET]) api.set_dev_channel('hass') response = api.login(user_input[CONF_USERNAME], user_input[CONF_PASSWORD]) print('TuyaConfigFlow._try_login finish, response:', response) return response
def _init_tuya_sdk(hass: HomeAssistant, entry_data: dict) -> TuyaDeviceManager: api = TuyaOpenAPI(entry_data[CONF_ENDPOINT], entry_data[CONF_ACCESS_ID], entry_data[CONF_ACCESS_SECRET]) api.set_dev_channel('hass') response = api.login(entry_data[CONF_USERNAME], entry_data[CONF_PASSWORD]) if response.get('success', False) == False: _LOGGER.error( "Tuya login error response: %s", response, ) return False mq = TuyaOpenMQ(api) mq.start() # Get device list devIds = [] assetManager = TuyaAssetManager(api) response = assetManager.getAssetList() assets = response.get('result', {}).get('assets', []) for asset in assets: asset_id = asset['asset_id'] devIds += assetManager.getDeviceList(asset_id) # Update device status deviceManager = TuyaDeviceManager(api, mq) deviceManager.updateDeviceCaches(devIds) # Create ha devices haDevices = [] for (devId, device) in deviceManager.deviceMap.items(): haDevice = crete_tuya_ha_device(device, deviceManager) if haDevice: haDevices.append(haDevice) hass.data[DOMAIN] = { 'haDevices': haDevices, } # Set mqtt listener def _onMessage(msg): devId = msg.get('data', {}).get('devId', '') haDevices = hass.data[DOMAIN]['haDevices'] for haDevice in haDevices: if haDevice.tuyaDevice.id == devId: haDevice.schedule_update_ha_state() mq.add_message_listener(_onMessage) return True
def _try_login(user_input): project_type = ProjectType(user_input[CONF_PROJECT_TYPE]) api = TuyaOpenAPI( user_input[CONF_ENDPOINT] if project_type == ProjectType.INDUSTY_SOLUTIONS else "", user_input[CONF_ACCESS_ID], user_input[CONF_ACCESS_SECRET], project_type, ) api.set_dev_channel("hass") if project_type == ProjectType.INDUSTY_SOLUTIONS: response = api.login(user_input[CONF_USERNAME], user_input[CONF_PASSWORD]) else: api.endpoint = TUYA_ENDPOINT_BASE response = api.login( user_input[CONF_USERNAME], user_input[CONF_PASSWORD], user_input[CONF_COUNTRY_CODE], user_input[CONF_APP_TYPE], ) if response.get("success", False) and isinstance( api.token_info.platform_url, str): api.endpoint = api.token_info.platform_url user_input[CONF_ENDPOINT] = api.token_info.platform_url _LOGGER.debug("TuyaConfigFlow._try_login finish, response:, %s", response) return response
def _try_login( user_input: dict[str, Any]) -> tuple[dict[Any, Any], dict[str, Any]]: """Try login.""" response = {} country = [ country for country in TUYA_COUNTRIES if country.name == user_input[CONF_COUNTRY_CODE] ][0] data = { CONF_ENDPOINT: country.endpoint, CONF_AUTH_TYPE: AuthType.CUSTOM, CONF_ACCESS_ID: user_input[CONF_ACCESS_ID], CONF_ACCESS_SECRET: user_input[CONF_ACCESS_SECRET], CONF_USERNAME: user_input[CONF_USERNAME], CONF_PASSWORD: user_input[CONF_PASSWORD], CONF_COUNTRY_CODE: country.country_code, } for app_type in ("", TUYA_SMART_APP, SMARTLIFE_APP): data[CONF_APP_TYPE] = app_type if data[CONF_APP_TYPE] == "": data[CONF_AUTH_TYPE] = AuthType.CUSTOM else: data[CONF_AUTH_TYPE] = AuthType.SMART_HOME api = TuyaOpenAPI( endpoint=data[CONF_ENDPOINT], access_id=data[CONF_ACCESS_ID], access_secret=data[CONF_ACCESS_SECRET], auth_type=data[CONF_AUTH_TYPE], ) api.set_dev_channel("hass") response = api.connect( username=data[CONF_USERNAME], password=data[CONF_PASSWORD], country_code=data[CONF_COUNTRY_CODE], schema=data[CONF_APP_TYPE], ) LOGGER.debug("Response %s", response) if response.get(TUYA_RESPONSE_SUCCESS, False): break return response, data
async def _init_tuya_sdk(hass: HomeAssistant, entry: ConfigEntry) -> bool: auth_type = AuthType(entry.data[CONF_AUTH_TYPE]) api = TuyaOpenAPI( endpoint=entry.data[CONF_ENDPOINT], access_id=entry.data[CONF_ACCESS_ID], access_secret=entry.data[CONF_ACCESS_SECRET], auth_type=auth_type, ) api.set_dev_channel("hass") if auth_type == AuthType.CUSTOM: response = await hass.async_add_executor_job( api.connect, entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD] ) else: response = await hass.async_add_executor_job( api.connect, entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], entry.data[CONF_COUNTRY_CODE], entry.data[CONF_APP_TYPE], ) if response.get("success", False) is False: _LOGGER.error("Tuya login error response: %s", response) return False tuya_mq = TuyaOpenMQ(api) tuya_mq.start() device_ids: set[str] = set() device_manager = TuyaDeviceManager(api, tuya_mq) home_manager = TuyaHomeManager(api, tuya_mq, device_manager) listener = DeviceListener(hass, device_manager, device_ids) device_manager.add_device_listener(listener) hass.data[DOMAIN][entry.entry_id] = HomeAssistantTuyaData( device_listener=listener, device_manager=device_manager, home_manager=home_manager, ) # Get devices & clean up device entities await hass.async_add_executor_job(home_manager.update_device_cache) await cleanup_device_registry(hass, device_manager) # Migrate old unique_ids to the new format async_migrate_entities_unique_ids(hass, entry, device_manager) # Register known device IDs device_registry = dr.async_get(hass) for device in device_manager.device_map.values(): device_registry.async_get_or_create( config_entry_id=entry.entry_id, identifiers={(DOMAIN, device.id)}, manufacturer="Tuya", name=device.name, model=f"{device.product_name} (unsupported)", ) device_ids.add(device.id) hass.config_entries.async_setup_platforms(entry, PLATFORMS) return True
async def _init_tuya_sdk(self) -> bool: auth_type = AuthType(0) api = TuyaOpenAPI( self._get_region_url(self._t_region), self._t_apikey, self._t_apisecret, auth_type, ) api.set_dev_channel("fhempy") response = ( await utils.run_blocking( functools.partial(api.connect, self._t_username, self._t_password) ) if auth_type == AuthType.CUSTOM else await utils.run_blocking( functools.partial( api.connect, self._t_username, self._t_password, self._get_countrycode(self._t_region), self._t_apptype, ) ) ) if response.get("success", False) is False: if response.get("code", 0) == 2406: await fhem.readingsSingleUpdate( self.hash, "state", "Tuya project too old, create new one", 1 ) else: await fhem.readingsSingleUpdate( self.hash, "state", f"failed to login: {response}", 1 ) self.logger.error(f"Tuya login error response: {response}") return False self.tuya_pulsar = TuyaOpenPulsar( self._t_apikey, self._t_apisecret, self._get_pulsar_endpoint(self._t_region), TuyaCloudPulsarTopic.PROD, ) self.tuya_pulsar.start() # check if pulsar is working await asyncio.sleep(2) pulsar_connected = False try: pulsar_connected = self.tuya_pulsar.ws_app.sock.status == 101 except Exception: pass if pulsar_connected is False: self.logger.error( "Please activate OpenPulsar: " + "https://developer.tuya.com/en/docs/iot/subscribe-mq?id=Kavqcrvckbh9h" ) # pulsar not working self.tuya_pulsar.stop() else: self.logger.info("Tuya Open Pulsar connected") self.tuya_mq = TuyaOpenMQ(api) self.tuya_mq.start() self.device_manager = TuyaDeviceManager(api, self.tuya_mq) # Get device list self.home_manager = TuyaHomeManager(api, self.tuya_mq, self.device_manager) await utils.run_blocking( functools.partial(self.home_manager.update_device_cache) ) t_cloud_setup = self class DeviceListener(TuyaDeviceListener): """Device Update Listener.""" def __init__(self, logger) -> None: super().__init__() self.logger = logger def update_device(self, device: TuyaDevice): self.logger.debug(f"update_device received for {device.id}") for dev in t_cloud_setup.tuya_devices: if dev.id == device.id: try: asyncio.run_coroutine_threadsafe( dev.update(device), t_cloud_setup.fhemdev.loop ) except Exception: self.logger.exception("Failed to update device") def add_device(self, device: TuyaDevice): self.logger.info(f"add_device received for {device.id}") try: asyncio.run_coroutine_threadsafe( self.add_fhem_device(device), t_cloud_setup.fhemdev.loop ) except Exception: self.logger.exception("Failed to add device") async def add_fhem_device(self, device: TuyaDevice): await t_cloud_setup._create_fhem_device(device.name, device.id) try: self.tuya_mq.stop() except Exception: pass self.tuya_mq = TuyaOpenMQ( t_cloud_setup.device_manager.device_manager.api ) self.tuya_mq.start() t_cloud_setup.device_manager.mq = self.tuya_mq self.tuya_mq.add_message_listener( t_cloud_setup.device_manager.on_message ) def remove_device(self, device_id: str): self.logger.info(f"remove_device received for {device_id}") __listener = DeviceListener(self.logger) self.device_manager.add_device_listener(__listener) def on_pulsar_message(msg): msg = json.loads(msg) status = msg.get("status", []) device = {"id": msg["devId"], "status": status} self.logger.debug(f"update_device received: {msg}") for dev in t_cloud_setup.tuya_devices: if dev.id == device["id"]: try: asyncio.run_coroutine_threadsafe( dev.update_readings_arr(device["status"]), t_cloud_setup.fhemdev.loop, ) except Exception: self.logger.exception("Failed to update device") self.tuya_pulsar.add_message_listener(on_pulsar_message) return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Async setup hass config entry.""" hass.data.setdefault(DOMAIN, {}) # Project type has been renamed to auth type in the upstream Tuya IoT SDK. # This migrates existing config entries to reflect that name change. if CONF_PROJECT_TYPE in entry.data: data = {**entry.data, CONF_AUTH_TYPE: entry.data[CONF_PROJECT_TYPE]} data.pop(CONF_PROJECT_TYPE) hass.config_entries.async_update_entry(entry, data=data) auth_type = AuthType(entry.data[CONF_AUTH_TYPE]) api = TuyaOpenAPI( endpoint=entry.data[CONF_ENDPOINT], access_id=entry.data[CONF_ACCESS_ID], access_secret=entry.data[CONF_ACCESS_SECRET], auth_type=auth_type, ) api.set_dev_channel("hass") try: if auth_type == AuthType.CUSTOM: response = await hass.async_add_executor_job( api.connect, entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD]) else: response = await hass.async_add_executor_job( api.connect, entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], entry.data[CONF_COUNTRY_CODE], entry.data[CONF_APP_TYPE], ) except requests.exceptions.RequestException as err: raise ConfigEntryNotReady(err) from err if response.get("success", False) is False: raise ConfigEntryNotReady(response) tuya_mq = TuyaOpenMQ(api) tuya_mq.start() device_ids: set[str] = set() device_manager = TuyaDeviceManager(api, tuya_mq) home_manager = TuyaHomeManager(api, tuya_mq, device_manager) listener = DeviceListener(hass, device_manager, device_ids) device_manager.add_device_listener(listener) hass.data[DOMAIN][entry.entry_id] = HomeAssistantTuyaData( device_listener=listener, device_manager=device_manager, home_manager=home_manager, ) # Get devices & clean up device entities await hass.async_add_executor_job(home_manager.update_device_cache) await cleanup_device_registry(hass, device_manager) # Migrate old unique_ids to the new format async_migrate_entities_unique_ids(hass, entry, device_manager) # Register known device IDs device_registry = dr.async_get(hass) for device in device_manager.device_map.values(): device_registry.async_get_or_create( config_entry_id=entry.entry_id, identifiers={(DOMAIN, device.id)}, manufacturer="Tuya", name=device.name, model=f"{device.product_name} (unsupported)", ) device_ids.add(device.id) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True
async def _init_tuya_sdk(hass: HomeAssistant, entry: ConfigEntry) -> bool: init_entry_data = entry.data # decrypt or encrypt entry info entry_data = entry_decrypt(hass, entry, init_entry_data) project_type = ProjectType(entry_data[CONF_PROJECT_TYPE]) api = TuyaOpenAPI( entry_data[CONF_ENDPOINT], entry_data[CONF_ACCESS_ID], entry_data[CONF_ACCESS_SECRET], project_type, ) api.set_dev_channel("hass") response = ( await hass.async_add_executor_job( api.login, entry_data[CONF_USERNAME], entry_data[CONF_PASSWORD] ) if project_type == ProjectType.INDUSTY_SOLUTIONS else await hass.async_add_executor_job( api.login, entry_data[CONF_USERNAME], entry_data[CONF_PASSWORD], entry_data[CONF_COUNTRY_CODE], entry_data[CONF_APP_TYPE], ) ) if response.get("success", False) is False: _LOGGER.error(f"Tuya login error response: {response}") return False tuya_mq = TuyaOpenMQ(api) tuya_mq.start() device_manager = TuyaDeviceManager(api, tuya_mq) # Get device list home_manager = TuyaHomeManager(api, tuya_mq, device_manager) await hass.async_add_executor_job(home_manager.update_device_cache) hass.data[DOMAIN][TUYA_HOME_MANAGER] = home_manager class DeviceListener(TuyaDeviceListener): """Device Update Listener.""" def update_device(self, device: TuyaDevice): for ha_device in hass.data[DOMAIN][TUYA_HA_DEVICES]: if ha_device.tuya_device.id == device.id: _LOGGER.debug(f"_update-->{self};->>{ha_device.tuya_device.status}") ha_device.schedule_update_ha_state() def add_device(self, device: TuyaDevice): device_add = False _LOGGER.info( f"""add device category->{device.category}; keys->, {hass.data[DOMAIN][TUYA_HA_TUYA_MAP].keys()}""" ) if device.category in itertools.chain( *hass.data[DOMAIN][TUYA_HA_TUYA_MAP].values() ): ha_tuya_map = hass.data[DOMAIN][TUYA_HA_TUYA_MAP] remove_hass_device(hass, device.id) for key, tuya_list in ha_tuya_map.items(): if device.category in tuya_list: device_add = True async_dispatcher_send( hass, TUYA_DISCOVERY_NEW.format(key), [device.id] ) if device_add: device_manager = hass.data[DOMAIN][TUYA_DEVICE_MANAGER] device_manager.mq.stop() tuya_mq = TuyaOpenMQ(device_manager.api) tuya_mq.start() device_manager.mq = tuya_mq tuya_mq.add_message_listener(device_manager.on_message) def remove_device(self, device_id: str): _LOGGER.info(f"tuya remove device:{device_id}") remove_hass_device(hass, device_id) __listener = DeviceListener() hass.data[DOMAIN][TUYA_MQTT_LISTENER] = __listener device_manager.add_device_listener(__listener) hass.data[DOMAIN][TUYA_DEVICE_MANAGER] = device_manager # Clean up device entities await cleanup_device_registry(hass) _LOGGER.info(f"init support type->{TUYA_SUPPORT_HA_TYPE}") for platform in TUYA_SUPPORT_HA_TYPE: _LOGGER.info(f"tuya async platform-->{platform}") hass.async_create_task( hass.config_entries.async_forward_entry_setup(entry, platform) ) hass.data[DOMAIN][TUYA_SETUP_PLATFORM].add(platform) return True
import logging from tuya_iot import TuyaOpenAPI, TuyaOpenMQ, TUYA_LOGGER from env import ENDPOINT, ACCESS_ID, ACCESS_KEY, USERNAME, PASSWORD TUYA_LOGGER.setLevel(logging.DEBUG) # Init openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY) openapi.connect(USERNAME, PASSWORD, "86", 'tuyaSmart') # Receive device message def on_message(msg): print("on_message: %s" % msg) openapi.token_info.expire_time = 0 openmq = TuyaOpenMQ(openapi) openmq.start() openmq.add_message_listener(on_message)
import logging from env import ENDPOINT, ACCESS_ID, ACCESS_KEY, USERNAME, PASSWORD from tuya_iot import (TuyaOpenAPI, AuthType, TuyaOpenMQ, TuyaDeviceManager, TuyaHomeManager, TuyaDeviceListener, TuyaDevice, TuyaTokenInfo, TUYA_LOGGER) TUYA_LOGGER.setLevel(logging.DEBUG) # Init openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY, AuthType.CUSTOM) openapi.connect(USERNAME, PASSWORD) openmq = TuyaOpenMQ(openapi) openmq.start() print("device test-> ", openapi.token_info.uid) # Get device list # assetManager = TuyaAssetManager(openapi) # devIds = assetManager.getDeviceList(ASSET_ID) # Update device status deviceManager = TuyaDeviceManager(openapi, openmq) homeManager = TuyaHomeManager(openapi, openmq, deviceManager) homeManager.update_device_cache() # # deviceManager.updateDeviceCaches(devIds) # device = deviceManager.deviceMap.get(DEVICE_ID) class tuyaDeviceListener(TuyaDeviceListener): def update_device(self, device: TuyaDevice): print("_update-->", device)
import logging from tuya_iot import TuyaOpenAPI, tuya_logger from env import * tuya_logger.setLevel(logging.DEBUG) # Init openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY) openapi.login(USERNAME, PASSWORD) # Get asset list of the user openapi.get('/v1.0/iot-03/users/assets', { 'parent_asset_id': '', 'page_no': 0, 'page_size': 100, }) # Get device list of the asset openapi.get('/v1.0/iot-02/assets/{}/devices'.format(ASSET_ID)) # Get device functions openapi.get('/v1.0/iot-03/devices/{}/functions'.format(DEVICE_ID)) # Get device status openapi.get('/v1.0/iot-03/devices/{}'.format(DEVICE_ID)) # Control device ## Set up the bright value to 25 commands = {'commands': [{'code': 'bright_value', 'value': 25}]} openapi.post('/v1.0/iot-03/devices/{}/commands'.format(DEVICE_ID), commands)