def get_hardware_state(self): data = None if self.__firmware is None: logger.error( 'Sonoff device is not connected. Cannot read power switch state' ) return terrariumPowerSwitch.OFF else: data = re.match(self.VALID_SOURCE, self.get_address()) if data: data = data.groupdict() url = None if 'tasmota' == self.__firmware: url = 'http://{}/cm?cmnd=Power'.format(data['host']) if 'user' in data and 'password' in data: url += '&user={}&password={}'.format( data['user'], data['password']) elif 'espeasy' == self.__firmware: url = 'http://{}/json'.format(data['host']) elif 'espurna' == self.__firmware: if 'password' not in data: # Just add dummy value... data['password'] = '******' url = 'http://{}/apis?apikey={}'.format( data['host'], data['password']) state = terrariumUtils.get_remote_data(url) if state is None: logger.warning( 'Error reading Sonoff \'{}\' power state. So retruning last known state: {}' .format(self.get_name(), self.state)) return self.state if 'tasmota' == self.__firmware: return terrariumPowerSwitch.ON if terrariumUtils.is_true( state['POWER']) else terrariumPowerSwitch.OFF elif 'espeasy' == self.__firmware: return terrariumPowerSwitch.ON if terrariumUtils.is_true( state['POWER']) else terrariumPowerSwitch.OFF elif 'espurna' == self.__firmware: return terrariumPowerSwitch.ON if terrariumUtils.is_true( state['POWER']) else terrariumPowerSwitch.OFF return terrariumPowerSwitch.OFF
def __template_variables(self, template): variables = { 'lang': self.__terrariumEngine.config.get_language(), 'title': self.__config['title'], 'version': self.__config['version'], 'page_title': _(template.replace('_', ' ').capitalize()), 'temperature_indicator': self.__terrariumEngine.get_temperature_indicator(), 'distance_indicator': self.__terrariumEngine.get_distance_indicator(), 'volume_indicator': self.__terrariumEngine.get_volume_indicator(), 'horizontal_graph_legend': 1 if self.__terrariumEngine.get_horizontal_graph_legend() else 0, 'translations': self.__translations, 'device': self.__terrariumEngine.device, 'notifications': self.__terrariumEngine.notification, 'show_gauge_overview': terrariumUtils.is_true(self.__config['sensor_gauge_overview']) } if 'index' == template or 'profile' == template: variables['person_name'] = self.__terrariumEngine.get_profile_name( ) variables[ 'person_image'] = self.__terrariumEngine.get_profile_image() return variables
def _get_hardware_value(self): async def __get_hardware_state(): data = [] await self.device.update() plugs = [self.device] if len(self._address) == 1 else self.device.children for plug in plugs: data.append(plug.is_on) return data try: data = self.__state_cache.get_data(self._address[0]) if data is None: toggle = asyncio.run_coroutine_threadsafe(__get_hardware_state(), self._async.async_loop) data = toggle.result() self.__state_cache.set_data(self._address[0],data,cache_timeout=20) return self.ON if len(data) >= self._device['switch'] and terrariumUtils.is_true(data[self._device['switch']]) else self.OFF except RuntimeError as err: logger.exception(err) except Exception as ex: logger.exception(ex) return None
def _get_hardware_value(self): (device, nr) = self.device data = self._device_get(device, nr) if data is None: return None return self.ON if terrariumUtils.is_true(data) else self.OFF
def __checker(self): logger.info('Start terrariumPI door checker for door \'%s\'' % self.get_name()) while True: current_status = None if self.get_hardware_type() == 'gpio': current_status = terrariumDoor.OPEN if GPIO.input(terrariumUtils.to_BCM_port_number(self.get_address())) else terrariumDoor.CLOSED elif self.get_hardware_type() == 'remote' and (int(time.time()) - self.__last_check) >= terrariumDoor.REMOTE_TIMEOUT: current_status = None url_data = terrariumUtils.parse_url(self.get_address()) if url_data is False: logger.error('Remote url \'%s\' for door \'%s\' is not a valid remote source url!' % (self.get_address(),self.get_name())) else: data = terrariumUtils.get_remote_data(self.get_address()) if data is not None: current_status = terrariumDoor.OPEN if terrariumUtils.is_true(data) else terrariumDoor.CLOSED else: logger.warning('Remote door \'%s\' got error from remote source \'%s\'' % (self.get_name(),self.get_address())) self.__last_check = int(time.time()) logger.debug('Current door \'%s\' status: %s' % (self.get_name(),current_status)) if current_status != self.get_status(): logger.info('Door \'%s\' changed from %s to %s' % (self.get_name(),self.get_status(), current_status)) self.set_status(current_status) if self.callback is not None: self.callback(self.get_data()) sleep(terrariumDoor.CHECKER_TIMEOUT)
def _get_hardware_value(self): # self.device.reconnect_with_device() data = self.device.get_state(True) if data is None: return None return self.ON if terrariumUtils.is_true(data) else self.OFF
def set_state(self, state, force=False): changed = False logger.debug( 'Changing power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), self.get_state(), state, force)) if self.get_state() is not state or terrariumUtils.is_true(force): old_state = self.get_state() try: self.set_hardware_state(state, force) self.state = state logger.info( 'Changed power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), old_state, state, force)) except Exception as ex: print(ex) logger.error( 'Failed changing power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), self.get_state(), state, force)) if (old_state is not None) or (old_state is None and state == 0): # This is due to a bug that will graph 0 watt usage in the graph after rebooting. # Fix is to add power and water usage in constructor changed = old_state != self.get_state() if changed and self.callback is not None: self.callback(self.get_data()) return changed
def wrapper(*a, **ka): if required or terrariumUtils.is_true( self.__terrariumEngine.config.get_system() ['always_authenticate']): user, password = request.auth or (None, None) ip = request.remote_addr if request.get_header( 'X-Real-Ip') is None else request.get_header( 'X-Real-Ip') if user is None or not check(user, password): err = HTTPError(401, text) err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm) if user is not None or password is not None: self.__terrariumEngine.notification.message( 'authentication_warning', { 'ip': ip, 'username': user, 'password': password }, []) logger.warning( 'Incorrect login detected using username \'{}\' and password \'{}\' from ip {}' .format(user, password, ip)) return err return func(*a, **ka)
def update(self): if 'remote' in self.get_hardware_type(): url_data = terrariumUtils.parse_url(self.get_address()) if url_data is False: logger.error('Remote url \'%s\' for switch \'%s\' is not a valid remote source url!' % (self.get_address(),self.get_name())) else: try: data = requests.get(self.get_address(),auth=(url_data['username'],url_data['password']),timeout=3) if data.status_code == 200: data = data.json() json_path = url_data['fragment'].split('/') if 'fragment' in url_data and url_data['fragment'] is not None else [] for item in json_path: # Dirty hack to process array data.... try: item = int(item) except Exception, ex: item = str(item) data = data[item] if 'remote' == self.get_hardware_type(): self.set_state(terrariumUtils.is_true(data)) elif 'remote-dimmer' == self.get_hardware_type(): self.set_state(int(data)) else: logger.warning('Remote switch \'%s\' got error from remote source \'%s\':' % (self.get_name(),self.get_address(),data.status_code))
def set_state(self, state, force=False): changed = False logger.debug( 'Changing power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), self.get_state(), state, force)) if self.get_state() is not state or terrariumUtils.is_true(force): try: old_state = self.get_state() self.set_hardware_state(state, force) self.state = state changed = True logger.info( 'Changed power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), old_state, state, force)) except Exception as ex: print(ex) logger.error( 'Failed changing power switch \'{}\' of type \'{}\' at address \'{}\' from state \'{}\' to state \'{}\' (Forced:{})' .format(self.get_name(), self.get_type(), self.get_address(), self.get_state(), state, force)) if changed and self.callback is not None: self.callback(self.get_data()) return changed
def set_state(self, new_state, force = False): if new_state is None or not (self.OFF <= new_state <= self.ON): logger.error(f'Illegal value for relay {self}: {new_state}') return False changed = False if self.state != new_state or terrariumUtils.is_true(force): old_state = self.state try: self.__set_hardware_value(new_state) #logger.info(f'Changed relay {self} from state \'{old_state}\' to state \'{new_state}\'') except Exception as ex: logger.error(f'Error changing state for relay {self} to {new_state} :{ex}') if (old_state is not None) or (old_state is None and new_state == 0): # This is due to a bug that will graph 0 watt usage in the graph after rebooting. # Fix is to add power and water usage in constructor changed = old_state != self.state if changed and self.callback is not None: self.callback(self.id, self.state) return changed
def get_hardware_state(self): data = None if self.__firmware is None: if self.__retries < 5: self.__retries += 1 logger.warning('Sonoff device is not connected while reading the state. Reconnect attempt: {}'.format(self.__retries)) self.load_hardware() return self.get_hardware_state() else: logger.error('Sonoff device is not connected. Cannot read power switch state') return terrariumPowerSwitch.OFF data = re.match(self.VALID_SOURCE,self.get_address()) if data: data = data.groupdict() url = None if 'tasmota' == self.__firmware: url = self.url elif 'espeasy' == self.__firmware: url = 'http://{}/json'.format(data['host']) elif 'espurna' == self.__firmware: if 'password' not in data: # Just add dummy value... data['password'] = '******' url = 'http://{}/apis?apikey={}'.format(data['host'],data['password']) state = terrariumUtils.get_remote_data(url) if state is None: logger.warning('Error reading Sonoff \'{}\' power state. So returning last known state: {}'.format(self.get_name(),self.state)) return self.state if 'tasmota' == self.__firmware: for state_name, state_value in state.items(): if state_name.startswith('POWER'): return terrariumPowerSwitch.ON if terrariumUtils.is_true(state_value) else terrariumPowerSwitch.OFF elif 'espeasy' == self.__firmware: return terrariumPowerSwitch.ON if terrariumUtils.is_true(state['POWER']) else terrariumPowerSwitch.OFF elif 'espurna' == self.__firmware: return terrariumPowerSwitch.ON if terrariumUtils.is_true(state['POWER']) else terrariumPowerSwitch.OFF return terrariumPowerSwitch.OFF
def get_hardware_state(self): data = None url_data = terrariumUtils.parse_url(self.get_address()) if url_data is False: logger.error('Remote url \'%s\' for switch \'%s\' is not a valid remote source url!' % (self.get_address(),self.get_name())) else: data = terrariumUtils.get_remote_data(self.get_address()) return terrariumPowerSwitch.ON if terrariumUtils.is_true(data) else terrariumPowerSwitch.OFF
def _get_data(self): result = self.device.read() if not terrariumUtils.is_true(result['valid']): return None data = {} data['temperature'] = result['temp_c'] data['humidity'] = result['humidity'] return data
def wrapper(*a, **ka): if int(self.engine.settings['always_authenticate']) != -1 and ( required or terrariumUtils.is_true( self.engine.settings['always_authenticate'])): user, password = request.auth or (None, None) ip = request.remote_addr if request.get_header( 'X-Real-Ip') is None else request.get_header( 'X-Real-Ip') if user is None or not check(user, password): err = HTTPError(401, text) err.add_header('WWW-Authenticate', f'Basic realm="{realm}"') if user is not None or password is not None: self.engine.notification.message( 'authentication_error', { 'ip': ip, 'username': user, 'password': password }, []) logger.warning( f'Incorrect login detected using username \'{user}\' and password \'{password}\' from ip {ip}' ) return err if request.method.lower() in ['get', 'head']: self.__add_caching_headers(response, request.fullpath) if request.url.lower().endswith( '.html') or '/' == request.fullpath: user, password = request.get_cookie( 'auth', secret=self.cookie_secret) or (None, None) if check(user, password): # Update the cookie timeout so that we are staying logged in as long as we are working on the interface response.set_cookie('auth', request.get_cookie( 'auth', secret=self.cookie_secret), secret=self.cookie_secret, **{ 'max_age': 3600, 'path': '/' }) elif request.method.lower() in ['post', 'put', 'delete']: response.set_cookie('no-cache', '1', secret=None, **{ 'max_age': 90, 'path': '/' }) response.set_header('Cache-Control', 'no-cache') return func(*a, **ka)
def get_hardware_state(self): data = None try: port = pywemo.ouimeaux_device.probe_wemo(self.get_address()) if port is not None: device = pywemo.discovery.device_from_description(terrariumPowerSwitchWeMo.URL.format(self.get_address(), port), None) data = device.get_state() except Exception as err: # Ignore for now print(err) return terrariumPowerSwitch.ON if terrariumUtils.is_true(data) else terrariumPowerSwitch.OFF
def save_power_switches(self,data): update_ok = True for power_switch in self.get_power_switches(): if 'exclude' not in power_switch or not terrariumUtils.is_true(power_switch['exclude']): self.__config.remove_section('switch' + power_switch['id']) for power_switch_id in data: update_ok = update_ok and self.save_power_switch(data[power_switch_id].get_data()) if len(data) == 0: update_ok = update_ok and self.__save_config() return update_ok
def save_sensors(self,data): update_ok = True for sensor in self.get_sensors(): if 'exclude' not in sensor or not terrariumUtils.is_true(sensor['exclude']): self.__config.remove_section('sensor' + sensor['id']) for sensorid in data: update_ok = update_ok and self.save_sensor(data[sensorid].get_data()) if len(data) == 0: update_ok = update_ok and self.__save_config() return update_ok
def wrapper(*a, **ka): user, password = request.auth or (None, None) if required or terrariumUtils.is_true( self.__terrariumEngine.config.get_system() ['always_authenticate']): if user is None or not check(user, password): err = HTTPError(401, text) err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm) return err return func(*a, **ka)
def _get_hardware_value(self): cmd = f'{self.device} -n -g {self._address[0]}' data = terrariumUtils.get_script_data(cmd) if data is None: return None data = data.decode('utf-8').strip() relay_data = self.__STATUS_REGEX.search(data) if relay_data is not None and int(relay_data.group('relay_nr')) == int( self._address[0]): return self.ON if terrariumUtils.is_true( relay_data.group('status')) else self.OFF return None
def _set_hardware_value(self, state): action = 1 if state == self.ON else 0 url = f'{self.device}Power{self._address["nr"]}%20{action}' data = terrariumUtils.get_remote_data(url) if data is None: return False if 'POWER' in data: data = data['POWER'] elif f'POWER{self._address["nr"]}' in data: data = data[f'POWER{self._address["nr"]}'] return state == (self.ON if terrariumUtils.is_true(data) else self.OFF)
def get_hardware_state(self): data = None try: tmpdata = self.__device.get_sys_data() for channel_data in tmpdata['all']['digest']['togglex']: if int(self.get_address()) == int(channel_data['channel']): data = channel_data['onoff'] break except Exception as ex: print('Get hardware ex') print(ex) return terrariumPowerSwitch.ON if terrariumUtils.is_true(data) else terrariumPowerSwitch.OFF
def _set_hardware_value(self, state): action = ('-o' if state == self.ON else '-f') cmd = f'{self.device} -n {action} {self._address[0]}' data = terrariumUtils.get_script_data(cmd) if data is None: return False data = data.decode('utf-8').strip() relay_data = self.__STATUS_REGEX.search(data) if relay_data is not None and int(relay_data.group('relay_nr')) == int( self._address[0]): return state == (self.ON if terrariumUtils.is_true( relay_data.group('status')) else self.OFF) return False
def _get_hardware_value(self): EMAIL = terrariumUtils.decrypt(os.environ.get('MEROSS_EMAIL')) PASSWORD = terrariumUtils.decrypt(os.environ.get('MEROSS_PASSWORD')) if '' == EMAIL or '' == PASSWORD: logger.error('Meross cloud is not enabled.') return None data = self.__state_cache.get_data(self._device['device']) if data is None: return None return self.ON if len( data) >= self._device['switch'] and terrariumUtils.is_true( data[self._device['switch']]) else self.OFF
def get_hardware_state(self): data = [] async def __get_hardware_state(device, address): await device.update() strip = len(address) == 2 if strip: data.append(device.plugs[int(address[1]) - 1].is_on) else: data.append(device.is_on) address = self.__get_address() try: asyncio.run(__get_hardware_state(self._device, address)) except RuntimeError as err: return None return len(data) == 1 and terrariumUtils.is_true(data[0])
def _get_hardware_value(self): cache_key = self.__relay_cache_key() data = self.__cache.get_data(cache_key) if data is None and not self.__cache.is_running(cache_key): self.__cache.set_running(cache_key) cmd = self.__CMD + [self._device['device'], self.__get_board_type(), 'all', 'status'] data = subprocess.check_output(cmd).strip().decode('utf-8').strip() self.__cache.set_data(cache_key, data, cache_timeout = 20) self.__cache.clear_running(cache_key) if data is None: return None # Make string '0000' to list ['0','0','0','0'] data = list(data) return self.ON if terrariumUtils.is_true(data[self._device['switch']-1]) else self.OFF
def get_hardware_state(self): #data = None #print('Get hardware state cache data') data = self.__cache.get_data(self.__get_cache_key()) #print(data) #print('IS running: {}' .format(self.__cache.is_running(self.__get_cache_key()))) if data is None and not self.__cache.is_running( self.__get_cache_key()): self.__cache.set_running(self.__get_cache_key()) cmd = [ '/usr/bin/sudo', '/usr/bin/java', '-jar', 'DenkoviRelayCommandLineTool/DenkoviRelayCommandLineTool.jar', self.__device, self._get_board_type(), 'all', 'status' ] logger.debug('Running get hardware state command {}'.format(cmd)) #print('Running cmd: {}'.format(cmd)) try: data = subprocess.check_output(cmd).strip().decode('utf-8') #print('Got data: *{}*'.format(data)) self.__cache.set_data(self.__get_cache_key(), data) except Exception as err: # Ignore for now logger.error( 'Error getting hardware state for switch type {}, with error: {}' .format(self.get_type(), err)) self.__cache.clear_running(self.__get_cache_key()) if data is None: return terrariumPowerSwitch.OFF address = int(self.get_address()) % self._get_relay_count() if address == 0: address = self._get_relay_count() #print('Final state data at address{} : {}'.format(address,data[address-1:address])) return terrariumPowerSwitch.ON if terrariumUtils.is_true( data[address - 1:address]) else terrariumPowerSwitch.OFF
def _get_hardware_value(self): data = self.__cache.get_data(self.__cache_key) if data is None: # Cache is expired, so we update with new data # Get the overall state information url = f'{self.device}State' data = terrariumUtils.get_remote_data(url) if data is None: return None self.__cache.set_data(self.__cache_key, data, self._CACHE_TIMEOUT) if 'POWER' in data: data = data['POWER'] elif f'POWER{self._address["nr"]}' in data: data = data[f'POWER{self._address["nr"]}'] return self.ON if terrariumUtils.is_true(data) else self.OFF
def _set_hardware_value(self, state): async def __set_hardware_state(state): await self.device.update() plug = self.device if len(self._address) == 1 else self.device.children[self._device['switch']] if state != 0.0: await plug.turn_on() else: await plug.turn_off() return state data = self.__state_cache.get_data(self._address[0]) if data is not None and terrariumUtils.is_true(data[self._device['switch']]) == (state != 0.0): return True toggle = asyncio.run_coroutine_threadsafe(__set_hardware_state(state), self._async.async_loop) data = toggle.result() return data == state
def _get_hardware_value(self): data = self.__cache.get_data(self.__cache_key) if data is None: # Cache is expired, so we update with new data # Get the overall state information if not self.__connect(): raise terrariumRelayUpdateException( f'Failed updating relay {self}. Unable to login') data = self.device.getstatus() if data is None: return None self.__cache.set_data(self.__cache_key, data, self._CACHE_TIMEOUT) address = self._address status = self.ON if terrariumUtils.is_true( data['sockets'][address['nr'] - 1]) else self.OFF self.__logout() return status