class LuceneEngine(object): def __init__(self, index_name='generic', wipe_index=False, analyzer=lucene.SimpleAnalyzer(), ): self.logger=Logger(logger_name='lucene') self.index_name=index_name self.analyzer=analyzer self.dir=os.path.join(settings.LUCENE_INDEX_DIR, self.index_name) self.new_index=wipe_index self.reader=None if not os.path.exists(self.dir): os.makedirs(self.dir, 0775) os.chmod(self.dir, 0775) self.new_index=True self.JCCEnvObj = lucene.getVMEnv() self.JCCEnvObj.attachCurrentThread() self.store = lucene.SimpleFSDirectory(lucene.File(self.dir)) self.text_blob="" def get_writer(self): try: self.writer = lucene.IndexWriter(self.store, self.analyzer, self.new_index, lucene.IndexWriter.MaxFieldLength.LIMITED) self.new_index=False return True except Exception, err: self.logger.error("%s: %s" % (Exception, err)) return False
def test_fan(): _fan = None _log = Logger("fan test", Level.INFO) try: # read YAML configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _fan = Fan(_config, Level.INFO) limit = 2 for i in range(limit): _log.info('Switching fan on! [{:d}/{:d}]'.format(i + 1, limit)) _fan.enable() time.sleep(5) _log.info('Switching fan off! [{:d}/{:d}]'.format(i + 1, limit)) _fan.disable() time.sleep(5) except KeyboardInterrupt: _log.info("Disabling switch") if _fan: _fan.disable() except Exception as e: _log.error('error in fan: {}\n{}'.format(e, traceback.format_exc())) sys.exit(1)
def add_server(self, host_ips): """ Add server to swarm_servers If the server consist in the self.swarm_servers it won't be add Args: host_ips(list or str) Returns: Append to self.swarm_servers the host_ips """ logger = Logger(filename="orchastrator", logger_name="ContainerManagement add_server") if isinstance(host_ips, str): if host_ips not in self.swarm_servers: self.swarm_servers.append(host_ips) update_config("orchastrator.json", "swarm_servers", host_ips, state='add') else: # print("The host ip is already in the list") logger.info( "The host ip {} is already in the list".format(host_ips)) logger.clear_handler() elif isinstance(host_ips, list): self.swarm_servers = list(set(self.swarm_servers + host_ips)) update_config("orchastrator.json", "swarm_servers", host_ips, state='add') else: logger.error("Server should be list or string") logger.clear_handler() raise TypeError("Server should be list or string")
def test_message(): _log = Logger('message-test', Level.INFO) try: _log.info('start message test...') _message_bus = MessageBus(Level.INFO) _message_factory = MessageFactory(_message_bus, Level.INFO) _subscriber1 = Subscriber('behaviour', Fore.YELLOW, _message_bus, Level.INFO) _message_bus.register_subscriber(_subscriber1) _subscriber2 = Subscriber('infrared', Fore.MAGENTA, _message_bus, Level.INFO) _message_bus.register_subscriber(_subscriber2) _subscriber3 = Subscriber('bumper', Fore.GREEN, _message_bus, Level.INFO) _message_bus.register_subscriber(_subscriber3) _message_bus.print_publishers() _message_bus.print_subscribers() # ................................ _message = _message_factory.get_message(Event.BRAKE, True) _log.info('created message {}; event: {}'.format( _message.name, _message.event.name)) _message.acknowledge(_subscriber1) _subscriber1.print_message_info('sub1 info for message:', _message, None) except Exception as e: _log.error('error: {}'.format(e)) finally: _log.info('complete.')
def main(argv): _temp = None _log = Logger('temp-test', Level.INFO) try: # read YAML configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _queue = MessageQueue(Level.DEBUG) _temp = Temperature(_config, _queue, Level.INFO) _temp.enable() while True: # _value = _temp.get_cpu_temperature() # _is_hot = _temp.is_hot() time.sleep(1.0) except KeyboardInterrupt: _log.info(Fore.YELLOW + 'exited via Ctrl-C' + Style.RESET_ALL) if _temp: _temp.close() sys.exit(0) except Exception: _log.error(Fore.RED + Style.BRIGHT + 'error getting RPI temperature: {}'.format( traceback.format_exc()) + Style.RESET_ALL) if _temp: _temp.close() sys.exit(1)
def main(): try: _log = Logger('test', Level.INFO) print(Fore.BLACK + Style.BRIGHT + RULER + Style.RESET_ALL) _base = 'abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789012345678901234567890' _max_width = 80 _margin = 27 # right-most colon is column 27 _available_width = _max_width - _margin # for i in range(1, _available_width): for i in range(1, _available_width + 2): _title = _base[:i] _message1 = _base[:i] _message2 = '[{:d}/{:d}]'.format(i, 10) _log.header(_title, _message1, _message2) _log.header(' ', None, None) _log.header('com.google.code.gson:gson', None, None) _log.header('commons-io:fileutils', 'Here\'s a message we want to display.', None) _log.header('org.apache.commons:commons-lang3', 'Here\'s another message we want to display.', '[3/10]') print(Fore.BLACK + Style.BRIGHT + RULER + Style.RESET_ALL) except Exception as e: _log.error('error in splenk processor: {}'.format(e)) traceback.print_exc(file=sys.stdout)
def main(): signal.signal(signal.SIGINT, signal_handler) _log = Logger('play_test', Level.INFO) try: _log.info('executing player tests...') _player = Player(Level.INFO) _player.play(Sound.BLIP) time.sleep(3.0) _player.play(Sound.ALARM) time.sleep(3.0) _log.info('test complete.') except KeyboardInterrupt: _log.warning('Ctrl-C caught: complete.') except Exception as e: _log.error('error in test: {}'.format(e)) traceback.print_exc(file=sys.stdout) sys.exit(1) finally: sys.exit(0)
def main(argv): try: _log = Logger('brake', Level.INFO) _log.info('configuring...') # read YAML configuration _loader = ConfigLoader(Level.WARN) _config = _loader.configure() _log.info('creating message factory...') _message_factory = MessageFactory(Level.INFO) _log.info('creating message bus...') _message_bus = MessageBus(Level.INFO) _log.info('creating clock...') _clock = Clock(_config, _message_bus, _message_factory, Level.WARN) _motor_configurer = MotorConfigurer(_config, _clock, Level.INFO) _motors = _motor_configurer.get_motors() _log.info('braking...') _motors.brake() _log.info('done.') except KeyboardInterrupt: _log.error('Ctrl-C caught in main: exiting...') finally: if _motors: _motors.stop() _motors.close() _log.info('complete.')
def test_temperature(): _temperature = None _fan = None _log = Logger('temp-test', Level.INFO) try: # scan I2C bus _log.info('scanning I²C address bus...') scanner = I2CScanner(_log.level) _addresses = scanner.get_int_addresses() # load configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) # create Fan if available _fan_config = _config['ros'].get('fan') _fan_i2c_address = _fan_config.get('i2c_address') fan_available = (_fan_i2c_address in _addresses) if fan_available: _fan = Fan(_config, Level.INFO) _log.info('fan is available at I²C address of 0x{:02X}.'.format( _fan_i2c_address)) else: _fan = None _log.info( 'fan is not available at I²C address of 0x{:02X}.'.format( _fan_i2c_address)) _message_factory = MessageFactory(Level.INFO) _message_bus = MessageBus(Level.DEBUG) _clock = Clock(_config, _message_bus, _message_factory, Level.WARN) _temperature = Temperature(_config, _clock, _fan, Level.INFO) _temperature.enable() _counter = itertools.count() _clock.enable() while True: _count = next(_counter) # _temperature.display_temperature() # _value = _temperature.get_cpu_temperature() # _is_warning_temp = _temperature.is_warning_temperature() # _is_max_temp = _temperature.is_max_temperature() # if _is_warning_temp: # _log.warning('[{:04d}] loop; is warning temp? {}; is max temp? {}'.format(_count, _is_warning_temp, _is_max_temp)) # else: # _log.info('[{:04d}] loop; is warning temp? {}; is max temp? {}'.format(_count, _is_warning_temp, _is_max_temp)) time.sleep(1.0) except KeyboardInterrupt: _log.info(Fore.YELLOW + 'exited via Ctrl-C' + Style.RESET_ALL) except Exception: _log.error(Fore.RED + Style.BRIGHT + 'error getting RPI temperature: {}'.format( traceback.format_exc()) + Style.RESET_ALL) finally: if _temperature: _temperature.close() if _fan: _fan.disable()
class I2CScanner(): ''' Scans the I2C bus returning a list of addresses. ''' def __init__(self, level): super().__init__() self._log = Logger('i2cscan', level) self._log.debug('initialising...') self.hex_list = [] try: import smbus bus_number = 1 # 1 indicates /dev/i2c-1 self._bus = smbus.SMBus(bus_number) self._log.info('ready.') except ImportError: self._log.warning('initialised. This script requires smbus. Will operate without but return an empty result.') self._bus = None def getHexAddresses(self): ''' Returns a hexadecimal version of the list. This is only populated after calling getAddresses(). ''' return self.hex_list def getIntAddresses(self): ''' Returns an integer version of the list. This is only populated after calling getAddresses(). ''' return self._int_list def getAddresses(self): self._int_list = [] device_count = 0 if self._bus is not None: for address in range(3, 128): try: self._bus.write_byte(address, 0) self._log.debug('found {0}'.format(hex(address))) self._int_list.append(address) self.hex_list.append(hex(address)) device_count = device_count + 1 except IOError as e: if e.errno != errno.EREMOTEIO: self._log.error('Error: {0} on address {1}'.format(e, hex(address))) except Exception as e: # exception if read_byte fails self._log.error('Error unk: {0} on address {1}'.format(e, hex(address))) self._bus.close() self._bus = None self._log.info("found {0} device(s)".format(device_count)) else: self._log.info("found no devices (no smbus available)") return self._int_list
def find_usb_device(self): tty_usb = self.usb.find() if tty_usb: try: success = self.usb.setup(tty_usb) if success: self.usb_active = True except Exception as error: Logger.error(error)
def remote_action(self): error = self.usb.get_errors() if len(error): Logger.error(error) self.usb_active = False else: action_codes = self.usb.get_codes() for code in action_codes: self.action.run(code)
def down(self,url,savepath): try: urllib.urlretrieve(url, savepath) self.errortimes = 0 return True except BaseException as e: Logger.error('down:%s , %s %s'%(url,savepath,e)) self.errortimes = self.errortimes + 1 if self.errortimes >= self.errorlimit: return False; return self.down(url,savepath)
def down(self, url, savepath): try: urllib.urlretrieve(url, savepath) self.errortimes = 0 return True except BaseException as e: Logger.error('down:%s , %s %s' % (url, savepath, e)) self.errortimes = self.errortimes + 1 if self.errortimes >= self.errorlimit: return False return self.down(url, savepath)
def postRequest(self,url,data): try: request=urllib2.Request(url) f =urllib2.urlopen(request,data,10000) response=f.read() self.errortimes = 0 return response; except BaseException as e: Logger.error('postRequest:%s %s'%(url,e)) self.errortimes = self.errortimes + 1 if self.errortimes >= self.errorlimit: return None; return self.postRequest(url,data)
def postRequest(self, url, data): try: request = urllib2.Request(url) f = urllib2.urlopen(request, data, 10000) response = f.read() self.errortimes = 0 return response except BaseException as e: Logger.error('postRequest:%s %s' % (url, e)) self.errortimes = self.errortimes + 1 if self.errortimes >= self.errorlimit: return None return self.postRequest(url, data)
def _error(self, downloader, handle): gtk.gdk.threads_enter() # Terminate download process downloader.terminate() # Emit error signal self.emit("download-failed", handle) # Log error Logger.error("DownloadWizard", MSG_000005 % (handle.item.source)) # Close dialog self.response(gtk.RESPONSE_REJECT) gtk.gdk.threads_leave()
def exe(command): if not len(command): return False try: process = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True) (out, error) = process.communicate() out = out.decode("utf-8") if len(out): Logger.log(out) if error: Logger.error(error) except Exception as error: Logger.error(error)
def join_server_swarm(self, host_ip): """ Join server to the swarm Args: host_ip(str) """ #####First way # self.ssh_client.connect(host_ip, username=self.user, password=self.password) # _, stdout, _ = self.ssh_client.exec_command('docker swarm join --token {} {}:2377'. \ # format(self.__token, self.__master)) # stdout = '\n'.join(map(lambda x: x.rstrip(), stdout.readlines())) # if re.search(r'This node joined a swarm as a worker', stdout, re.I|re.S): # self.remove_available_server(host_ip) # self.add_swarm_server(host_ip) # else: # return "Node {} can't be joined to the swarm".format(host_ip) #####Second way logger = Logger(filename="orchastrator", logger_name="SwarmManagment join_server_swarm") docker_api = self.get_docker_api(host_ip) response = False try: response = docker_api.swarm.join(remote_addrs= \ [parse_config("orchastrator.json")["master"]], \ join_token = parse_config("orchastrator.json")["token"]) except docker.errors.APIError as e: logger.info( "Exception handling swarm joining but config will be updated and corrected" ) logger.clear_handler() self.remove_available_server(host_ip) self.add_swarm_server(host_ip) if response == True: logger.info( "Node {} was successfully joined to the swarm".format(host_ip)) logger.clear_handler() self.remove_available_server(host_ip) self.add_swarm_server(host_ip) else: logger.error( "Node {} can't be joined to the swarm".format(host_ip)) logger.clear_handler() return "Node {} can't be joined to the swarm".format(host_ip)
def test_motors(): _log = Logger('test', Level.INFO) # read YAML configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _motor_configurer = MotorConfigurer(_config, Level.INFO) _motors = _motor_configurer.configure() _motors.enable() _log.info('starting motors...') _port_motor = _motors.get_motor(Orientation.PORT) _stbd_motor = _motors.get_motor(Orientation.STBD) _port_motor.enable() _stbd_motor.enable() try: for i in range(5): _power = i * 0.1 _log.info(Fore.YELLOW + 'set motor power: {:5.2f};'.format(_power)) _stbd_motor.set_motor_power(_power) _port_motor.set_motor_power(_power) time.sleep(1.0) _log.info('[{:d}]\t'.format(i) \ + Fore.RED + 'power {:5.2f}/{:5.2f}; '.format(_port_motor.get_current_power_level(), _power) \ + Fore.CYAN + ' {:>4d} steps; \t'.format(_port_motor.steps) \ + Fore.GREEN + 'power {:5.2f}/{:5.2f}; '.format(_stbd_motor.get_current_power_level(), _power) \ + Fore.CYAN + ' {:>4d} steps.'.format(_stbd_motor.steps) ) # if i > 2 and ( _port_motor.steps == 0 or _stbd_motor.steps == 0 ): # raise Exception('motors are not turning.') time.sleep(1.0) # tests... _log.info('port motor: {:d} steps.'.format(_port_motor.steps)) # assert _port_motor.steps > 0 _log.info('stbd motor: {:d} steps.'.format(_stbd_motor.steps)) # assert _stbd_motor.steps > 0 except Exception as e: _log.error('error: {}'.format(e)) finally: close_motors(_log, _port_motor, _stbd_motor) _log.info(Fore.YELLOW + 'complete.')
def parse_config(json_file): """ Parse json_file and load it to a dictionary Returns: js_data(dict) """ try: with open(json_file) as json_data: js_data = json.load(json_data) except IOError: logger = Logger(filename="orchastrator", logger_name="parse_config") logger.error( "File => {} couldn't be opened for read!".format(json_file)) logger.clear_handler() raise ("File => {} couldn't be opened for read!".format(json_file)) return js_data
def main(): signal.signal(signal.SIGINT, signal_handler) print('uscanner_test :' + Fore.CYAN + Style.BRIGHT + ' INFO : starting test...' + Style.RESET_ALL) print('uscanner_test :' + Fore.YELLOW + Style.BRIGHT + ' INFO : Press Ctrl+C to exit.' + Style.RESET_ALL) _log = Logger("uscanner", Level.INFO) try: _scanner = I2CScanner(Level.WARN) _int_addresses = _scanner.get_int_addresses() _hex_addresses = _scanner.get_hex_addresses() _addrDict = dict( list(map(lambda x, y: (x, y), _int_addresses, _hex_addresses))) for i in range(len(_int_addresses)): _log.debug( Fore.BLACK + Style.DIM + 'found device at address: {}'.format(_hex_addresses[i]) + Style.RESET_ALL) ultraborg_available = (0x36 in _int_addresses) if ultraborg_available: _log.info('starting ultrasonic scan...') _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _scanner = UltrasonicScanner(_config, Level.INFO) _scanner.enable() values = _scanner.scan() time.sleep(1.0) _scanner.close() else: _log.error('required hardware dependencies not available.') print('uscanner_test :' + Fore.CYAN + Style.BRIGHT + ' INFO : test complete.' + Style.RESET_ALL) except Exception: _log.info(traceback.format_exc()) sys.exit(1)
def main(argv): _log = Logger("main", Level.INFO) try: _log.info(Fore.BLUE + 'configuring objects...') _loop_freq_hz = 10 _ticker = Ticker(_loop_freq_hz, Level.INFO) _message_factory = MessageFactory(Level.INFO) _message_bus = MessageBus() # _publisher = Publisher(_message_bus) _publisher = MyPublisher(_message_factory, _message_bus) # _publisher.enable() _publish = _publisher.publish(10) _log.info(Fore.BLUE + 'generating subscribers...') _subscribers = [] _subscriptions = [] for x in range(10): _subscriber = MySubscriber('s{}'.format(x), _ticker, _message_bus) _subscribers.append(_subscriber) _subscriptions.append(_subscriber.subscribe()) _ticker.enable() loop = asyncio.get_event_loop() _log.info(Fore.BLUE + 'starting loop...') loop.run_until_complete(asyncio.gather(_publish, *_subscriptions)) _log.info(Fore.BLUE + 'closing {} subscribers...'.format(len(_subscribers))) for subscriber in _subscribers: _log.info(Fore.BLUE + 'subscriber {} has {:d} messages remaining in queue: {}'.format(subscriber.name, subscriber.queue_length(), _subscriber.print_queue_contents())) _log.info(Fore.BLUE + 'loop complete.') except KeyboardInterrupt: _log.info('caught Ctrl-C; exiting...') except Exception: _log.error('error processing message bus: {}'.format(traceback.format_exc())) finally: _log.info('exit.')
def remove_swarm_server(self, host_ip): """ Remove server ip from self.swarm_servers Args: host_ip(str) """ if host_ip in self.swarm_servers: self.swarm_servers.remove(host_ip) update_config("orchastrator.json", "swarm_servers", host_ip, state='remove') else: logger = Logger(filename="orchastrator", logger_name="SwarmManagment remove_swarm_server") logger.error( "Node {} can't be removed from swarm_servers (It is not in swarm_servers)" .format(host_ip)) logger.clear_handler()
def main(): signal.signal(signal.SIGINT, signal_handler) try: _log = Logger("batcheck test", Level.INFO) _log.header('battery check', 'Starting test...', '[1/3]') _log.info(Fore.RED + 'Press Ctrl+C to exit.') # read YAML configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _log.header('battery check', 'Creating objects...', '[2/3]') _queue = MessageQueue(Level.INFO) _message_factory = MessageFactory(Level.INFO) _battery_check = BatteryCheck(_config, _queue, _message_factory, Level.INFO) _battery_check.enable() _battery_check.set_enable_messaging(True) _log.header('battery check', 'Enabling battery check...', '[3/3]') _log.info('ready? {}'.format(_battery_check.is_ready())) count = 0 while not _battery_check.is_ready() and count < 10: count += 1 time.sleep(0.5) while _battery_check.get_count() < 30: time.sleep(0.5) _battery_check.close() _log.info('complete.') except KeyboardInterrupt: _log.info('Ctrl-C caught: complete.') except Exception as e: _log.error('error closing: {}\n{}'.format(e, traceback.format_exc())) finally: sys.exit(0)
def leave_server_swarm(self, host_ip): """ Leave server from the swarm Args: host_ip(str) """ #####First way # if host_ip in parse_config("orchastrator.json")["master_nodes"]: # print("Demoting the node from manager") # self.demote_manager(host_ip) # self.ssh_client.connect(host_ip, username=self.user, password=self.password) # _, stdout, _ = self.ssh_client.exec_command('docker swarm leave') # stdout = '\n'.join(map(lambda x: x.rstrip(), stdout.readlines())) # print("STDOUT => {}".format(stdout)) # stdout = "Node left the swarm" # hostname = self.get_hostname(host_ip) # if re.search(r'Node left the swarm', stdout, re.I|re.S): # print("YEEEEE") # self.ssh_client.connect(self.__master, username=self.user, password=self.password) # _, leave_stdout, _ = self.ssh_client.exec_command('docker node rm -f {}'.format(hostname)) # leave_stdout = '\n'.join(map(lambda x: x.rstrip(), leave_stdout.readlines())) # self.add_server(host_ip) # self.remove_swarm_server(host_ip) # else: # return "Node {} can't left the swarm for some reason".format(host_ip) #####Second way logger = Logger(filename="orchastrator", logger_name="SwarmManagment leave_server_swarm") docker_api = self.get_docker_api(host_ip) response = docker_api.swarm.leave(force=True) if response: self.add_server(host_ip) self.remove_swarm_server(host_ip) else: logger.error( "Node {} can't left the swarm for some reason".format(host_ip)) logger.clear_handler() return "Node {} can't left the swarm for some reason".format( host_ip)
def main(): signal.signal(signal.SIGINT, signal_handler) try: _log = Logger("batterycheck test", Level.INFO) _log.info('starting test...') _log.info(Fore.YELLOW + Style.BRIGHT + ' INFO : Press Ctrl+C to exit.') # read YAML configuration _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _queue = MessageQueue(Level.INFO) _battery_check = BatteryCheck(_config, _queue, Level.INFO) _battery_check.set_loop_delay_sec(0.5) _battery_check.set_enable_messaging(True) _battery_check.enable() _log.info('ready? {}'.format(_battery_check.is_ready())) count = 0 while not _battery_check.is_ready() and count < 10: count += 1 time.sleep(0.5) while count < 20: count += 1 time.sleep(0.5) _battery_check.close() _log.info('complete.') except KeyboardInterrupt: _log.info('Ctrl-C caught: complete.') except Exception as e: _log.error('error closing master: {}'.format(e)) finally: sys.exit(0)
def test_imu(): _log = Logger("imu-test", Level.INFO) _i2c_scanner = I2CScanner(Level.WARN) _addresses = _i2c_scanner.get_int_addresses() _rgbmatrix = RgbMatrix(Level.INFO) if (0x74 in _addresses) else None if _rgbmatrix: _rgbmatrix.set_display_type(DisplayType.SOLID) _rgbmatrix.enable() try: _loader = ConfigLoader(Level.INFO) filename = 'config.yaml' _config = _loader.configure(filename) _cardinal = Cardinal.get_heading_from_degrees(0) _imu = IMU(_config, Level.INFO) while True: _heading = _imu.read_heading()[0] if _rgbmatrix: _cardinal = Cardinal.get_heading_from_degrees(_heading) _color = Cardinal.get_color_for_direction(_cardinal) _rgbmatrix.set_color(_color) _log.info(Fore.YELLOW + 'heading: {:05.2f}°;\tcardinal: {}'.format( _heading, _cardinal.display) + Style.RESET_ALL) time.sleep(2.0) except KeyboardInterrupt: _log.info('Ctrl-C caught: exiting...') except Exception as e: _log.error('error closing: {}\n{}'.format(e, traceback.format_exc())) finally: if _rgbmatrix: _rgbmatrix.set_color(Color.BLACK) _rgbmatrix.disable() _log.info('complete.')
def demote_manager(self, host_ip): """ Demote the server from manager in the swarm Args: host_ip(str) """ logger = Logger(filename="orchastrator", logger_name="SwarmManagment demote_manager") hostname = self.get_hostname(host_ip) self.ssh_client.connect(self.__master, username=self.user, password=self.password) _, demoted_stdout, _ = self.ssh_client.exec_command( 'docker node demote {}'.format(hostname)) demoted_stdout = '\n'.join( map(lambda x: x.rstrip(), demoted_stdout.readlines())) if re.search(r'demoted in the swarm', demoted_stdout, re.I | re.S): self.remove_master_node(host_ip) else: logger.error( "Node {} can't be demoted from manager".format(host_ip)) logger.clear_handler() return "Node {} can't be demoted from manager".format(host_ip)
if __name__ == '__main__': """Write switch memory. Args: INV_FILE (string): Inventory file. LOG_LEVEL (string): Log level. Raises: Exception: If parameter count is invalid. """ LOG = Logger(__file__) ARGV_MAX = 3 ARGV_COUNT = len(sys.argv) if ARGV_COUNT > ARGV_MAX: try: raise Exception() except Exception: LOG.error('Invalid argument count') sys.exit(1) INV_FILE = sys.argv[1] LOG.set_level(sys.argv[2]) SWITCHES = WriteSwitchMemory(LOG, INV_FILE) SWITCHES.write_mgmt_switch_memory() SWITCHES.write_data_switch_memory()
class I2cMaster(): ''' A Raspberry Pi Master for a corresponding Arduino Slave. Parameters: device_id: the I²C address over which the master and slave communicate level: the log level, e.g., Level.INFO ''' def __init__(self, config, level): super().__init__() if config is None: raise ValueError('no configuration provided.') self._config = config['ros'].get('i2c_master') self._device_id = self._config.get( 'device_id' ) # i2c hex address of slave device, must match Arduino's SLAVE_I2C_ADDRESS self._channel = self._config.get('channel') self._log = Logger('i²cmaster-0x{:02x}'.format(self._device_id), level) self._log.info('initialising...') self._counter = itertools.count() self._loop_count = 0 # currently only used in testing self._thread = None self._enabled = False self._closed = False self._i2c = SMBus(self._channel) self._log.info( 'ready: imported smbus2 and obtained I²C bus at address 0x{:02X}...' .format(self._device_id)) # .......................................................................... def enable(self): self._enabled = True self._log.info('enabled.') # .......................................................................... def disable(self): self._enabled = False self._log.info('disabled.') # .............................................................................. def read_i2c_data(self): ''' Read a byte from the I²C device at the specified handle, returning the value. ## Examples: int.from_bytes(b'\x00\x01', "big") # 1 int.from_bytes(b'\x00\x01', "little") # 256 ''' with SMBus(self._channel) as bus: _byte = bus.read_byte_data(self._device_id, 0) time.sleep(0.01) return _byte # .......................................................................... def write_i2c_data(self, data): ''' Write a byte to the I²C device at the specified handle. ''' with SMBus(self._channel) as bus: bus.write_byte(self._device_id, data) time.sleep(0.01) # .......................................................................... def get_input_from_pin(self, pin): ''' Sends a message to the pin, returning the result as a byte. ''' self.write_i2c_data(pin) # time.sleep(0.2) _received_data = self.read_i2c_data() # time.sleep(0.2) self._log.debug('received response from pin {:d} of {:08b}.'.format( pin, _received_data)) return _received_data # .......................................................................... def in_loop(self): ''' Returns true if the main loop is active (the thread is alive). ''' return self._thread != None and self._thread.is_alive() # .......................................................................... def _front_sensor_loop(self, loop_delay_sec, callback): self._log.info('starting event loop...\n') while self._enabled: _count = next(self._counter) print(CLEAR_SCREEN) # pin 1: analog infrared sensor ................ _received_data = self.get_input_from_pin(1) # self._log.info('[{:04d}] ANALOG IR ({:d}): \t'.format(_count, 1) + ( Fore.RED if ( _received_data > 100.0 ) else Fore.YELLOW ) \ # + Style.BRIGHT + '{:d}'.format(_received_data) + Style.DIM + '\t(analog value 0-255)') callback(1, PinType.ANALOG_INPUT, _received_data) # pin 2: analog infrared sensor ................ _received_data = self.get_input_from_pin(2) # self._log.info('[{:04d}] ANALOG IR ({:d}): \t'.format(_count, 2) + ( Fore.RED if ( _received_data > 100.0 ) else Fore.YELLOW ) \ # + Style.BRIGHT + '{:d}'.format(_received_data) + Style.DIM + '\t(analog value 0-255)') callback(2, PinType.ANALOG_INPUT, _received_data) # pin 3: analog infrared sensor ................ _received_data = self.get_input_from_pin(3) # self._log.info('[{:04d}] ANALOG IR ({:d}): \t'.format(_count, 3) + ( Fore.RED if ( _received_data > 100.0 ) else Fore.YELLOW ) \ # + Style.BRIGHT + '{:d}'.format(_received_data) + Style.DIM + '\t(analog value 0-255)') callback(3, PinType.ANALOG_INPUT, _received_data) # pin 4: analog infrared sensor ................ _received_data = self.get_input_from_pin(4) # self._log.info('[{:04d}] ANALOG IR ({:d}): \t'.format(_count, 4) + ( Fore.RED if ( _received_data > 100.0 ) else Fore.YELLOW ) \ # + Style.BRIGHT + '{:d}'.format(_received_data) + Style.DIM + '\t(analog value 0-255)') callback(4, PinType.ANALOG_INPUT, _received_data) # pin 5: analog infrared sensor ................ _received_data = self.get_input_from_pin(5) # self._log.info('[{:04d}] ANALOG IR ({:d}): \t'.format(_count, 5) + ( Fore.RED if ( _received_data > 100.0 ) else Fore.YELLOW ) \ # + Style.BRIGHT + '{:d}'.format(_received_data) + Style.DIM + '\t(analog value 0-255)') callback(5, PinType.ANALOG_INPUT, _received_data) # pin 9: digital bumper sensor ................. _received_data = self.get_input_from_pin(9) # self._log.info('[{:04d}] DIGITAL IR ({:d}): \t'.format(_count, 9) + Fore.GREEN + Style.BRIGHT + '{:d}'.format(_received_data) \ # + Style.DIM + '\t(displays digital pup value 0|1)') callback(9, PinType.DIGITAL_INPUT_PULLUP, _received_data) # pin 10: digital bumper sensor ................ _received_data = self.get_input_from_pin(10) # self._log.info('[{:04d}] DIGITAL IR ({:d}): \t'.format(_count, 10) + Fore.GREEN + Style.BRIGHT + '{:d}'.format(_received_data) \ # + Style.DIM + '\t(displays digital pup value 0|1)') callback(10, PinType.DIGITAL_INPUT_PULLUP, _received_data) # pin 11: digital bumper sensor ................ _received_data = self.get_input_from_pin(11) # self._log.info('[{:04d}] DIGITAL IR ({:d}): \t'.format(_count, 11) + Fore.GREEN + Style.BRIGHT + '{:d}'.format(_received_data) \ # + Style.DIM + '\t(displays digital pup value 0|1)') callback(11, PinType.DIGITAL_INPUT_PULLUP, _received_data) time.sleep(loop_delay_sec) # we never get here if using 'while True:' self._log.info('exited event loop.') # .......................................................................... def start_front_sensor_loop(self, loop_delay_sec, callback): ''' This is the method to call to actually start the loop. ''' if not self._enabled: raise Exception( 'attempt to start front sensor event loop while disabled.') elif not self._closed: if self._thread is None: enabled = True self._thread = threading.Thread( target=I2cMaster._front_sensor_loop, args=[self, loop_delay_sec, callback]) self._thread.start() self._log.info('started.') else: self._log.warning('cannot enable: process already running.') else: self._log.warning('cannot enable: already closed.') # .......................................................................... def close(self): ''' Close the instance. ''' self._log.debug('closing I²C master.') if not self._closed: try: if self._thread != None: self._thread.join(timeout=1.0) self._log.debug('front sensor loop thread joined.') self._thread = None self._closed = True # self._pi.i2c_close(self._handle) # close device self._log.debug('I²C master closed.') except Exception as e: self._log.error('error closing master: {}'.format(e)) else: self._log.debug('I²C master already closed.')
Args: INV_FILE (string): Inventory file. LOG_LEVEL (string): Log level. Raises: Exception: If parameter count is invalid. """ LOG = Logger(__file__) if len(sys.argv) != 4: try: raise Exception() except: LOG.error('Invalid argument count') sys.exit(1) INV_FILE = sys.argv[1] SWITCH_TYPE = sys.argv[2] LOG.set_level(sys.argv[3]) SWITCH = GetSwitchInfoAssignClass(LOG, INV_FILE) if SWITCH_TYPE == SWITCH.MGMT_SWITCH_TYPE: SWITCH.update_mgmt_switch_info() elif SWITCH_TYPE == SWITCH.DATA_SWITCH_TYPE: SWITCH.update_data_switch_info() else: try: raise Exception() except:
class I2CScanner(): ''' Scans the I²C bus, returning a list of devices. ''' def __init__(self, level): super().__init__() self._log = Logger('i2cscan', level) self._log.debug('initialising...') self._int_list = [] self._hex_list = [] try: import smbus bus_number = 1 # 1 indicates /dev/i2c-1 self._bus = smbus.SMBus(bus_number) self._log.info('ready.') except ImportError: self._log.warning('initialised. This script requires smbus. Will operate without but return an empty result.') self._bus = None # .......................................................................... def get_hex_addresses(self): ''' Returns a hexadecimal version of the list. ''' self._scan_addresses() return self._hex_list # .......................................................................... def get_int_addresses(self): ''' Returns an integer version of the list. ''' self._scan_addresses() return self._int_list # .......................................................................... def has_address(self, addresses): ''' Performs the address scan (if necessary) and returns true if a device is available at any of the specified addresses. ''' self._scan_addresses() for address in addresses: if address in self._int_list: return True return False # .......................................................................... def _scan_addresses(self): ''' Scans the bus and returns the available device addresses. After being called and populating the int and hex lists, this closes the connection to smbus. ''' if len(self._int_list) == 0: device_count = 0 if self._bus is not None: for address in range(3, 128): try: self._bus.write_byte(address, 0) self._log.debug('found I²C device at 0x{:02X}'.format(address)) self._int_list.append(address) self._hex_list.append(hex(address)) device_count = device_count + 1 except IOError as e: if e.errno != errno.EREMOTEIO: self._log.error('Error: {0} on address {1}'.format(e, hex(address))) except Exception as e: # exception if read_byte fails self._log.error('Error unk: {0} on address {1}'.format(e, hex(address))) self._bus.close() self._bus = None self._log.info("found {:d} device(s).".format(device_count)) else: self._log.info("found no devices (no smbus available).") return self._int_list
class Motors(): ''' A dual motor controller with encoders. ''' def __init__(self, config, tb, level): super().__init__() self._log = Logger('motors', level) self._log.info('initialising motors...') if tb is None: tb = self._configure_thunderborg_motors(level) if tb is None: raise Exception('unable to configure thunderborg.') self._tb = tb self._set_max_power_ratio() self._pi = pigpio.pi() try: from lib.motor_v2 import Motor self._log.info('imported Motor.') except Exception: traceback.print_exc(file=sys.stdout) self._log.error('failed to import Motor, exiting...') sys.exit(1) self._port_motor = Motor(config, self._tb, self._pi, Orientation.PORT, level) self._port_motor.set_max_power_ratio(self._max_power_ratio) self._stbd_motor = Motor(config, self._tb, self._pi, Orientation.STBD, level) self._stbd_motor.set_max_power_ratio(self._max_power_ratio) self._enabled = True # default enabled # a dictionary of motor # to last set value self._msgIndex = 0 self._last_set_power = {0: 0, 1: 0} self._log.info('motors ready.') # .......................................................................... def _configure_thunderborg_motors(self, level): ''' Import the ThunderBorg library, then configure the Motors. ''' self._log.info('configure thunderborg & motors...') global pi try: self._log.info('importing thunderborg...') import lib.ThunderBorg3 as ThunderBorg self._log.info('successfully imported thunderborg.') TB = ThunderBorg.ThunderBorg( level) # create a new ThunderBorg object TB.Init() # set the board up (checks the board is connected) self._log.info('successfully instantiated thunderborg.') if not TB.foundChip: boards = ThunderBorg.ScanForThunderBorg() if len(boards) == 0: self._log.error( 'no thunderborg found, check you are attached.') else: self._log.error( 'no ThunderBorg at address {:02x}, but we did find boards:' .format(TB.i2cAddress)) for board in boards: self._log.info('board {:02x} {:d}'.format( board, board)) self._log.error( 'if you need to change the I²C address change the setup line so it is correct, e.g. TB.i2cAddress = {:0x}' .format(boards[0])) sys.exit(1) TB.SetLedShowBattery(True) return TB except Exception as e: self._log.error('unable to import thunderborg: {}'.format(e)) traceback.print_exc(file=sys.stdout) sys.exit(1) # .......................................................................... def set_led_show_battery(self, enable): self._tb.SetLedShowBattery(enable) # .......................................................................... def set_led_color(self, color): self._tb.SetLed1(color.red / 255.0, color.green / 255.0, color.blue / 255.0) # .......................................................................... def _set_max_power_ratio(self): pass # initialise ThunderBorg ........................... self._log.info('getting battery reading...') # get battery voltage to determine max motor power # could be: Makita 12V or 18V power tool battery, or 12-20V line supply voltage_in = self._tb.GetBatteryReading() if voltage_in is None: raise OSError('cannot continue: cannot read battery voltage.') self._log.info('voltage in: {:>5.2f}V'.format(voltage_in)) # voltage_in = 20.5 # maximum motor voltage voltage_out = 9.0 self._log.info('voltage out: {:>5.2f}V'.format(voltage_out)) if voltage_in < voltage_out: raise OSError( 'cannot continue: battery voltage too low ({:>5.2f}V).'.format( voltage_in)) # Setup the power limits if voltage_out > voltage_in: self._max_power_ratio = 1.0 else: self._max_power_ratio = voltage_out / float(voltage_in) # convert float to ratio format self._log.info('battery level: {:>5.2f}V; motor voltage: {:>5.2f}V;'.format( voltage_in, voltage_out) + Fore.CYAN + Style.BRIGHT \ + ' maximum power ratio: {}'.format(str(Fraction(self._max_power_ratio).limit_denominator(max_denominator=20)).replace('/',':'))) # .......................................................................... def get_motor(self, orientation): if orientation is Orientation.PORT: return self._port_motor else: return self._stbd_motor # .......................................................................... def enable(self): self._enabled = True # .......................................................................... def disable(self): ''' Disable the motors, halting first if in motion. ''' self._log.info('disabling motors...') self._enabled = False if self.is_in_motion(): # if we're moving then halt self._log.warning('event: motors are in motion (halting).') self.halt() self._log.info('motors disabled.') # .......................................................................... def is_in_motion(self): ''' Returns true if either motor is moving. ''' return self._port_motor.is_in_motion( ) or self._stbd_motor.is_in_motion() # .......................................................................... def get_steps(self): ''' Returns the port and starboard motor step count. ''' return [self._port_motor.get_steps(), self._stbd_motor.get_steps()] # .......................................................................... def get_current_power_level(self, orientation): ''' Returns the last set power of the specified motor. ''' if orientation is Orientation.PORT: return self._port_motor.get_current_power_level() else: return self._stbd_motor.get_current_power_level() # .......................................................................... def close(self): ''' Halts, turn everything off and stop doing anything. ''' self._log.debug('closing...') self.halt() self._port_motor.close() self._stbd_motor.close() self._log.debug('closed.') # Stopping Behaviours .................................................................... # .......................................................................... def interrupt(self): ''' Interrupt any motor loops by setting the _interrupt flag. ''' self._port_motor.interrupt() self._stbd_motor.interrupt() # .......................................................................... def halt(self): ''' Quickly (but not immediately) stops both motors. ''' self._log.info('halting...') if self.is_stopped(): self._log.debug('already stopped.') return True # source: https://stackoverflow.com/questions/2957116/make-2-functions-run-at-the-same-time _tp = Thread(target=self.processStop, args=(Event.HALT, Orientation.PORT)) _ts = Thread(target=self.processStop, args=(Event.HALT, Orientation.STBD)) _tp.start() _ts.start() _tp.join() _ts.join() self._log.info('halted.') return True # .......................................................................... def brake(self): ''' Slowly coasts both motors to a stop. ''' self._log.info('braking...') if self.is_stopped(): self._log.warning('already stopped.') return True _tp = Thread(target=self.processStop, args=(Event.BRAKE, Orientation.PORT)) _ts = Thread(target=self.processStop, args=(Event.BRAKE, Orientation.STBD)) _tp.start() _ts.start() _tp.join() _ts.join() self._log.info('braked.') return True # .......................................................................... def stop(self): ''' Stops both motors immediately, with no slewing. ''' self._log.info('stopping...') if self.is_stopped(): self._log.warning('already stopped.') return True self._port_motor.stop() self._stbd_motor.stop() self._log.info('stopped.') return True # .......................................................................... def is_stopped(self): return self._port_motor.is_stopped() and self._stbd_motor.is_stopped() # Synchronisation Support ................................................................ # .......................................................................... def processStop(self, event, orientation): ''' Synchronised process control over various kinds of stopping. ''' if orientation is Orientation.PORT: if event is Event.HALT: self._log.info('halting port motor...') self._port_motor.halt() elif event is Event.BRAKE: self._log.info('braking port motor...') self._port_motor.brake() else: # is stop self._log.info('stopping port motor...') self._port_motor.stop() else: if event is Event.HALT: self._log.info('halting starboard motor...') self._stbd_motor.halt() elif event is Event.BRAKE: self._log.info('braking starboard motor...') self._stbd_motor.brake() else: # is stop self._log.info('stopping starboard motor...') self._stbd_motor.stop() self.print_current_power_levels() # .......................................................................... def get_current_power_levels(self): ''' Returns the last set power values. ''' _port_power = self._port_motor.get_current_power_level() _stbd_power = self._stbd_motor.get_current_power_level() return [_port_power, _stbd_power] # .......................................................................... def print_current_power_levels(self): ''' Prints the last set power values. ''' self._msgIndex += 1 self._log.info('{}:\tcurrent power:\t{:6.1f}\t{:6.1f}'.format( self._msgIndex, self._last_set_power[0], self._last_set_power[1])) # .......................................................................... @staticmethod def cancel(): print('cancelling motors...') Motor.cancel()
class JobQueueManager(): """ Handles the monitoring of the JobQueue and runs jobs """ def __init__(self, config, verbose, daemon=True): """ Parse config file and setup the logging """ self.config = config self.verbose = verbose self.daemon = daemon self.running = True self.logger = Logger(self.config.DAEMON.log_name, self.config.DAEMON.log_dir).get_logger() self.pidfile = self.config.DAEMON.pid_file self.api_manager = FrontendApiManager(self.config.API, logger=self.logger) self.sync_manager = SyncManager(self.api_manager, logger=self.logger) def daemonize(self): """ Turn this running process into a deamon """ # Perform first fork try: pid = os.fork() if pid > 0: self.logger.error('First fork returned but was >0, exiting') sys.exit(1) self.logger.debug('First fork worked') except OSError as e: self.logger.error('First fork failed ({0})'.format(e)) raise Exception(e) # Escape out of where we started os.chdir(self.config.DAEMON.working_dir) os.umask(self.config.DAEMON.umask) os.setsid() # Perform second fork try: pid = os.fork() if pid > 0: self.logger.error('Second fork returned but was >0, exiting') sys.exit(1) except OSError as e: self.logger.error('Second fork failed ({0})'.format(e)) raise Exception(e) # Close off the stdXXX self.logger.debug('Closing file descriptors') sys.stdout.flush() sys.stderr.flush() si = open(os.devnull, 'r') so = open(os.devnull, 'a+') se = open(os.devnull, 'a+') os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # Register the pid file deletion atexit.register(self.on_exit) # Write the PID to file pid = str(os.getpid()) with open(self.pidfile, 'w+') as f: f.write(pid + '\n') self.logger.debug("Written PID of '{0}' into file '{1}'".format(pid, self.pidfile)) def on_exit(self): """ Delete the PID file """ os.remove(self.pidfile) self.logger.debug('Removed the pid file ({0})'.format(self.pidfile)) def run(self): """ Main worker loop """ while self.running: # Loop over the job queue and handle any jobs that we are not processing yet job_queue = self.api_manager.get_job_queue() if not job_queue: self.logger.info('Job queue empty') for job in job_queue: try: self.sync_manager.handle(job) self.logger.info('Starting job {0}'.format(job['name'])) except self.sync_manager.AlreadyWorkingOnException: self.logger.debug('Already working on job {0}'.format(job['name'])) except self.sync_manager.ActionAlreadyWorkingOnException: self.logger.debug("action='{0}' job='{1}' message='action already working on'".format( job['action'], job['name'])) # Go over all queued jobs and complete any finished ones, report on what jobs we finished off for job in self.sync_manager.complete_jobs(): self.logger.info('Removed finished job {0}'.format(job)) # Sleep for a set time before checking the queue again sleep_time = float(self.config.DAEMON.sleep) self.logger.debug('Sleeping for {0} seconds'.format(sleep_time)) time.sleep(sleep_time) if not self.running: # Good-ish place to be in self.logger.warning('Main loop was stopped (running = False)') return True else: # Bad place to be in self.logger.warning('Main loop broke without us saying (running = True)') return False def start(self): """ Start the daemon """ # Check for a pidfile to see if the daemon already runs try: with open(self.pidfile, 'r') as pf: pid = int(pf.read().strip()) except IOError: if not os.path.isdir(os.path.dirname(self.pidfile)): print('ERROR: PID folder does not exist: {0}'.format(os.path.dirname(self.pidfile))) sys.exit(1) pid = None if pid: # pidfile exists, bail message = 'pidfile {0} already exists. Daemon already running?' self.logger.error(message.format(self.pidfile)) sys.exit(1) # Turn into a daemon if we are told to if self.daemon: self.daemonize() message = 'We are now a daemon, all stdout/stderr redirected' self.logger.debug(message) else: print('INFO: Skipping daemon mode') print('INFO: Log file: {0}'.format(self.logger.log_file)) # Work our magic self.run() # Finishing up properly self.logger.info('Finished successfully, bye bye!') return True def stop(self): """ Stop the daemon, kill off all jobs """ # Check for a pidfile to see if the daemon already runs try: with open(self.pidfile, 'r') as pf: pid = int(pf.read().strip()) except IOError: if not os.path.isdir(os.path.dirname(self.pidfile)): message = 'ERROR: PID folder does not exist: {0}' print(message.format(os.path.dirname(self.pidfile))) sys.exit(1) pid = None if not pid: message = 'pidfile {0} does not exist. Daemon not running?' self.logger.error(message.format(self.pidfile)) sys.exit(1) # Go over all queued jobs and close off any finished ones, report on the number we finished off for job in self.sync_manager.complete_jobs(): self.logger.info('Removed finished job {0}'.format(job)) # Go over all currently running jobs, report on them and then kill them. for process in self.sync_manager.processing_queue: self.logger.info('Still processing job {0}'.format(process.name)) # We now kill off the process, upon restart the job should restart again self.logger.warning('Killing job {0}'.format(process.name)) process.terminate() self.running = False