def main() -> None: # Setup GPIO MOTOR1_PINS = [11, 13] MOTOR2_PINS = [16, 15] GPIO.setmode(GPIO.BOARD) GPIO.setup(MOTOR1_PINS, GPIO.OUT) GPIO.setup(MOTOR2_PINS, GPIO.OUT) # ------- logger.setLevel('INFO') scraper: Scraper = Scraper(DBStorage()) controller: Controller = Controller() sensors: List[ISensor] = [] sentries: List[ISentry] = [] horizontal_sensor: HorizontalCapacitanceSensor = HorizontalCapacitanceSensor( ) vertical_sensor: VerticalCapacitanceSensor = VerticalCapacitanceSensor() # TODO: add LCD display? # register all sensors sensors.append(PIM486()) sensors.append(ArduinoSerialInterface()) # register all sentries sentries.append(HumiditySentry()) sentries.append(LightSentry()) sentries.append(WaterSentry()) sentries.append(TemperatureSentry()) # spawn two threads and run one for any external events (user input etc) # run main loop scraper_runner: threading.Thread = threading.Thread(target=scraper.run, name="Scraper") controller_runner: threading.Thread = threading.Thread( target=controller.run, name="Controller") try: scraper_runner.start() controller_runner.start() while True: for s in sensors: s.poll() # poll for data for most of the sensors time.sleep(0.5) # poll the sensors periodically, serve IRQ's from some most important - pindas etc except KeyboardInterrupt: scraper.is_done = True controller.is_done = True scraper_runner.join() controller_runner.join() # deinit all sensors for s in sensors: s.close() # GPIO CLEANUP GPIO.cleanup() logInfo("Exiting")
def poll(self): # some sensors are poll'able raw_temp = self.bme280.get_temperature() raw_humidity = self.bme280.get_humidity() raw_press = self.bme280.get_pressure() logInfo(f"PIM486 got temp {raw_temp}") data = SensorData("pim486", "bme280", "temperature", datetime.now(), raw_temp) pub.sendMessage('sensor_read', args=data) pub.sendMessage('temperature_out', raw_temp)
def poll(self): # Turns on the sensor (if not already on) and returns a reading if not automationhat.output[self.output_pin_no]: automationhat.output[self.output_pin_no].write(True) raw_data = True if automationhat.analog[analog_input_pin_no].read( ) < CapacitanceSensor.threshold_voltage else False logInfo(f"{self.name} PINDA got reading {raw_data}") data = SensorData("capacitance_sensor", "horizontal", "distance", datetime.now(), raw_data) pub.sendMessage("sensor_read", args=data)
def poll(self): self.arduino_serial.write((bytes(ArduinoSerialInterface.get_msg, 'ascii'))) sleep(0.05) # Wait for arduino to process and send data raw_data = self.arduino_serial.readline()#[:-2] # Cut out endline char #data = str(data, encoding='ascii') if raw_data: logInfo(f"Arduino sent data over serial: {raw_data}") split = raw_data.split(' ') sensor_name = split[0] for i in range(1, len(split) - 1, 2): data = SensorData("Arduino", sensor_name, split[i], datetime.now(), split[i + 1]) pub.sendMessage("sensor_read", args=data) # nasty else for sentry data signalling if split[i] == "water": pub.sendMessage("water_level", split[i + 1]) elif split[i] == "humidity_near": pub.sendMessage("humidity_near", split[i + 1]) elif split[i] == "humidity_far": pub.sendMessage("humidity_far", split[i + 1])
def sensor_read_cb(self, args: SensorData = None): logInfo(f"Obtained the reading! DATA: {args}") self.message_queue.append(args) # TODO: thread safe list
def write_single(self, record: SensorData) -> bool: logInfo("Saving a single record data to DB") pass
def write_all(self, records: List[SensorData]) -> bool: logInfo("Saving data to DB") formatted = self.format_data(records) self.write_api.write(bucket=self.bucket_name, record=formatted)
def write_all(self, record) -> bool: logInfo("Saving data to file")
def motion_status_listener(self, args, rest=None): # Motor messages: FORWARD, BACKWARD, STOP # Position Status: INSIDE, OUTSIDE # Message format: [MOTOR_STATUS, POSITION_STATUS] logInfo(f"Controller received motion_status message {args}") motor_status, position_status = args if motor_status == "STOP": GPIO.output(MOTOR1_PINS[0], MOTOR1_STATIONARY[0]) GPIO.output(MOTOR1_PINS[1], MOTOR1_STATIONARY[1]) GPIO.output(MOTOR2_PINS[0], MOTOR2_STATIONARY[0]) GPIO.output(MOTOR2_PINS[1], MOTOR2_STATIONARY[1]) return if position_status == "INSIDE" and motor_status == "BACKWARD": logWarning( f"Controller received motion_status message {args}, but position_status is {position_status}\ and motor_status is {motor_status}") return if position_status == "OUTSIDE" and motor_status == "FORWARD": logWarning( f"Controller received motion_status message {args}, but position_status is {position_status}\ and motor_status is {motor_status}") return # MOTORS WILL RUN # Case 1: POSITION INSIDE, MOTOR FORWARD if position_status == "INSIDE" and motor_status == "FORWARD": logInfo( f"Controller received motion_status message {args}, Begin moving outside!" ) pinda_val = vertical_sensor.poll() if not pinda_val: logError( f"Controller received motion_status message {args}, vertical capacitance sensor not triggered before motion began!" ) return while pinda_val: pinda_val = vertical_sensor.poll() GPIO.output(MOTOR1_PINS[0], MOTOR1_FORWARD[0]) GPIO.output(MOTOR1_PINS[1], MOTOR1_FORWARD[1]) GPIO.output(MOTOR2_PINS[0], MOTOR2_FORWARD[0]) GPIO.output(MOTOR2_PINS[1], MOTOR2_FORWARD[1]) GPIO.output(MOTOR1_PINS[0], MOTOR1_STATIONARY[0]) GPIO.output(MOTOR1_PINS[1], MOTOR1_STATIONARY[1]) GPIO.output(MOTOR2_PINS[0], MOTOR2_STATIONARY[0]) GPIO.output(MOTOR2_PINS[1], MOTOR2_STATIONARY[1]) vertical_sensor.close() logInfo( f"Controller received motion_status message {args}, Envidrawer is outside!" ) # Case 2: POSITION OUTSIDE, MOTOR BACKWARD if position_status == "OUTSIDE" and motor_status == "BACKWARD": logInfo( f"Controller received motion_status message {args}, Begin moving inside!" ) pinda_val = horizontal_sensor.poll() if pinda_val: logError( f"Controller received motion_status message {args}, horizontal capacitance sensor triggered before motion began!" ) return while pinda_val: pinda_val = horizontal_sensor.poll() GPIO.output(MOTOR1_PINS[0], MOTOR1_BACKWARD[0]) GPIO.output(MOTOR1_PINS[1], MOTOR1_BACKWARD[1]) GPIO.output(MOTOR2_PINS[0], MOTOR2_BACKWARD[0]) GPIO.output(MOTOR2_PINS[1], MOTOR2_BACKWARD[1]) GPIO.output(MOTOR1_PINS[0], MOTOR1_STATIONARY[0]) GPIO.output(MOTOR1_PINS[1], MOTOR1_STATIONARY[1]) GPIO.output(MOTOR2_PINS[0], MOTOR2_STATIONARY[0]) GPIO.output(MOTOR2_PINS[1], MOTOR2_STATIONARY[1]) horizontal_sensor.close() logInfo( f"Controller received motion_status message {args}, Envidrawer is inside!" )
def dummy_listener(self, args, rest=None): logInfo(f"Controller Received message {args}")