class SerialListener: """ Responsible for listening to serial messages which are incoming through the port the given listener is assigned to. When the port the listener is responsible for is closed, the process should exit. """ def __init__(self, port_name: str): self.config = Config() self.baud_rate = self.config.get_serial_config_value("BaudRate") self.port_name = port_name self.serial_dao = SerialDao( self.port_name, int(self.config.get_serial_config_value("BaudRate")), int(self.config.get_serial_config_value("SerialTimeout"))) self.state_machine = SerialStateMachine(self.serial_dao) def listen(self): print("Listening".format(self.port_name)) timer = threading.Timer( 2.0 * float(self.config.get_serial_config_value("SerialTimeout")), self.exception) timer.start() self.state_machine.run() timer.cancel() def exception(self): raise TimeoutError("Timeout reached: Aborting process!")
def __init__(self, port_name: str): self.config = Config() self.baud_rate = self.config.get_serial_config_value("BaudRate") self.port_name = port_name self.serial_dao = SerialDao( self.port_name, int(self.config.get_serial_config_value("BaudRate")), int(self.config.get_serial_config_value("SerialTimeout"))) self.state_machine = SerialStateMachine(self.serial_dao)
def __init__(self, serial_dao: SerialDao): self.active_state = States.DISCONNECTED self.config = Config() self.states = { States.DISCONNECTED: self.disconnected, States.CONNECTED: self.connected, } self.serial_dao = serial_dao self.message_client = MessageClient() self.header_message_length = 11 self.done = False
def __init__(self, rds_dao: RdsDao, pillar_dao: PillarDao, cloud_orchestrator: CloudOrchestrator): self.config = Config() self.pipe_name = self.config.get_pillar_config_value("PipeName") self.rds_dao = rds_dao self.q_badge_currency = 0 self.c_badge_currency = 0 self.pillar_type = PillarType( int(self.config.get_master_config_value("PillarType"))) self.c_badge_target_currency = int( self.config.get_pillar_config_value("CBadgeTargetAmount")) self.q_badge_target_currency = int( self.config.get_pillar_config_value("QBadgeTargetAmount")) self.pillar_dao = pillar_dao self.cloud_orchestrator = cloud_orchestrator self.start_up()
class MessageClient: def __init__(self): self.config = Config() self.pipe_name = self.config.get_pillar_config_value("PipeName") def send_message_to_queue(self, message: PillarMessage): print("New message: {}".format(message)) pipe = os.open(self.pipe_name, os.O_WRONLY) os.write(pipe, message.to_bytes()) os.close(pipe)
class PillarDao: DRIP_VALUE = "55" def __init__(self, port_name): self.config = Config() self.ser = serial.Serial( port=port_name, baudrate=self.config.get_pillar_config_value("BaudRate"), parity=serial.PARITY_NONE) def write(self, message: str): self.send(message) sleep(0.12) self.send(PillarDao.DRIP_VALUE) sleep(2.4) def send(self, message: str): for index in range(0, len(message)): self.ser.write(message[index].encode('ascii'))
class SerialStateMachine: def __init__(self, serial_dao: SerialDao): self.active_state = States.DISCONNECTED self.config = Config() self.states = { States.DISCONNECTED: self.disconnected, States.CONNECTED: self.connected, } self.serial_dao = serial_dao self.message_client = MessageClient() self.header_message_length = 11 self.done = False def run(self): while not self.done: self.states[self.active_state]() def disconnected(self): # Send HELO Messages waiting for an ACK.You hello_message = HeaderMessage( OpCode.HELO, 0, int(self.config.get_master_config_value("PillarID")), 0) self.serial_dao.write(hello_message.to_serial_payload()) message = self.serial_dao.read(self.header_message_length) try: SerialUtil.validate_message_header(message) except TimeoutError as ex: return except ValueError as ex: print(ex) return header_message = HeaderMessage.build_header_object(message[1:]) if header_message.opcode == OpCode.ACK: print("Received ACK! Now connected to badge {}!".format( header_message.from_id)) self.active_state = States.CONNECTED else: print("Received unknown message! Skipping..") def connected(self): # Send DUMPQ messages waiting for a DUMPA. dump_q_message = HeaderMessage( OpCode.DUMPQ, 1, int(self.config.get_master_config_value("PillarID")), 0) dump_q_payload = PayloadMessage( int(self.config.get_master_config_value("PillarType"))) print("Sending dump Q message!") print("Dump Q Header: {}".format( dump_q_message.to_serial_payload(dump_q_payload))) self.serial_dao.write(dump_q_message.to_serial_payload(dump_q_payload)) print("Dump q payload: {}".format(dump_q_payload.to_serial_payload())) self.serial_dao.write_no_sync(dump_q_payload.to_serial_payload()) message = self.serial_dao.read(self.header_message_length) try: SerialUtil.validate_message_header(message) header_message = HeaderMessage.build_header_object(message[1:]) if header_message.opcode == OpCode.DUMPA: print("Received DUMPA! Sending update to cloud!") message = self.serial_dao.read(header_message.payload_len) payload_message = PayloadMessage.build_payload_object(message) pillar_message = PillarMessageTransformer\ .transform_serial_message_to_pillar_message(header_message, payload_message) self.message_client.send_message_to_queue(pillar_message) self.done = True else: print("Unexpected message type!") except TimeoutError as ex: print(ex) except ValueError as ex: print(ex) self.active_state = States.DISCONNECTED
class MessageProcessor: def __init__(self, rds_dao: RdsDao, pillar_dao: PillarDao, cloud_orchestrator: CloudOrchestrator): self.config = Config() self.pipe_name = self.config.get_pillar_config_value("PipeName") self.rds_dao = rds_dao self.q_badge_currency = 0 self.c_badge_currency = 0 self.pillar_type = PillarType( int(self.config.get_master_config_value("PillarType"))) self.c_badge_target_currency = int( self.config.get_pillar_config_value("CBadgeTargetAmount")) self.q_badge_target_currency = int( self.config.get_pillar_config_value("QBadgeTargetAmount")) self.pillar_dao = pillar_dao self.cloud_orchestrator = cloud_orchestrator self.start_up() def start_up(self): # Get the current currency count from the SQL DB query_template = "select quantity from {} where currency_type = {}" df = self.rds_dao.read( query_template.format(self.rds_dao.table_name, self.get_q_badge_currency_type().value)) self.q_badge_currency = df['quantity'].sum() print("Q Badge starting currency: {}".format(self.q_badge_currency)) df = self.rds_dao.read( query_template.format(self.rds_dao.table_name, self.get_c_badge_currency_type().value)) self.c_badge_currency = df['quantity'].sum() print("C Badge starting currency: {}".format(self.c_badge_currency)) self.pillar_dao.send(str(self.calculate_message_value())) def process(self): try: os.mkfifo(self.pipe_name) except OSError as ex: print(ex) if ex.errno != errno.EEXIST: raise ex with open(self.pipe_name) as messageQueue: input_line = "" while True: try: input_line = messageQueue.readline() if len(input_line) > 0: message = PillarMessage.build_message(input_line) self.handle_message(message) except ValueError as ex: print(input_line) print(ex) def handle_message(self, message: PillarMessage): if message.quantity == 0: # self.pillar_dao.restart(self.calculate_message_value()) return if message.badge_type == BadgeType.C_BADGE: self.c_badge_currency += message.quantity message.currency_type = CurrencyType(message.currency_type.value + 3) else: self.q_badge_currency += message.quantity payload = self.calculate_message_value() self.cloud_orchestrator.process_message(message) self.pillar_dao.write(str(payload)) def get_q_badge_currency_type(self): if self.pillar_type == PillarType.PARTY: return CurrencyType.COINS elif self.pillar_type == PillarType.PRIDE: return CurrencyType.CAMERAS else: return CurrencyType.LOCKS def get_c_badge_currency_type(self): if self.pillar_type == PillarType.PARTY: return CurrencyType.COCKTAILS elif self.pillar_type == PillarType.PRIDE: return CurrencyType.FLAGS else: return CurrencyType.KEYS def calculate_message_value(self): c_badge_percent = float( self.c_badge_currency) / self.c_badge_target_currency q_badge_percent = float( self.q_badge_currency) / self.q_badge_target_currency if c_badge_percent >= 1.0 and q_badge_percent >= 1.0: return 49 return int((c_badge_percent + q_badge_percent) * 49 / 2)
def __init__(self, port_name): self.config = Config() self.ser = serial.Serial( port=port_name, baudrate=self.config.get_pillar_config_value("BaudRate"), parity=serial.PARITY_NONE)
def __init__(self): self.config = Config() self.pipe_name = self.config.get_pillar_config_value("PipeName")
def __init__(self, quantity: int): config = Config() self.currency_type = CurrencyType(int(config.get_master_config_value("PillarType"))) self.quantity = quantity
def test_config(): config = Config() print(config.get_master_config_value("PillarType"))