# Path: plugins/io_base.py
# class IOBase:
#     def __init__(self, bus):
#         self.bus = bus
#         self.bus.subscribe(self.process_event, thread=False)
#         self.write_queue = Queue(10)
#         self.reader = threading.Thread(target=self.reader_thread)
#         self.reader.daemon = True
#         self.reader.start()
#         self.writer = threading.Thread(target=self.writer_thread)
#         self.writer.daemon = True
#         self.writer.start()
# 
#     def reader_thread(self):
#         raise NotImplementedError()
# 
#     def writer_thread(self):
#         raise NotImplementedError()
# 
#     def convert_data(self, data):
#         return data
# 
#     def process_event(self, ev):
#         try:
#             if ev.name == "leds_enabled":
#                 data = self.convert_data(ev.data)
#                 self.write_queue.put_nowait(data)
#         except queue.Full:
#             #TODO alert somehow without flooding?
#             pass
# 
# Path: plugins/arduino.py
# def getEventForButton(line):
#     if any([k in line for k in goalmap.keys()]):
#         parts = line.split()
#         data = {'source': 'serial', 'team': goalmap[parts[0]]}
# 
#         if len(parts) > 1:
#             data['duration'] = int(parts[1])
# 
#         if len(parts) > 2:
#             data['elapsed'] = int(parts[2])
# 
#         return 'goal_event', data
# 
#     if '_' in line:
#         btn, state = line.split('_')
#         btn = btnmap.get(btn, 'ERROR')
#         state = statemap.get(state, 'ERROR')
#         return 'button_event', {'source': 'serial', 'btn': btn, 'state': state}
# 
#     return None


import time
import serial
import glob
import logging
from .io_base import IOBase
from .arduino import getEventForButton
        return chr(value + ord('A'))

    def convert_data(self, data):
        return (self.__getArduinoValueFor(data) + "\n").encode("ascii")

    def reader_thread(self):
        while True:
            if not self.ser:
                self.open_serial()
            try:
                line = self.ser.readline()
                try:
                    line = line.decode('ascii').strip()
                    ev = getEventForButton(line)
                    if ev:
                        self.bus.notify(*ev)
                except Exception as e:
                    logger.exception("Error reading data")

            except serial.SerialException as e:
                logger.error("Error reading data: %s", e)
                self.open_serial()

    def writer_thread(self):
        while True:
            line = self.write_queue.get()
            if not self.ser:
                # Wait until the reader thread opens the serial line again
                # FIXME: What if the queue fills up?
                time.sleep(1)

# Path: plugins/io_base.py
# class IOBase:
#     def __init__(self, bus):
#         self.bus = bus
#         self.bus.subscribe(self.process_event, thread=False)
#         self.write_queue = Queue(10)
#         self.reader = threading.Thread(target=self.reader_thread)
#         self.reader.daemon = True
#         self.reader.start()
#         self.writer = threading.Thread(target=self.writer_thread)
#         self.writer.daemon = True
#         self.writer.start()
# 
#     def reader_thread(self):
#         raise NotImplementedError()
# 
#     def writer_thread(self):
#         raise NotImplementedError()
# 
#     def convert_data(self, data):
#         return data
# 
#     def process_event(self, ev):
#         try:
#             if ev.name == "leds_enabled":
#                 data = self.convert_data(ev.data)
#                 self.write_queue.put_nowait(data)
#         except queue.Full:
#             #TODO alert somehow without flooding?
#             pass
# 
# Path: plugins/arduino.py
# def getEventForButton(line):
#     if any([k in line for k in goalmap.keys()]):
#         parts = line.split()
#         data = {'source': 'serial', 'team': goalmap[parts[0]]}
# 
#         if len(parts) > 1:
#             data['duration'] = int(parts[1])
# 
#         if len(parts) > 2:
#             data['elapsed'] = int(parts[2])
# 
#         return 'goal_event', data
# 
#     if '_' in line:
#         btn, state = line.split('_')
#         btn = btnmap.get(btn, 'ERROR')
#         state = statemap.get(state, 'ERROR')
#         return 'button_event', {'source': 'serial', 'btn': btn, 'state': state}
# 
#     return None


# Path: plugins/io_serial.py
import time
import serial
import glob
import logging
from .io_base import IOBase
from .arduino import getEventForButton

        return chr(value + ord('A'))

    def convert_data(self, data):
        return (self.__getArduinoValueFor(data) + "\n").encode("ascii")

    def reader_thread(self):
        while True:
            if not self.ser:
                self.open_serial()
            try:
                line = self.ser.readline()
                try:
                    line = line.decode('ascii').strip()
                    ev = getEventForButton(line)
                    if ev:
                        self.bus.notify(*ev)
                except Exception as e:
                    logger.exception("Error reading data")

            except serial.SerialException as e:
                logger.error("Error reading data: %s", e)
                self.open_serial()

    def writer_thread(self):
        while True:
            line = self.write_queue.get()
            if not self.ser:
                # Wait until the reader thread opens the serial line again
                # FIXME: What if the queue fills up?
                time.sleep(1)

                continue