def setup_platform(hass, config, add_devices, discovery_info=None): """Set up of the Tuya switch.""" import pytuya devices = config.get(CONF_SWITCHES) switches = [] _LOGGER.debug("LocalTUYA: %s %s %s", str(CONF_DEVICE_ID), str(CONF_HOST), str(CONF_LOCAL_KEY)) outlet_device = TuyaCache( pytuya.OutletDevice(config.get(CONF_DEVICE_ID), config.get(CONF_HOST), config.get(CONF_LOCAL_KEY))) for object_id, device_config in devices.items(): switches.append( TuyaDevice(outlet_device, device_config.get(CONF_FRIENDLY_NAME, object_id), device_config.get(CONF_ICON), device_config.get(CONF_ID))) name = config.get(CONF_NAME) if name: switches.append( TuyaDevice(outlet_device, name, config.get(CONF_ICON), config.get(CONF_ID))) add_devices(switches)
def __init__(self, addresses="192.168.1.*"): print 'searching ' + addresses print 'should find/add devices now (indicated by [FOUND])...' # find all MAC address -> IP mappings self.addresses = addresses ans, unans = arping(addresses) # add them to a dict for r in ans: mac = r[1].hwsrc ip = r[1].psrc self.mac_to_ip[mac] = ip print '\n' # run through MAC addresses in config and see if we have an IP for oc in config.outlets: ip = self.networking__lookup_mac(oc[2]) # if we do, add it to outlet_configs and add the device to outlets if ip is not None: self.outlet_configs.append((oc[0], oc[1], ip)) self.outlets.append(pytuya.OutletDevice(oc[0], ip, oc[1])) print '[FOUND] found and added ' + str(oc[0]) + \ ', device #' + str(len(self.outlets)-1) print '\nDone searching.\n'
def setstatus(index, status, count): count += 1 # print count,index,status try: d = pytuya.OutletDevice(ids[index], ips[index], keys[index]) data = d.status() # NOTE this does NOT require a valid key # print data if isinstance(data, basestring): # print basestring time.sleep(2 * count) return setstatus(index, status, count) else: if status == data['dps']['1']: return status else: data = d.set_status(status) time.sleep(2) data = d.status() # print data return data except IOError as e: print "I/O error({0}): {1}".format(e.errno, e.strerror) time.sleep(2 * count) if count < 10: return setstatus(index, status, count) else: return False
def deviceInfo( deviceid, ip, key, vers ): returnedInfo = {} watchdog = 0 now = datetime.datetime.utcnow() iso_time = now.strftime("%Y-%m-%dT%H:%M:%SZ") returnedInfo["datetime"] = iso_time returnedInfo["deviceid"] = deviceid while True: try: d = pytuya.OutletDevice(deviceid, ip, key) if vers == '3.3': d.set_version(3.3) data = d.status() if(d): dpsKeys = data['dps'].keys() if vers == '3.3' and ('19' in dpsKeys): returnedInfo.update(getValuesFromDataPack(data, 19, 18, 20)) else: if '5' in dpsKeys: returnedInfo.update(getValuesFromDataPack(data, 5, 4, 6)) else: returnedInfo["result"] = "Incomplete response from plug: %s [%s]." % (deviceid, ip) break except KeyboardInterrupt: pass except: watchdog+=1 if(watchdog>RETRY): returnedInfo["result"] = "Incomplete response from plug%s [%s]." % (deviceid, ip) break sleep(2) return json.dumps(returnedInfo)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up of the Tuya switch.""" import pytuya name = config.get(CONF_NAME) dev_id = config.get(CONF_DEVICE_ID) host = config.get(CONF_HOST) local_key = config.get(CONF_LOCAL_KEY) min_temp = config.get(CONF_MIN_TEMP) max_temp = config.get(CONF_MAX_TEMP) protocol_version = config.get(CONF_PROTOCOL_VERSION) climate = [] climate_device = TuyaCache( pytuya.OutletDevice(config.get(CONF_DEVICE_ID), config.get(CONF_HOST), config.get(CONF_LOCAL_KEY)), protocol_version) climate.append( TuyaClimate(climate_device, config.get(CONF_NAME), None, None, None, None, TEMP_CELSIUS, min_temp, max_temp, protocol_version)) async_add_entities(climate)
def __init__(self, hass, entry): super().__init__( hass, _LOGGER, name=entry.data[CONF_NAME], update_interval=UPDATE_INTERVAL, ) self._device_id = entry.data[CONF_DEVICE_ID] self._ip_address = entry.data[CONF_IP_ADDRESS] self._local_key = entry.data[CONF_LOCAL_KEY] self._protocol = entry.data[CONF_PROTOCOL] self._force_fahrenheit = entry.options.get(CONF_FORCE_FAHRENHEIT, False) _LOGGER.debug("force_fahrenheit is {}".format(self._force_fahrenheit)) self._pytuya = pytuya.OutletDevice(self._device_id, self._ip_address, self._local_key) self._pytuya.set_version(float(self._protocol)) self._cached_status = None self._cached_status_time = None self._units = hass.config.units self._lock = Lock() self._unsub = entry.add_update_listener(async_update_listener)
def deviceInfo(deviceid, ip, localkey): counter = 0 retryCount = 4 while True: try: d = pytuya.OutletDevice(deviceid, ip, localkey) data = d.status() if (d): devId = data['devId'] power = (float(data['dps']['5']) / 10.0) current = float(data['dps']['4'] * 0.001) voltage = (float(data['dps']['6']) / 10.0) return devId, power, current, voltage except: counter += 1 if (counter > retryCount): print "ERROR: No response from plug %s [%s]." % (deviceid, ip) return (0.0) sleep(2)
def setTuyaStatus(self, devid, newstatus, switch=1): done = False for attempt in ("first", "second", "third"): try: logger.logDebug("%s try to set status on %s" % (attempt, devid)) key = CFG.DEVICES[devid] tuyadev = pytuya.OutletDevice(devid, key[0], key[1]) status = tuyadev.status()['dps'][str(switch)] if status == newstatus: logger.logDebug("status already set, skipping %s" % devid) break tuyadev.set_status(newstatus, switch) time.sleep(CFG.SLEEP_INTERVAL) status = tuyadev.status()['dps'][str(switch)] if status == newstatus: logger.logDebug("status successfully set %s" % devid) done = True except: logger.logError("failed to set status of %s" % devid) if done: break
def deviceInfo( deviceid, ip ): watchdog = 0 while True: try: d = pytuya.OutletDevice(deviceid, ip, '0123456789abcdef') data = d.status() if(d): print('Dictionary %r' % data) print('Switch On: %r' % data['dps']['1']) if '5' in data['dps'].keys(): print('Power (W): %f' % (float(data['dps']['5'])/10.0)) print('Current (mA): %f' % float(data['dps']['4'])) print('Voltage (V): %f' % (float(data['dps']['6'])/10.0)) return(float(data['dps']['5'])/10.0) else: return(0.0) else: return(0.0) break except KeyboardInterrupt: pass except: watchdog+=1 if(watchdog>RETRY): print("ERROR: No response from plug %s [%s]." % (deviceid,ip)) return(0.0) sleep(2)
def _discover(self): self._discovering = True self.device = None while not self.device: self.logger.debug('Discovering TuYa devices on network...') try: devices = self.discover_devices() except: self.logger.error('Error discovering devices, aborting') self._discovering = False return self.logger.debug('Found {} TuYa devices'.format(len(devices))) for device in devices: self.logger.debug('Checking device {}'.format(device)) if self.is_valid_device(device): self.ip = device.ip self.mac = device.mac self.deviceID = self.get_deviceID() self.device = pytuya.OutletDevice(self.deviceID, self.ip, '1') break else: self.logger.debug('No valid devices, trying again in 1 second') sleep(1) self.logger.info('Selected device \"{}\" with MAC {}'.format( self.ip, self.mac)) self._discovering = False
def deviceInfo(deviceid, ip, key, vers): watchdog = 0 while True: try: d = pytuya.OutletDevice(deviceid, ip, key) if vers == '3.3': d.set_version(3.3) data = d.status() if (d): print('Dictionary %r' % data) print('Switch On: %r' % data['dps']['1']) if vers == '3.3': if '19' in data['dps'].keys(): w = (float(data['dps']['19']) / 10.0) mA = float(data['dps']['18']) V = (float(data['dps']['20']) / 10.0) day = (w / 1000.0) * 24 week = 7.0 * day month = (week * 52.0) / 12.0 print('Power (W): %f' % w) print('Current (mA): %f' % mA) print('Voltage (V): %f' % V) print( 'Projected usage (kWh): Day: %f Week: %f Month: %f' % (day, week, month)) return (float(data['dps']['19']) / 10.0) else: return (0.0) else: if '5' in data['dps'].keys(): w = (float(data['dps']['5']) / 10.0) mA = float(data['dps']['4']) V = (float(data['dps']['6']) / 10.0) day = (w / 1000.0) * 24 week = 7.0 * day month = (week * 52.0) / 12.0 print('Power (W): %f' % w) print('Current (mA): %f' % mA) print('Voltage (V): %f' % V) print( 'Projected usage (kWh): Day: %f Week: %f Month: %f' % (day, week, month)) return (float(data['dps']['5']) / 10.0) else: return (0.0) else: return (0.0) break except KeyboardInterrupt: pass except OSError as o: watchdog += 1 if (watchdog > RETRY): print("OSERROR: No response from plug %s [%s] %s." % (deviceid, ip, o.strerror)) return (0.0) sleep(2)
def test_status(self): d = pytuya.OutletDevice('DEVICE_ID_HERE', 'IP_ADDRESS_HERE', LOCAL_KEY) d._send_receive = MagicMock(side_effect=mock_send_receive_status) result = d.status() # Make sure mock_send_receive_set_timer() has been called twice with correct parameters self.assertEqual(result['test_result'], "SUCCESS")
def __init__(self, device_id, host, local_key, protocol): self._device = pytuya.OutletDevice(device_id, host, local_key) self._device.set_version(float(protocol)) self._cached_status = '' self._cached_status_time = 0 self._lock = Lock()
def getstatus(index): # print index try: d = pytuya.OutletDevice(ids[index], ips[index], keys[index]) data = d.status() return data['dps']['1'] except: print "Unexpected error:", sys.exc_info()[0] return False
def test_set_status(self): d = pytuya.OutletDevice('DEVICE_ID_HERE', 'IP_ADDRESS_HERE', LOCAL_KEY) d._send_receive = MagicMock(side_effect=mock_send_receive_set_status) result = d.set_status(True, 1) result = result.decode(mock_byte_encoding) # Python 3 (3.5.4 and earlier) workaround to json stdlib "behavior" https://docs.python.org/3/whatsnew/3.6.html#json result = json.loads(result) # Make sure mock_send_receive_set_timer() has been called twice with correct parameters self.assertEqual(result['test_result'], "SUCCESS")
def init_devices(): global devices global groups groups = secrets.GROUPS devices_info = secrets.DEVICES_INFO for dev_name in devices_info.keys(): dev_info = devices_info[dev_name] devices[dev_name] = pytuya.OutletDevice(dev_info['id'], dev_info['ip'], dev_info['key'])
def __init__(self, device_id, ip_address, local_key, protocol): self._device_id = device_id self._ip_address = ip_address self._local_key = local_key self._protocol = protocol self._device = pytuya.OutletDevice(device_id, ip_address, local_key) self._device.set_version(float(protocol)) self._cached_status = None self._cached_status_time = None self._lock = Lock() self.update()
def powerIntent(): d = pytuya.OutletDevice('XXXXXXXXXXXXXXXXXXXX', 'YYY.YYY.YYY.YYY', 'ZZZZZZZZZZZZZZZZ') data = d.status() rt_state = data['dps']['1'] if rt_state: speech_text = 'Your RecTec is powered is on.' return statement(speech_text).simple_card('Power', speech_text) else: speech_text = 'Your RecTec is powered is off.' return statement(speech_text).simple_card('Power', speech_text)
def setup_platform(hass, config, add_devices, discovery_info=None): """Set up of the Tuya switch.""" import pytuya add_devices([ TuyaLocalDevice( pytuya.OutletDevice( config.get(CONF_DEVICE_ID), config.get(CONF_HOST), config.get(CONF_LOCAL_KEY), ), config.get(CONF_NAME), config.get(CONF_ID)) ])
def test_set_timer(self): d = pytuya.OutletDevice('DEVICE_ID_HERE', 'IP_ADDRESS_HERE', LOCAL_KEY) d._send_receive = MagicMock(side_effect=mock_send_receive_set_timer) # Reset call_counter and start test mock_send_receive_set_timer.call_counter = 0 result = d.set_timer(6666) result = result[result.find(b'{'):result.rfind(b'}') + 1] result = json.loads(result.decode()) # Make sure mock_send_receive_set_timer() has been called twice with correct parameters self.assertEqual(result['test_result'], "SUCCESS")
def deviceInfo( deviceid, ip, key, vers ): watchdog = 0 now = datetime.datetime.utcnow() iso_time = now.strftime("%Y-%m-%dT%H:%M:%SZ") while True: try: d = pytuya.OutletDevice(deviceid, ip, key) if vers == '3.3': d.set_version(3.3) data = d.status() if(d): sw =data['dps']['1'] if vers == '3.3': if '19' in data['dps'].keys(): w = (float(data['dps']['19'])/10.0) mA = float(data['dps']['18']) V = (float(data['dps']['20'])/10.0) ret = "{ \"datetime\": \"%s\", \"switch\": \"%s\", \"power\": \"%s\", \"current\": \"%s\", \"voltage\": \"%s\" }" % (iso_time, sw, w, mA, V) pub_mqtt( w, mA, V ) return(ret) else: ret = "{ \"switch\": \"%s\" }" % sw return(ret) else: if '5' in data['dps'].keys(): w = (float(data['dps']['5'])/10.0) mA = float(data['dps']['4']) V = (float(data['dps']['6'])/10.0) ret = "{ \"datetime\": \"%s\", \"switch\": \"%s\", \"power\": \"%s\", \"current\": \"%s\", \"voltage\": \"%s\" }" % (iso_time, sw, w, mA, V) pub_mqtt( w, mA, V ) return(ret) else: ret = "{ \"switch\": \"%s\" }" % sw return(ret) else: ret = "{\"result\": \"Incomplete response from plug %s [%s].\"}" % (deviceid,ip) return(ret) break except KeyboardInterrupt: pass except: watchdog+=1 if(watchdog>RETRY): ret = "{\"result\": \"ERROR: No response from plug %s [%s].\"}" % (deviceid,ip) return(ret) sleep(2)
def get(self, identifier): url = 'http://localhost:5001/outlet/' + identifier response = requests.request("GET", url).json() device_data = response['data'] device_id = device_data['device_id'] ip = device_data['ip'] local_key = device_data['local_key'] d = pytuya.OutletDevice(device_id, ip, local_key) data = d.status() state = data['dps']['1'] return {'message': 'Success', 'data': {'state': state}}, 200
def deviceRaw(deviceid, ip, key, vers): """Poll Device for Status - raw DPS response rawData = tuyapower.deviceRaw(id, ip, key, vers) Parameters : id = Device ID e.g. 01234567891234567890 ip = Device IP Address e.g. 10.0.1.99 key = Device Key e.g. 0123456789abcdef vers = Version of Protocol 3.1 or 3.3 Response : rawData = Data response from device """ watchdog = 0 while True: data = False if(api == "tinytuya"): d = tinytuya.OutletDevice(deviceid, ip, key) else: d = pytuya.OutletDevice(deviceid, ip, key) if vers == "3.3": d.set_version(3.3) try: data = d.status() except KeyboardInterrupt: log.info( "CANCEL: Received interrupt from user while polling plug %s [%s]." % (deviceid, ip) ) except: watchdog += 1 if watchdog > RETRY: log.info( "TIMEOUT: No response from plug %s [%s] after %s attempts." % (deviceid, ip, RETRY) ) return ("ERROR: Timeout polling device") try: sleep(2) continue except KeyboardInterrupt: log.info( "CANCEL: Received interrupt from user while polling plug %s [%s]." % (deviceid, ip) ) return(data)
def test_set_timer(self): d = pytuya.OutletDevice('ID', 'IP_ADDRESS_HERE', LOCAL_KEY) d._send_receive = MagicMock(side_effect=mock_send_receive_set_timer) # Reset call_counter and start test mock_send_receive_set_timer.call_counter = 0 result = d.set_timer(6666) result = result[result.find(b'{'):result.rfind(b'}') + 1] result = result.decode( mock_byte_encoding) # Python 3 (3.5.4 and earlier) workaround to json stdlib "behavior" https://docs.python.org/3/whatsnew/3.6.html#json result = json.loads(result) # Make sure mock_send_receive_set_timer() has been called twice with correct parameters self.assertEqual(result['test_result'], "SUCCESS")
def everythingIntentResponse(): d = pytuya.OutletDevice('XXXXXXXXXXXXXXXXXXXX', 'YYY.YYY.YYY.YYY', 'ZZZZZZZZZZZZZZZZ') data = d.status() rt_state = data['dps']['1'] if rt_state: everything_text = 'Your RecTec is powered is on' else: everything_text = 'Your RecTec is powered is off' target = ', Target temperature is %r' % data['dps']['102'] everything_text += target current = ', Current temperature is %r' % data['dps']['103'] everything_text += current probea = ', Probe A temperature is %r' % data['dps']['105'] everything_text += probea probeb = ', Probe B temperature is %r' % data['dps']['106'] everything_text += probeb return statement(everything_text).simple_card('Everything', everything_text)
def deviceInfo(deviceid, ip, localkey): watchdog = 0 while True: try: d = pytuya.OutletDevice(deviceid, ip, localkey) data = d.status() if (d): print('Dictionary %r' % data) print('Switch On: %r' % data['dps']['1']) if '5' in data['dps'].keys(): #print('Power (W): %f' % (float(data['dps']['5'])/10.0)) #print('Current (mA): %f' % float(data['dps']['4'])) #print('Voltage (V): %f' % (float(data['dps']['6'])/10.0)) mqttc = mqtt.Client(MQTTUSER) mqttc.username_pw_set(MQTTUSER, MQTTPASSWORD) mqttc.connect(MQTTSERVER, 1883) mqttc.publish(MQTTTOPIC + "watt", str(float(data['dps']['5']) / 10.0), retain=False) mqttc.publish(MQTTTOPIC + "current", data['dps']['4'], retain=False) mqttc.publish(MQTTTOPIC + "voltage", str(float(data['dps']['6']) / 10.0), retain=False) mqttc.loop(2) return (float(data['dps']['5']) / 10.0) else: return (0.0) else: return (0.0) break except KeyboardInterrupt: pass except Exception as e: watchdog += 1 if (watchdog > RETRY): print("ERROR: No response from plug %s [%s]." % (deviceid, ip)) print(e) return (0.0) sleep(2)
def readVal(): for device in devices: try: print("Polling from " + device["name"] + " on vpin " + str(device["vpin"])) d = pytuya.OutletDevice(device["id"], device["ip"], device["key"]) data = d.status() # NOTE this does NOT require a valid key print('Dictionary %r' % data) print('state (bool, true is ON) %r' % data['dps']['1'] ) # Show status of first controlled switch on device output = str(data['dps']['4']) print(output) if (output is not None and output.isnumeric()): print('Output: ', output) val = float(output) val /= 1000 print('Sending: ', val) except Exception as e: print(e)
def sendCommand(self, cmd, plugip, args=None, tries=1): self._tuyasmartplug_logger.debug('Sending command: %s to %s' % (cmd, plugip)) plug = self.plug_search(self._settings.get(["arrSmartplugs"]), "ip", plugip) device = pytuya.OutletDevice(plug['id'], plug['ip'], plug['localKey']) commands = { 'info': ('status', None), 'on': ('set_status', True), 'off': ('set_status', False), 'countdown': ('set_timer', None), } try: command, arg = commands[cmd] func = getattr(device, command, None) if not func: self._tuyasmartplug_logger.debug("No such command '%s'" % command) return False if args: func(args) elif arg is not None: func(arg) else: func() time.sleep(0.5) ret = device.status() self._tuyasmartplug_logger.debug('Status: %s' % str(ret)) return ret except socket.error as e: if e.errno == 104: if tries <= 3: self._tuyasmartplug_logger.debug("Connection refused... Trying again soon") time.sleep(1) return self.sendCommand(cmd, plugip, args, tries + 1) self._tuyasmartplug_logger.debug("Too many failed attempts") return False self._tuyasmartplug_logger.debug("Network error") return False except: self._tuyasmartplug_logger.debug('Something went wrong while running the command') return False
import pytuya import config import requests from time import sleep import sys from logzero import logger from dateutil import parser from datetime import datetime, timedelta d = pytuya.OutletDevice(config.DEVICE_ID, config.IP_ADDRESS, config.LOCAL_KEY) data = d.status() logger.info('Dictionary %r' % data) logger.info( 'state (bool, true is ON) %r' % data['dps']['1']) # Show status of first controlled switch on device def get_status(): logger.info("Getting Status") try: return requests.get( f'http://{config.MAD_IP}:{config.MAD_PORT}/get_status', auth=(config.MAD_USERNAME, config.MAD_PASSWORD)).json() except requests.exceptions.Timeout: logger.error('Connection to get_status timed-out') except requests.exceptions.RequestException as e: logger.error(str(e)) except Exception as e: logger.error("General error {0}".format(e))
def running_state(): d = pytuya.OutletDevice(config.PLUG_CONFIG['id'], config.PLUG_CONFIG['host'], config.PLUG_CONFIG['key']) data = d.status() return data['dps']['1']