Ejemplo n.º 1
0
 def run(self):
     self.reading_thread = ThreadLooping(
         target=self.read, wait_time=self.min_result_freq_time)
     self.reading_thread.start()
     self.checking_thread = ThreadLooping(
         target=self.check, wait_time=self.min_result_freq_time)
     self.checking_thread.start()
  def __init__(self, plant_lib_path='./assets/plant_lib.json'):
    self.cfg = ConfigManager('Gardener')
    self.plant_lib = PlantLibrary(plant_lib_path)
    self.station_mgr = StationManager(self.plant_lib)

    self.logger = Logger()
    self.logging_interval_time = 300 # second = 5 minutes
    self.logging_thread = ThreadLooping(self._logging_handle, self.logging_interval_time)
class EnvironmentFactor:
    def __init__(self, name, info_in_lib=None):
        self.name = name
        self.is_ensure_living_environment = False
        self.ensure_thread = ThreadLooping(
            target=self._ensure_living_environment, wait_time=2)
        # self.parse_from_lib(info_in_lib)

    def parse_from_lib(self, info_in_lib):
        pass

    def _ensure_living_environment(self):
        """ Kiểm tra thông số môi trường có hợp lệ và đưa ra hành động cần thiết để điều chỉnh
    #### Một số tham số ẩn:
     - ``self``.**equipment_set**: Đối tượng quản lý trang thiết bị (cảm biến, van, bơm...)
     - ``self``.**user_plant**: Đối tượng lưu thông tin cây trồng (ngày trồng và thông tin liên kết từ plant library)
    """
        pass

    def _save_equipmentset_plantinfo(self, equipment_set, user_plant):
        self.equipment_set = equipment_set
        self.user_plant = user_plant

    def start_ensure_living_environment(self,
                                        equipment_set=None,
                                        user_plant=None):
        if equipment_set is not None and user_plant is not None:
            self._save_equipmentset_plantinfo(equipment_set, user_plant)
        if self.equipment_set is not None and self.user_plant is not None:
            self.ensure_thread.start()
        else:
            print("[EnvFactor] > equipment_set or user_plant is None")

    def stop_ensure_living_environment(self):
        self.ensure_thread.stop()

    def restart_ensure_living_environment(self):
        self.stop_ensure_living_environment()
        self.start_ensure_living_environment()
 def __init__(self, name, info_in_lib=None):
     self.name = name
     self.is_ensure_living_environment = False
     self.ensure_thread = ThreadLooping(
         target=self._ensure_living_environment, wait_time=2)
class DHT22(GPIOPin):
  def __init__(self, pin=None, serial_port=None, precision=2, retry=15, emulate_sensors=False):
    super().__init__(pin, False)
    self.name = "HuTemp"
    self.sensor = Adafruit_DHT.DHT22
    self.precision = precision
    self.default = (80, 20)
    # self.last_result = self.default # Commented for Simulation
    self.last_result = self.random # Simulation
    self.retry = retry
    self.is_normally = None
    self.min_result_freq_time = 10
    self.emulate_sensors = emulate_sensors

  def attach_serial_port(self, serial_port):
    self.serial_port = serial_port

  @property
  def value(self):
    return self.last_result

  @property
  def random(self):
    return (round(random.uniform(55,90),self.precision), round(random.uniform(25,32),self.precision))

  def read(self):
    humidity, temperature = Adafruit_DHT.read(self.sensor, self.pin)
    retry = 0
    while humidity is None or temperature is None or humidity > 100 or humidity < 0 or (temperature == 0 and humidity == 0):
      if self.emulate_sensors:
        self.last_result = self.random
        return self.last_result
      else:
        retry += 1
        humidity, temperature = Adafruit_DHT.read(self.sensor, self.pin)
        sleep(2)
        if retry >= self.retry:
          if self.is_normally or self.is_normally is None:
            print("[DHT22] > Hutemp module is failed to read.")
          return self.default
    humidity = 100 if humidity >= 99 else humidity
    hutemp = (round(humidity,self.precision), round(temperature,self.precision))
    self.last_result = hutemp
    return hutemp

  def run(self):
    self.reading_thread = ThreadLooping(target=self.read, wait_time=self.min_result_freq_time)
    self.reading_thread.start()
    self.checking_thread = ThreadLooping(target=self.check, wait_time=self.min_result_freq_time)
    self.checking_thread.start()
  
  def stop(self):
    self.reading_thread.stop()
    self.checking_thread.stop()

  def check(self):
    if self.value == self.default:
      if self.is_normally or self.is_normally is None:
        print("[DHT22] > Hutemp module is not working normally.")
        self.is_normally = False
        self.on_broken()
        self.on_state_change(self, False)
    else:
      if not self.is_normally or self.is_normally is None:
        print("[DHT22] > Hutemp module is working normally.")
        self.is_normally = True
        self.on_working()
        self.on_state_change(self, True)

  def on_broken(self):
    """override to add event listener for broken event"""
    pass

  def on_working(self):
    """override to add event listener for working good event"""
    pass

  def on_state_change(self, sensor, state):
    """override to add event listener for both working well and broken event"""
    pass
