# Path: communication/Serial.py
# class Serial:
#     def __init__(self, port: str, baud_rate: str):
#         self.__port = port
#         self.__baud_rate = baud_rate
#         self.__message_buffer = ''
#         self.__serial = None
#         self.__receive_message_callback = None
# 
#     def add_callback(self, receive_message_callback):
#         self.__receive_message_callback = receive_message_callback
# 
#     def connect(self):
#         self.__serial = serial.Serial(self.__port, self.__baud_rate,timeout=0.5, writeTimeout=0.5)
# 
#     def disconnect(self):
#         self.__serial.close()
# 
#     def send(self, value: str):
#         self.__serial.write(value)
# 
#     def loop(self):
#         if self.__receive_message_callback is None:
#             return
#         received_data = self.__serial.read()
#         if received_data.decode() is False or received_data.decode() == '':
#             return
#         self.__message_buffer += received_data.decode()
#         if not self.__has_received_full_message():
#             return
#         self.__receive_message_callback(self.__message_buffer)
#         self.__message_buffer = ''
# 
#     def __has_received_full_message(self):
#         return True if self.__message_buffer[-1] == RobotSerialCommandsConverter.MESSAGE_TERMINATOR else False
# 
# Path: navigation/RobotSerialCommandsConverter.py
# class RobotSerialCommandsConverter:
#     MAX_ANGLE = 180
#     MIN_ANGLE = 0
#     MOTOR_COMMAND = 'M:{0}:{1}'
#     LIGHT_COMMAND = 'L:{0}'
#     MESSAGE_TERMINATOR = ';'
#     POWER_LIMITS = {'forward': {'max': 50, 'min': 0}, 'backward': {'max': -50, 'min': 0}}
#     DIRECTION_LIMITS = {'right': 50, 'left': -50}
# 
#     def get_steer_command(self, angle: int, percent_power: int, forward: bool) -> str:
#         direction = self.__get_converted_direction(angle)
#         power = self.__get_converted_power(percent_power, forward)
#         return self.MOTOR_COMMAND.format(direction, power)
# 
#     def get_lights_command(self, state: bool) -> str:
#         literal_state = {True: '1', False: '0'}
#         return self.LIGHT_COMMAND.format(literal_state[state])
# 
#     def __get_converted_power(self, percent_power: int, forward: bool) -> str:
#         power_limits_key = {True: 'forward', False: 'backward'}[forward]
#         return str(MathUtils.remap(
#                 percent_power, 0, 100,
#                 self.POWER_LIMITS[power_limits_key]['min'], self.POWER_LIMITS[power_limits_key]['max']))
# 
#     def __get_converted_direction(self, angle: int) -> int:
#         return MathUtils.remap(angle, self.MIN_ANGLE, self.MAX_ANGLE,
#                                self.DIRECTION_LIMITS['left'], self.DIRECTION_LIMITS['right'])
# 
# Path: navigation/LongRunningCommand.py
# class LongRunningCommand(Process):
#     """
#     Sends a serial command regularry for a period of time
#     """
#     SLEEP_INTERVAL = 0.1
# 
#     def __init__(self, serial: Serial, input_queue: Queue, command_max_duration: int):
#         Process.__init__(self)
#         self.__serial = serial
#         self.__input_queue = input_queue
#         self.__command_max_duration = command_max_duration
#         self.__stop = False
#         self.__command_started = 0
#         self.__last_command = None
# 
#     def run(self):
#         while not self.__stop:
#             command = self.__get_command()
#             time.sleep(self.SLEEP_INTERVAL)
#             if command is not None:
#                 self.__command_started = int(round(time.time() * 1000))
#                 self.__last_command = command
#             if command is None and int(round(time.time() * 1000)) - self.__command_started > self.__command_max_duration:
#                 continue
#             self.__serial.send(self.__last_command.encode())
#             print("Sending command:" + self.__last_command)
# 
#     def stop_process(self):
#         self.__stop = True
# 
#     def __get_command(self):
#         if not self.__input_queue.empty():
#             return self.__input_queue.get(False)
#         else:
#             return None


from multiprocessing import Queue
from flask import Flask, Response, request
from communication.Serial import Serial
from navigation.RobotSerialCommandsConverter import RobotSerialCommandsConverter
from navigation.LongRunningCommand import LongRunningCommand
import config




app = Flask(__name__)
serial = Serial(config.serial['port'], config.serial['baud_rate'])
serial.connect()
commands_converter = RobotSerialCommandsConverter()

communication_queue = Queue(maxsize=3)
process = LongRunningCommand(serial, communication_queue, 5000)

