def set_alarm_max(self, start, stop, timer_on, timer_off, light_state, door_state, duration_on, settle, powerswitches): self.config['alarm_max'] = { 'timer_start': start, 'timer_stop': stop, 'timer_on': None if not terrariumUtils.is_float(timer_on) else float(timer_on), 'timer_off': None if not terrariumUtils.is_float(timer_off) else float(timer_off), 'light_state': light_state, 'door_state': door_state, 'duration_on': None if not terrariumUtils.is_float(duration_on) else float(duration_on), 'settle': None if not terrariumUtils.is_float(settle) else float(settle), 'powerswitches': powerswitches if isinstance(powerswitches, list) else powerswitches.split(','), } self.timer_max_data['lastaction'] = 0 self.timer_max_data['power_state'] = False
def _address(self): address = super()._address if len(address) == 1: address.append(0) elif len(address) == 2: address[1] = int(address[1]) if terrariumUtils.is_float(address[1]) and terrariumUtils.is_float(address[1]) > 0 else 0 return address
def __dim_switch(self,value,duration): # When the dimmer is working, ignore new state changes. if not self.__dimmer_running: self.__dimmer_running = True self.__dimmer_state = (0.0 if not terrariumUtils.is_float(self.get_state()) else float(self.get_state())) value = (0.0 if not terrariumUtils.is_float(value) else float(value)) duration = (0.0 if not terrariumUtils.is_float(duration) else float(duration)) direction = (1.0 if self.__dimmer_state <= value else -1.0) distance = abs(self.__dimmer_state - value) if int(duration) == 0 or int(distance) == 0: steps = 1.0 else: steps = math.floor(min( (abs(duration) / terrariumPowerDimmerSource.DIMMER_MIN_TIMEOUT), (distance / terrariumPowerDimmerSource.DIMMER_MIN_STEP))) distance /= steps duration /= steps logger.debug('Dimmer settings: Steps: %s, Distance per step: %s%%, Time per step: %s, Direction: %s',steps, distance, duration, direction) for counter in range(int(steps)): self.__dimmer_state += (direction * distance) if self.get_type() == terrariumPowerDimmerPWM.TYPE: dim_value = terrariumPowerDimmerPWM.DIMMER_MAXDIM * ((100.0 - float(self.__dimmer_state)) / 100.0) dim_freq = terrariumPowerDimmerPWM.DIMMER_FREQ elif self.get_type() == terrariumPowerDimmerDC.TYPE: dim_value = terrariumPowerDimmerDC.DIMMER_MAXDIM * (float(self.__dimmer_state) / 100.0) dim_freq = terrariumPowerDimmerDC.DIMMER_FREQ for gpiopin in self.get_address().split(','): if terrariumUtils.to_BCM_port_number(gpiopin) is False: continue logger.debug('Dimmer animation: Step: %s, value %s%%, Dim value: %s, timeout %s',counter+1, self.__dimmer_state, dim_value, duration) self.__pigpio.hardware_PWM(terrariumUtils.to_BCM_port_number(gpiopin), dim_freq, int(dim_value) * 1000) # 5000Hz state*1000% dutycycle if duration > 0.0: sleep(duration) # For impatient people... Put the dimmer at the current state value if it has changed during the animation (DISABLED FOR NOW) # dim_value = terrariumSwitch.PWM_DIMMER_MAXDIM * ((100.0 - self.get_state()) / 100.0) # self.__pigpio.hardware_PWM(terrariumUtils.to_BCM_port_number(self.get_address()), 5000, int(dim_value) * 1000) # 5000Hz state*1000% dutycycle self.__dimmer_state = value self.__dimmer_running = False if self.callback is not None: self.callback(self.get_data()) logger.info('Power switch \'{}\' at address \'{}\' is done at value {}% in {} seconds'.format(self.get_name(), self.get_address(), self.get_state(), duration*steps))
def get_light(self): logger.debug('Read brightness value from sensor type \'%s\' at device %s with address %s' % (self.__class__.__name__,self.__device_number,self.__address)) light = self.__get_raw_data('light') if light is not None: light = 100.0 - ((light / 65536.0) * 100.0) logger.debug('Got data from brightness sensor type \'%s\' at device %s with address %s: brightness: %s' % (self.__class__.__name__,self.__device_number,self.__address,light)) return None if not terrariumUtils.is_float(light) else float(light)
def __init__(self, sensor_id, sensor_type, address, name = '', callback_indicator = None): self.__sensor_cache = terrariumSensorCache() self.__sensor_cache_key = None self.__current_value = None self.__erratic_errors = 0 self.__last_update = 0 self.exclude_avg = False self.sensor_id = sensor_id self.notification = True self.set_address(address) self.set_name(name) self.set_sensor_type(sensor_type,callback_indicator) self.set_alarm_min(0) self.set_alarm_max(0) self.set_limit_min(0) try: if not terrariumUtils.is_float(self.limit_max): self.set_limit_max(100) except AttributeError as ex: self.set_limit_max(100) # Default max diff: abs(limit_min-limit_max) * 25% self.set_max_diff(abs(self.get_limit_max() - self.get_limit_min()) / 4.0) logger.info('Loaded %s %s sensor \'%s\' on location %s.' % (self.get_type(),self.get_sensor_type(),self.get_name(),self.get_address())) self.update()
def _load_hardware(self): if not Path(self.__CMD).exists(): raise terrariumRelayLoadingException( 'Please install tool \'sispmctl\'. Can\'t controll EnergenieUSB relays without it.' ) address = self._address if len(address) == 1: address.append(1) elif address[1] is None or '' == address[1]: address[1] = 1 mode = '-d' if terrariumUtils.is_float(address[1]) else '-D' device = ' '.join([ self.__CMD, mode, str(address[1] if '-D' == mode else int(address[1]) - 1) ]) # TEMP data. Will be overwritten by the return value later on self._device['device'] = device if self._get_hardware_value() in [self.ON, self.OFF]: return device raise terrariumRelayLoadingException( f'Could not find the relay {self}.')
def get_humidity(self): #From datasheet convert this in human view. RH% = ((RH*125)/65536)-6 / RH = -6 + (125 * (SRH / 2 ^16)) #For convert 2 byte in number need MSB*256+LSB. logger.debug('Read humidity value from sensor type \'%s\' at device %s with address %s with command %s and timeout %s' % (self.__class__.__name__,self.__device_number,self.__address,self.__TRIGGER_HUMIDITY_NO_HOLD,self.__humidity_timeout)) bytedata = self.__get_raw_data(self.__TRIGGER_HUMIDITY_NO_HOLD,self.__humidity_timeout) humidity = ((bytedata[0]*256.0+bytedata[1])*125.0/65536.0)-6.0 logger.debug('Got data from humidity sensor type \'%s\' at device %s with address %s: byte data: %s, humidity: %s' % (self.__class__.__name__,self.__device_number,self.__address,bytedata,humidity)) return None if not terrariumUtils.is_float(humidity) else float(humidity)
def get_temperature(self): #From datasheet convert this in human view. Temp C = ((Temp_Code*175.72)/65536)-46.85 / T = -46.82 + (172.72 * (ST/2^16)) #For convert 2 byte in number need MSB*256+LSB. logger.debug('Read temperature value from sensor type \'%s\' at device %s with address %s with command %s and timeout %s' % (self.__class__.__name__,self.__device_number,self.__address,self.__TRIGGER_TEMPERATURE_NO_HOLD,self.__temperature_timeout)) bytedata = self.__get_raw_data(self.__TRIGGER_TEMPERATURE_NO_HOLD,self.__temperature_timeout) temperature = ((bytedata[0]*256.0+bytedata[1])*175.72/65536.0)-46.85 logger.debug('Got data from temperature sensor type \'%s\' at device %s with address %s: byte data: %s, temperature: %s' % (self.__class__.__name__,self.__device_number,self.__address,bytedata,temperature)) return None if not terrariumUtils.is_float(temperature) else float(temperature)
def _load_hardware(self): address = self._address if len(address) >= 2 and terrariumUtils.is_float(address[1]): # Set / enable power management self._device['power_mngt'] = terrariumUtils.to_BCM_port_number(address[1]) GPIO.setup(terrariumUtils.to_BCM_port_number(address[0]), GPIO.IN) # Data in return terrariumUtils.to_BCM_port_number(address[0])
def get_moisture(self): value = None logger.debug('Read moisture value from sensor type \'%s\' with address %s' % (self.__class__.__name__,self.__address)) self.__get_raw_data() if terrariumUtils.is_float(self.__cached_data['moisture']): value = float(self.__cached_data['moisture']) logger.debug('Got data from moisture sensor type \'%s\' with address %s: moisture: %s' % (self.__class__.__name__,self.__address,value)) return value
def get_battery(self): value = None logger.debug('Read firmware value from sensor type \'%s\' with address %s' % (self.__class__.__name__,self.__address)) self.__get_raw_data() if terrariumUtils.is_float(self.__cached_data['battery']): value = float(self.__cached_data['battery']) logger.debug('Got data from firmware sensor type \'%s\' with address %s: fertility: %s' % (self.__class__.__name__,self.__address,value)) return value
def get_light(self): value = None logger.debug('Read brightness value from sensor type \'%s\' with address %s' % (self.__class__.__name__,self.__address)) self.__get_raw_data() if terrariumUtils.is_float(self.__cached_data['light']): value = float(self.__cached_data['light']) logger.debug('Got data from brightness sensor type \'%s\' with address %s: brightness: %s' % (self.__class__.__name__,self.__address,value)) return value
def get_humidity(self): value = None logger.debug('Read humidity value from sensor type \'%s\' with address %s' % (self.__class__.__name__,self.__datapin)) self.__get_raw_data() if terrariumUtils.is_float(self.__cached_data['humidity']): value = float(self.__cached_data['humidity']) logger.debug('Got data from humidity sensor type \'%s\' with address %s: moisture: %s' % (self.__class__.__name__,self.__datapin,value)) return value
def get_moisture(self): logger.debug( 'Read moisture value from sensor type \'%s\' at device %s with address %s' % (self.__class__.__name__, self.__device_number, self.__address)) moisture = self.__get_raw_data('moisture') logger.debug( 'Got data from moisture sensor type \'%s\' at device %s with address %s: moisture: %s' % (self.__class__.__name__, self.__device_number, self.__address, moisture)) return None if not terrariumUtils.is_float(moisture) else float( moisture)
def _load_hardware(self): address = self._address if len(address) >= 2 and terrariumUtils.is_float(address[1]): # Set / enable power management self._device['power_mngt'] = terrariumUtils.to_BCM_port_number(address[1]) if self.HARDWARE == terrariumDHT11Sensor.HARDWARE: device = DHT11(terrariumUtils.to_BCM_port_number(address[0])) elif self.HARDWARE in [terrariumDHT22Sensor.HARDWARE, terrariumAM2302Sensor.HARDWARE]: device = DHT22(terrariumUtils.to_BCM_port_number(address[0])) return device
def get_uvb(self): value = None logger.debug('Read UVB value from sensor type \'%s\' with address %s' % (self.__class__.__name__, self.__address)) self.__get_raw_data() if terrariumUtils.is_float(self.__cached_data['uvb']): value = float(self.__cached_data['uvb']) logger.debug( 'Got data from UVA sensor type \'%s\' with address %s: UVB: %s' % (self.__class__.__name__, self.__address, value)) return value
def __get_raw_data(self): # Read 5 samples of data and get an average of it values = [] for counter in range(5): value = self.__sensor.value if terrariumUtils.is_float(value): values.append(float(value)) time.sleep(0.2) # sort values from low to high values.sort() # Calculate average. Exclude the min and max value. And therefore devide by 3 self.__value = round((sum(values[1:-1]) / (len(values) - 2)), 5)
def _get_data(self): # This will return the measured voltage of the analog device. values = [] for counter in range(self.__AMOUNT_OF_MEASUREMENTS): value = self.device.value if terrariumUtils.is_float(value): values.append(float(value)) sleep(0.2) # sort values from low to high values.sort() # Calculate average. Exclude the min and max value. return statistics.mean(values[1:-1])
def load_hardware(self): address = self.get_address().strip().split(',') self.__socket_nr = int(address[0].strip()) # Default we use the device counter option self.__device_type = '-d' # Check if custom device number or serial is entered self.__device = 0 if len(address) == 1 else address[1].strip() # If the device is not a number, it should be a string with an identifier in it if not terrariumUtils.is_float(self.__device): # Use the device serial identification self.__device_type = '-D' else: # If the user has enterd a number, it is probaly 1 to high. A human will enter device number 1 and not zero.... self.__device = int(self.__device) - 1
def __get_data(self, sensortype): value = None logger.debug('Read %s value from sensor type \'%s\' with address %s' % (sensortype, self.__class__.__name__, self.__address)) self.__get_raw_data() if 'firmware' == sensortype: value = self.__cached_data[sensortype].decode() elif terrariumUtils.is_float(self.__cached_data[sensortype]): value = float(self.__cached_data[sensortype]) if 'temperature' == sensortype: value /= 10.0 logger.debug( 'Got data from %s sensor type \'%s\' with address %s: temperature: %s' % (sensortype, self.__class__.__name__, self.__address, value)) return value
def _load_hardware(self): # Address value = Switch_number,board_serial (optional). When board_serial is missing, use the first found device and update the address.... address = self._address number_mode = terrariumUtils.is_float(address[1]) counter = 1 for (_, device_type, serial) in Driver().list_devices(): # Loop until we reatch the number (amount) or serial that is entered if (number_mode and counter != address[1]) or (not number_mode and address[1] != serial): counter += 1 continue device = serial device_type = terrariumRelayFTDI.SERIAL if device_type.lower().endswith('uart') else terrariumRelayFTDI.BITBANG self.address = f'{address[0]},{device}' return (serial,device_type)
def _load_hardware(self): self.__cache = terrariumCache() address = self._address if len(address) == 1: address.append(1) elif address[1] is None or '' == address[1]: address[1] = 1 number_mode = len(str(address[1])) <= 2 and terrariumUtils.is_float(address[1]) # Only reduce the boardnumber if in number mode if number_mode: address[1] = int(address[1]) address[1] -= 1 # Reduce board number by one, human start counting at 1, computers at 0 (zero) scan_regex = r'^(?P<serial>[^ ]+)\W(\[(?P<device>[^\]]+\]))\W\[id=\d\]$' counter = 0 cmd = self.__CMD + ['list'] try: data = subprocess.check_output(cmd).strip().decode('utf-8').strip().split('\n') except subprocess.CalledProcessError as ex: # Device does not exists.... return False for line in data: line = re.match(scan_regex,line) if line is not None: line = line.groupdict() if (number_mode and counter != address[1]) or (not number_mode and address[1] != line['serial']): counter += 1 continue self._device['device'] = line['serial'] self._device['type'] = 'v2' if 'mcp' in line['device'].lower() else '' self._device['switch'] = int(address[0]) if self._device['switch'] == 0: self._device['switch'] = self.__get_relay_count() self.address = '{},{}'.format(self._device['switch'],self._device['device']) break return self._device['device']
def load_data(self): data = None if self.get_address() is not None and len(self.get_address().split(',')) >= 1: address = self.get_address().split(',') data_pin = address[0] device = 0 if len(address[0]) == 1 else address[1] sensor = MCP3008(channel=int(data_pin), device=int(device)) values = [] for counter in range(5): value = sensor.value if terrariumUtils.is_float(value): values.append(float(value)) sleep(0.2) sensor = None # sort values from low to high values.sort() # Calculate average. Exclude the min and max value. And therefore devide by 3 data = round((sum(values[1:-1]) / (len(values)-2)),5) return data
def set_water_flow(self,value): if terrariumUtils.is_float(value): self.water_flow = float(value)
def set_power_wattage(self,value): if terrariumUtils.is_float(value): self.power_wattage = float(value)
def set_timer_off_duration(self,value): if terrariumUtils.is_float(value) and int(value) >= 0: self.__timer_off_duration = int(value) self.__calculate_time_table()
def set_dimmer_off_percentage(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_off_percentage = value if (0.0 <= value <= 100.0) else 100.0
def set_dimmer_off_duration(self,value): value = float(value) if terrariumUtils.is_float(value) else 0.0 self.__dimmer_off_duration = value if value >= 0.0 else 0.0
def set_dimmer_step(self,value): value = float(value) if terrariumUtils.is_float(value) else 100.0 self.__dimmer_step = value if value >= 0.0 else 100.0
def get_altitude(self): self.__get_raw_data() return None if not terrariumUtils.is_float( self.__current_altitude) else float(self.__current_altitude)