diff --git a/module.py b/module.py --- a/module.py +++ b/module.py @@ -1,10 +1,36 @@ from abc import ABCMeta, abstractmethod import uuid +import logging +import protocol +from message import HydroBotMessage class ModuleList(): - def __init__(self): + 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' @@ -25,68 +51,133 @@ class ModuleList(): if module.uuid == uuid: return module - def new_module(self, device_type, address, interface): + 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) - if device_type == 0x01: - module = AirSenseModule(device_type, address, interface) - elif device_type == 0x02: - module = RelayDriveModule(device_type, address, interface) - else: - module = UnknownModule(device_type, address, interface) + 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, device_type, address, interface): - self.device_type = device_type + 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() - print("Created new module! " + str(self.uuid)) + self.logger.info("Created new module! " + self.name + " " + str(self.uuid)) @abstractmethod - def send_message(self): + def send_message(self, message): pass @abstractmethod - def receive_message(self): + def receive_message(self, message): + pass + + @abstractmethod + def update(self): pass + + @abstractmethod + def config(self): + pass + class AirSenseModule(Module): - def __init__(self, device_type, address, interface): - super(AirSenseModule, self).__init__(device_type, address, interface) + def __init__(self, address, interface, name, database): + super(AirSenseModule, self).__init__(address, interface, name, database) - def send_message(self): - message = None + def send_message(self, message): self.interface.network.send_message(message) - def receive_message(self): - print("AirSenseModule receive 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, device_type, address, interface): - super(RelayDriveModule, self).__init__(device_type, address, interface) + 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 send_message(self): + 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 receive_message(self): - print("RelayDriveModule receive 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, device_type, address, interface): - super(UnknownModule, self).__init__(device_type, address, interface) + def __init__(self, address, interface, name, database): + super(UnknownModule, self).__init__(address, interface, name, database) - def send_message(self): + def send_message(self, message): pass - def receive_message(self): - print("UnknownModule receive message!") + 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) +