# Path: communication/Serial.py
# class Serial:
#     def __init__(self, port: str, baud_rate: str):
#         self.__port = port
#         self.__baud_rate = baud_rate
#         self.__message_buffer = ''
#         self.__serial = None
#         self.__receive_message_callback = None
# 
#     def add_callback(self, receive_message_callback):
#         self.__receive_message_callback = receive_message_callback
# 
#     def connect(self):
#         self.__serial = serial.Serial(self.__port, self.__baud_rate,timeout=0.5, writeTimeout=0.5)
# 
#     def disconnect(self):
#         self.__serial.close()
# 
#     def send(self, value: str):
#         self.__serial.write(value)
# 
#     def loop(self):
#         if self.__receive_message_callback is None:
#             return
#         received_data = self.__serial.read()
#         if received_data.decode() is False or received_data.decode() == '':
#             return
#         self.__message_buffer += received_data.decode()
#         if not self.__has_received_full_message():
#             return
#         self.__receive_message_callback(self.__message_buffer)
#         self.__message_buffer = ''
# 
#     def __has_received_full_message(self):
#         return True if self.__message_buffer[-1] == RobotSerialCommandsConverter.MESSAGE_TERMINATOR else False
# 
# Path: navigation/RobotSerialCommandsConverter.py
# class RobotSerialCommandsConverter:
#     MAX_ANGLE = 180
#     MIN_ANGLE = 0
#     MOTOR_COMMAND = 'M:{0}:{1}'
#     LIGHT_COMMAND = 'L:{0}'
#     MESSAGE_TERMINATOR = ';'
#     POWER_LIMITS = {'forward': {'max': 50, 'min': 0}, 'backward': {'max': -50, 'min': 0}}
#     DIRECTION_LIMITS = {'right': 50, 'left': -50}
# 
#     def get_steer_command(self, angle: int, percent_power: int, forward: bool) -> str:
#         direction = self.__get_converted_direction(angle)
#         power = self.__get_converted_power(percent_power, forward)
#         return self.MOTOR_COMMAND.format(direction, power)
# 
#     def get_lights_command(self, state: bool) -> str:
#         literal_state = {True: '1', False: '0'}
#         return self.LIGHT_COMMAND.format(literal_state[state])
# 
#     def __get_converted_power(self, percent_power: int, forward: bool) -> str:
#         power_limits_key = {True: 'forward', False: 'backward'}[forward]
#         return str(MathUtils.remap(
#                 percent_power, 0, 100,
#                 self.POWER_LIMITS[power_limits_key]['min'], self.POWER_LIMITS[power_limits_key]['max']))
# 
#     def __get_converted_direction(self, angle: int) -> int:
#         return MathUtils.remap(angle, self.MIN_ANGLE, self.MAX_ANGLE,
#                                self.DIRECTION_LIMITS['left'], self.DIRECTION_LIMITS['right'])
# 
# Path: navigation/LongRunningCommand.py
# class LongRunningCommand(Process):
#     """
#     Sends a serial command regularry for a period of time
#     """
#     SLEEP_INTERVAL = 0.1
# 
#     def __init__(self, serial: Serial, input_queue: Queue, command_max_duration: int):
#         Process.__init__(self)
#         self.__serial = serial
#         self.__input_queue = input_queue
#         self.__command_max_duration = command_max_duration
#         self.__stop = False
#         self.__command_started = 0
#         self.__last_command = None
# 
#     def run(self):
#         while not self.__stop:
#             command = self.__get_command()
#             time.sleep(self.SLEEP_INTERVAL)
#             if command is not None:
#                 self.__command_started = int(round(time.time() * 1000))
#                 self.__last_command = command
#             if command is None and int(round(time.time() * 1000)) - self.__command_started > self.__command_max_duration:
#                 continue
#             self.__serial.send(self.__last_command.encode())
#             print("Sending command:" + self.__last_command)
# 
#     def stop_process(self):
#         self.__stop = True
# 
#     def __get_command(self):
#         if not self.__input_queue.empty():
#             return self.__input_queue.get(False)
#         else:
#             return None


# Path: voice_commands.py
from multiprocessing import Queue
from flask import Flask, Response, request
from communication.Serial import Serial
from navigation.RobotSerialCommandsConverter import RobotSerialCommandsConverter
from navigation.LongRunningCommand import LongRunningCommand
import config





app = Flask(__name__)
serial = Serial(config.serial['port'], config.serial['baud_rate'])
serial.connect()
commands_converter = RobotSerialCommandsConverter()

communication_queue = Queue(maxsize=3)
process = LongRunningCommand(serial, communication_queue, 5000)

process.daemon = True