class Gardener:
  def __init__(self, plant_lib_path='./assets/plant_lib.json'):
    self.cfg = ConfigManager('Gardener')
    self.plant_lib = PlantLibrary(plant_lib_path)
    self.station_mgr = StationManager(self.plant_lib)

    self.logger = Logger()
    self.logging_interval_time = 300 # second = 5 minutes
    self.logging_thread = ThreadLooping(self._logging_handle, self.logging_interval_time)

  @property
  def auto(self):
    return self.cfg.getz('automation')

  @auto.setter
  def auto(self, state):
    print("[Gardener] > Automation mode is set to {}".format(state))
    self.cfg.set('automation', state)

  def start_working(self):
    print("[Gardener] >> Start working!")
    if self.auto:
      print("[Gardener] > Automation mode is on.")
      self.working_thread = threading.Thread(target=self._work)
      self.working_thread.start()
    else:
      print("[Gardener] > Automation mode is off.")

  def _work(self):
    # self.hydroponic_mgr.start_ensure_living_environment()
    self.station_mgr.run()
    self.start_logging()
    pass

  def keep_working(self):
    print("[Gardener] >> Keep working.")
    while True:
      sleep(1)
  
  def stop_working(self):
    print("[Gardener] >> Stop working.")
    try: self.working_thread.join()
    except: pass
    self.stop_tracking()
    
    self.station_mgr.stop_ensure_living_environment()

  def command_handle(self, station_id, equipment, state):
    self.station_mgr.set_state(station_id, equipment, state, 'UserSet')
  
  def get_station_info(self, station_id):
    station = self.station_mgr.get_station_by_id(station_id)
    return station.dump()

  def _logging_handle(self):
    for station in self.station_mgr.stations:
      temperature = station.equipment_set.sensors_mgr.temperature
      humidity = station.equipment_set.sensors_mgr.humidity
      if temperature is None or humidity is None:
        continue
      record = "{},{}".format(temperature, humidity)
      Logger.log(record, 'envs', './log/{}'.format(station.id))

  def start_logging(self):
    self.logging_thread.start()

  def stop_tracking(self):
    self.logging_thread.stop()

  def get_records_from(self, station_id, hours_ago=6):
    station = self.station_mgr.get_station_by_id(station_id)
    records = Logger.get_log('envs', './log/{}'.format(station.id), hours_ago)
    records_map = []
    for record in records:
      data = record[1].split(',')
      records_map.append([record[0], [float(data[0]), float(data[1])]])
    return records_map

  def plant_new_plant(self, station_id, plant_type, planting_date, alias):
    self.station_mgr.plant_new_plant(station_id, plant_type, planting_date, alias)

  def remove_plant(self, station_id, plant_id):
    self.station_mgr.remove_plant(station_id, plant_id)

  def attach_station(self, station_id, serial_port):
    self.station_mgr.attach_station(station_id, serial_port)

  def attach_serial_port(self, serial_port):
    self.station_mgr.attach_serial_port(serial_port)

  def update_station_sensors(self, station_id, sensors_data):
    self.station_mgr.update_station_sensors(station_id, sensors_data)

  def get_station_list(self):
    return self.station_mgr.stations
Ejemplo n.º 7
0
class SEN0161:
    def __init__(self,
                 i2c_address=0x04,
                 bus=1,
                 serial_port=None,
                 retry=0,
                 precision=3,
                 emulate_sensors=False):
        self.name = "pH_Meter"
        self.i2c_address = i2c_address
        self.bus = smbus.SMBus(bus)
        self.serial_port = serial_port
        self.precision = precision
        self.error_signal = -1
        self.last_result = self.error_signal
        self.is_normally = None
        self.min_result_freq_time = 4
        self.emulate_sensors = emulate_sensors

    def attach_serial_port(self, serial_port):
        self.serial_port = serial_port

    @property
    def value(self):
        return self.last_result

    @property
    def random(self):
        return round(random.uniform(5, 7), self.precision)

    def read(self):
        try:
            block = self.bus.read_i2c_block_data(self.i2c_address, 0, 4)
        except Exception as e:
            if self.is_normally or self.is_normally is None:
                if not self.emulate_sensors:
                    print(
                        "[pHMeter] > Unable to detect device on I2C address: {}."
                        .format(self.i2c_address),
                        flush=True)
                    self.last_result = self.error_signal
                else:
                    self.last_result = self.random
            return self.last_result
        pH = round(struct.unpack('f', bytearray(block))[0], self.precision)
        self.last_result = pH
        return pH

    def run(self):
        self.reading_thread = ThreadLooping(
            target=self.read, wait_time=self.min_result_freq_time)
        self.reading_thread.start()
        self.checking_thread = ThreadLooping(
            target=self.check, wait_time=self.min_result_freq_time)
        self.checking_thread.start()

    def stop(self):
        self.reading_thread.stop()
        self.checking_thread.stop()

    def check(self):
        if self.value == self.error_signal:
            if self.is_normally or self.is_normally is None:
                print("[pHMeter] > pHMeter module is failed to read.")
                self.is_normally = False
                self.on_broken()
                self.on_state_change(self, False)
        else:
            if not self.is_normally or self.is_normally is None:
                print("[pHMeter] > pHMeter module is working normally.")
                self.is_normally = True
                self.on_working()
                self.on_state_change(self, True)

    def on_broken(self):
        """override to add event listener for broken event"""
        pass

    def on_working(self):
        """override to add event listener for working well event"""
        pass

    def on_state_change(self, sensor, state):
        """override to add event listener for both working well and broken event"""
        pass