from abc import ABCMeta, abstractmethod import uuid import logging import protocol from message import HydroBotMessage class ModuleList(): def __init__(self, network, database, config): self.network = network self.database = database self.config = config self._modules = [] self.load_modules() def load_modules(self): for section in self.config.sections(): if "module" in section: module_name = self.config.get(section, "name") module_type = self.config.get(section, "type") module_address = int(self.config.get(section, "address"), 16) module_interface = self.config.get(section, "interface") network_interface = self.network.get_interface(module_interface) module_id = protocol.lookup_device_id_by_name(module_type) new_module = self.new_module(module_id, module_address, network_interface, module_name) network_interface.address_lookup[module_address] = new_module.uuid network_interface.uuid_lookup[new_module.uuid] = module_address new_module.config("data_rate", int(self.config.get(section, "data_rate"))) new_module.config("led_brightness", int(self.config.get(section, "led_brightness"))) def add_module(self, module): assert isinstance(module, Module), 'invalid module' if module in self._modules: raise ValueError('Module %s already in database' % module) else: self._modules.append(module) def remove_module(self, module): assert isinstance(Module, module), 'invalid module' try: self._module.remove(module) except ValueError: raise ValueError('Module %s is not in database' % module) def lookup_module(self, uuid): for module in self._modules: if module.uuid == uuid: return module def lookup_module_by_name(self, name): for module in self._modules: if module.name == name: return module def new_module(self, device_id, address, interface, name = None): if name == None or self.lookup_module_by_name(name) != None: name = self.auto_assign_name(device_id) device_class = eval(protocol.lookup_device_class_by_id(device_id)) module = device_class(address, interface, name, self.database) #if device_type == "airsense": #module = AirSenseModule(address, interface, name, self.database) #elif device_type == "relaydrive": #module = RelayDriveModule(address, interface, name, self.database) #else: #module = UnknownModule(address, interface, name, self.database) self.add_module(module) return module def auto_assign_name(self, device_id): keep_going = True num = 1 device_name = protocol.lookup_device_display_by_id(device_id) while keep_going: name_taken = False for module in self._modules: if module.name == device_name + str(num): name_taken = True break if not name_taken: return device_name + str(num) else: num = num + 1 class Module(metaclass=ABCMeta): def __init__(self, address, interface, name, database): self.logger = logging.getLogger('hydrobot') self.address = address self.interface = interface self.name = name self.database = database self.uuid = uuid.uuid1() self.logger.info("Created new module! " + self.name + " " + str(self.uuid)) @abstractmethod def send_message(self, message): pass @abstractmethod def receive_message(self, message): pass @abstractmethod def update(self): pass @abstractmethod def config(self): pass class AirSenseModule(Module): def __init__(self, address, interface, name, database): super(AirSenseModule, self).__init__(address, interface, name, database) def send_message(self, message): self.interface.network.send_message(message) def receive_message(self, message): self.logger.debug("Receive message! From: " + self.name) self.database.log_message(self.name, message) def update(self): pass def config(self, data_key, value): message = HydroBotMessage(self.uuid, (0x80 | protocol.lookup_command_key_by_name("config")), protocol.lookup_data_key_by_name(data_key), 0, value) self.interface.send_message(message) class RelayDriveModule(Module): def __init__(self, address, interface, name, database): super(RelayDriveModule, self).__init__(address, interface, name, database) def send_message(self, message): self.interface.network.send_message(message) def receive_message(self, message): self.logger.debug("Receive message! From: " + self.name) self.database.log_message(self.name, message) def update(self): pass def config(self, data_key, value): message = HydroBotMessage(self.uuid, (0x80 | protocol.lookup_command_key_by_name("config")), protocol.lookup_data_key_by_name(data_key), 0, value) self.interface.send_message(message) def set_output(self, output, value): message = HydroBotMessage(self.uuid, (0x80 | protocol.lookup_command_key_by_name("set_output")), protocol.lookup_data_key_by_name("digital_out"), int(output), value) self.send_message(message) class UnknownModule(Module): def __init__(self, address, interface, name, database): super(UnknownModule, self).__init__(address, interface, name, database) def send_message(self, message): pass def receive_message(self, message): self.logger.debug("Receive message! From: " + self.name) def update(self): pass def config(self, data_key, value): message = HydroBotMessage(self.uuid, (0x80 | protocol.lookup_command_key_by_name("config")), protocol.lookup_data_key_by_name(data_key), 0, value) self.interface.send_message(message)