def consume_serial(protocol: SerialProtocol): port_id = os.path.basename(protocol.serial_port) logger = get_logger_to_file("Consumer_{}".format(port_id)) parser = Parser() error_logger = get_logger("ConsumeErrorLog_{}".format(port_id)) def loop_and_parse(conn): while True: data = protocol.read_until(conn) try: parsed_data = parser.parse(data) for metric in parsed_data: logger.info(metric) except IOError: error_logger.info("Error to parse message:{}".format(data)) def connect_and_parse(): try: with protocol.connect() as conn: error_logger.info("Connected...") loop_and_parse(conn) except SerialException: error_logger.error("Error connecting to port {}".format( protocol.serial_port)) error_logger.error( "Waiting {}s to retry".format(CONNECTION_BACKOFF_TIME)) time.sleep(CONNECTION_BACKOFF_TIME) connect_and_parse() connect_and_parse()
class KnowledgeBase: logger = get_logger("KnowledgeBase") def __init__(self, rules_files=[], databases: List[Database] = [], prolog=Prolog()): self._file_path = [db.get_file_path() for db in databases] + rules_files self._prolog = prolog def _consult(self): for file_path in self._file_path: self._prolog.consult(file_path) def query(self, prolog_query, limit=-1): """This method runs a Prolog query over rules_files, metrics_fact_file and plants_fact_file. Args: prolog_query (str): Prolog query limit (int, optional): limit for the result size. Returns: [list[dict]]: List of dicts with all query answers. """ self._consult() return [result for result in self._prolog.query(prolog_query, limit)]
class SerialProtocol: logger = get_logger("Protocol") def __init__(self, serial_port): """Protocol class that handles message exchanges Args: serial_port (string): serial_port is Arduino's serial port. Usually is /dev/ttyACM0. """ self.serial_port = serial_port def connect(self): return serial.Serial(self.serial_port) def _send_message(self, message): encoded_message = str.encode(message) with self.connect() as conn: self.logger.debug("Sending message \"%s\"", encoded_message) conn.write(encoded_message) conn.flush() def read_until(self, conn): """Read the serial port until message is finish. Returns: str: Readed message. """ self.logger.debug("Reading ... ") sensor_data = conn.read_until(END) self.logger.debug("Readed message: \"%s\"", sensor_data) return sensor_data.decode("utf-8") def get_metrics(self): """Send message `getMetrics` Returns: [None]: Nothing """ self._send_message("{}".format(METRICS)) def water_in(self, pump, time): """Send message to water a plant for some time Args: pump (str): Pump id time (int): Time in seconds to water the plant Returns: [None]: Nothing """ self.logger.info( "Send message water_in: {}:{}:{}".format( WATER, pump, time)) message_info = [WATER, pump, str(time)] self._send_message(":".join(message_info))
def __init__(self, protocol, arduino_id, analyzer=Analyzer(), planner=Planner()): self._arduino_id = arduino_id self._protocol = protocol self._analyzer = analyzer self._planner = planner self._logger = get_logger(self.__class__.__name__)
def __init__(self, db: DatabaseMetric, log_files=LOG_FILES): self._db = db self._log_files = log_files self._logger = get_logger(self.__class__.__name__)
#!/usr/bin/env python3 # run every 6 hours from controller import get_logger from controller.config import DEVICES_ENDPOINT, SLOTS_ENDPOINT from controller.plants import Plants from social.arduino import Devices, Slots from database import DatabasePlant, DatabaseArduino logger = get_logger("UserData") arduinos = Devices(DEVICES_ENDPOINT) db_plants = DatabasePlant() db_arduino = DatabaseArduino() db_arduino.add_arduino_fact(arduinos) db_arduino.update_database() for arduino in arduinos.all: arduino_id = arduino["id"] logger.info("Load Plants data of arduino {}".format(arduino_id)) slots = Slots(SLOTS_ENDPOINT, arduino_id) plants = Plants(slots) plants.set_info() db_plants.add_plants_fact(arduino_id, plants) db_plants.update_database()
def __init__(self): self._memory_db = {} self._logger = get_logger(self.__class__.__name__)
#!/usr/bin/env python3 # run every hour from controller import get_logger from controller.log_parser import LogParser from controller.config import DEVICES_ENDPOINT from mape.cycle import Cycle from social.arduino import Devices from social.serial_protocol import SerialProtocol from database import DatabaseMetric logger = get_logger("Main") db_metrics = DatabaseMetric() log_parser = LogParser(db_metrics) if not log_parser.has_files(): logger.info("Logfiles do not exist") else: log_parser.parse_all_files() arduinos = Devices(DEVICES_ENDPOINT) for arduino in arduinos.all: protocol = SerialProtocol(arduino["port"]) logger.info("Start MAPE cycle") Cycle(protocol, arduino["id"]).start()
#!/usr/bin/env python3 import time import os from serial.serialutil import SerialException from controller import get_logger from controller.config import DEVICES_ENDPOINT from social.arduino import Devices from social.serial_protocol import SerialProtocol SLEEP_SECONDS = os.environ.get("WAIT_TIME", 15) logger = get_logger("Requester") arduinos = Devices(DEVICES_ENDPOINT) while True: logger.info("Waiting {} seconds".format(SLEEP_SECONDS)) time.sleep(SLEEP_SECONDS) logger.info("Start loop...") for arduino in arduinos.all: protocol = SerialProtocol(arduino["port"]) try: protocol.get_metrics() except SerialException: logger.error( "Error connecting to port {}, trying in next {} seconds". format(protocol.serial_port, SLEEP_SECONDS)) logger.info("End loop.")
import threading import time import os from serial.serialutil import SerialException from controller.config import DEVICES_ENDPOINT from controller import get_logger_to_file, get_logger from social.arduino import Devices from social.serial_protocol import SerialProtocol from social.parser import Parser CONNECTION_BACKOFF_TIME = 60 arduinos = Devices(DEVICES_ENDPOINT) protocols = [SerialProtocol(arduino["port"]) for arduino in arduinos.all] main_thread_logger = get_logger("Consumer") def consume_serial(protocol: SerialProtocol): port_id = os.path.basename(protocol.serial_port) logger = get_logger_to_file("Consumer_{}".format(port_id)) parser = Parser() error_logger = get_logger("ConsumeErrorLog_{}".format(port_id)) def loop_and_parse(conn): while True: data = protocol.read_until(conn) try: parsed_data = parser.parse(data) for metric in parsed_data: logger.info(metric)