def __init__(self): rospy.init_node("mission_publisher", anonymous=True) config_path = rospy.get_param("~config") try: with open(config_path) as f: content = f.read() config = yaml.load(content, Loader=yaml.FullLoader) rospy.logdebug(f"Configuration dict: {content}") except Exception as e: while True: rospy.logerr("Configuration file is broken or not readable!") rospy.logerr(e) rospy.sleep(5) self.myroomba = Roomba(config["roomba"]["IP"], config["roomba"]["blid"], config["roomba"]["password"]) self.myroomba.connect() time.sleep(5) while not self.myroomba.roomba_connected: #print(1) time.sleep(1) print("Roomba connected") rospy.Service("send_command", Command, self.send_command) self.pub_mission = rospy.Publisher("mission", Mission, queue_size=10)
def listener_for_roombas(self, ros_msg): if len(ros_msg.localization_map) > 0: for msg in ros_msg.localization_map: ground_roomba = Roomba() ground_roomba.pos = ( msg.x, msg.y ) ground_roomba.id = msg.id self.update_active_roombas(ground_roomba)
def runMain(): # First, we import our devices from our configuration file. These will be split into two different groups, those # controlled by Philips Hue and those controlled by Insteon. configuration = Configuration() config = configuration.loadConfig() hueDevices = {} insteonDevices = {} for device in config['devices']['hue']: hueDevices[device] = config['devices']['hue'][device] for device in config['devices']['insteon']: insteonDevices[device] = config['devices']['insteon'][device] insteon = Insteon() hue = Hue() roomba = Roomba() # Now we set up the voice recognition using Pocketsphinx from CMU Sphinx. pocketSphinxListener = PocketSphinxListener() # We want to run forever, or until the user presses control-c, whichever comes first. while True: try: command = pocketSphinxListener.getCommand().lower() command = command.replace('the', '') if command.startswith('turn'): onOrOff = command.split()[1] deviceName = ''.join(command.split()[2:]) if deviceName in hueDevices: deviceId = hueDevices[deviceName]['deviceID'] hue.turn(deviceId=deviceId, onOrOff=onOrOff) if deviceName in insteonDevices: deviceId = insteonDevices[deviceName]['deviceID'] insteon.turn(deviceId=deviceId, onOrOff=onOrOff) if deviceName == 'roomba': roomba.turn(onOrOff) elif command.startswith('roomba'): action = ' '.join(command.split()[1:]) if action == 'clean': roomba.clean() if action == 'go home': roomba.goHome() # This will allow us to be good cooperators and sleep for a second. # This will give the other greenlets which we have created for talking # to the Hue and Insteon hubs a chance to run. gevent.sleep(1) except (KeyboardInterrupt, SystemExit): print 'People sometimes make mistakes, Goodbye.' sys.exit() except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout) sys.exit()
def run(self): logger.info('starting horizon agent') listen_queue = Queue(maxsize=settings.MAX_QUEUE_SIZE) pid = getpid() # Start the workers for i in range(settings.WORKER_PROCESSES): Worker(listen_queue, pid).start() # Start the listeners Listen(settings.PICKLE_PORT, listen_queue, pid, type="pickle").start() Listen(settings.UDP_PORT, listen_queue, pid, type="udp").start() # Start the roomba Roomba(pid).start() # Warn the Mac users try: listen_queue.qsize() except NotImplementedError: logger.info( 'WARNING: Queue().qsize() not implemented on Unix platforms like Mac OS X. Queue size logging will be unavailable.' ) # Keep yourself occupied, sucka while 1: time.sleep(100)
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): """Set up the iRobot Roomba vacuum cleaner platform.""" from roomba import Roomba if PLATFORM not in hass.data: hass.data[PLATFORM] = {} host = config.get(CONF_HOST) name = config.get(CONF_NAME) username = config.get(CONF_USERNAME) password = config.get(CONF_PASSWORD) certificate = config.get(CONF_CERT) continuous = config.get(CONF_CONTINUOUS) # Create handler roomba = Roomba(address=host, blid=username, password=password, cert_name=certificate, continuous=continuous) _LOGGER.info("Initializing communication with host %s (username: %s)", host, username) yield from hass.async_add_job(roomba.connect) roomba_vac = RoombaVacuum(name, roomba) hass.data[PLATFORM][host] = roomba_vac async_add_devices([roomba_vac], update_before_add=True)
def run(self): logger.info('starting horizon agent') listen_queue = Queue(maxsize=settings.MAX_QUEUE_SIZE) pid = getpid() #If we're not using oculus, don't bother writing to mini try: skip_mini = True if settings.OCULUS_HOST == '' else False except Exception: skip_mini = True # Start the workers for i in range(settings.WORKER_PROCESSES): if i == 0: Worker(listen_queue, pid, skip_mini, canary=True).start() else: Worker(listen_queue, pid, skip_mini).start() # Start the listeners Listen(settings.PICKLE_PORT, listen_queue, pid, type="pickle").start() Listen(settings.UDP_PORT, listen_queue, pid, type="udp").start() # Start the roomba Roomba(pid, skip_mini).start() # Warn the Mac users try: listen_queue.qsize() except NotImplementedError: logger.info('WARNING: Queue().qsize() not implemented on Unix platforms like Mac OS X. Queue size logging will be unavailable.') # Keep yourself occupied, sucka while 1: time.sleep(100)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the iRobot Roomba vacuum cleaner platform.""" from roomba import Roomba if PLATFORM not in hass.data: hass.data[PLATFORM] = {} host = config.get(CONF_HOST) name = config.get(CONF_NAME) username = config.get(CONF_USERNAME) password = config.get(CONF_PASSWORD) certificate = config.get(CONF_CERT) continuous = config.get(CONF_CONTINUOUS) roomba = Roomba(address=host, blid=username, password=password, cert_name=certificate, continuous=continuous) _LOGGER.debug("Initializing communication with host %s", host) try: with async_timeout.timeout(9): await hass.async_add_job(roomba.connect) except asyncio.TimeoutError: raise PlatformNotReady roomba_vac = RoombaVacuum(name, roomba) hass.data[PLATFORM][host] = roomba_vac async_add_entities([roomba_vac], True)
def generateRoombas(walls, dropOffs, dirts, superDirts, furnitures): roombas = [] for i in range(Consts.NUM_ROOMBAS.value): startx = random.randint(5, CELLWIDTH - 6) starty = random.randint(5, CELLHEIGHT - 6) roombas.append( Roomba(startx, starty, walls, dropOffs, dirts, superDirts, furnitures, AREA, i)) return roombas
async def async_setup_entry(hass, config_entry): """Set the config entry up.""" # Set up roomba platforms with config entry if not config_entry.options: hass.config_entries.async_update_entry( config_entry, options={ "continuous": config_entry.data[CONF_CONTINUOUS], "delay": config_entry.data[CONF_DELAY], }, ) roomba = Roomba( address=config_entry.data[CONF_HOST], blid=config_entry.data[CONF_BLID], password=config_entry.data[CONF_PASSWORD], cert_name=config_entry.data[CONF_CERT], continuous=config_entry.options[CONF_CONTINUOUS], delay=config_entry.options[CONF_DELAY], ) roomba.exclude = "wifistat" # ignore wifistat to avoid unnecessary updates try: if not await async_connect_or_timeout(hass, roomba): return False except CannotConnect: raise exceptions.ConfigEntryNotReady hass.data[DOMAIN][config_entry.entry_id] = { ROOMBA_SESSION: roomba, BLID: config_entry.data[CONF_BLID], } for component in COMPONENTS: hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) if not config_entry.update_listeners: config_entry.add_update_listener(async_update_options) return True
def run(self): """ Determine the `MAX_QUEUE_SIZE` for the listen process. Determine if horizon should populate the mini redis store for Oculus. Starts the defined number of `WORKER_PROCESSES`, with the first worker populating the canary metric. Start the pickle (and UDP) listen processes. Start roomba. """ logger.info('agent starting skyline %s' % skyline_app) listen_queue = Queue(maxsize=settings.MAX_QUEUE_SIZE) pid = getpid() # If we're not using oculus, don't bother writing to mini try: skip_mini = True if settings.OCULUS_HOST == '' else False except Exception: skip_mini = True # Start the workers for i in range(settings.WORKER_PROCESSES): if i == 0: logger.info('%s :: starting Worker - canary' % skyline_app) Worker(listen_queue, pid, skip_mini, canary=True).start() else: logger.info('%s :: starting Worker' % skyline_app) Worker(listen_queue, pid, skip_mini).start() # Start the listeners logger.info('%s :: starting Listen - pickle' % skyline_app) Listen(settings.PICKLE_PORT, listen_queue, pid, type="pickle").start() logger.info('%s :: starting Listen - udp' % skyline_app) Listen(settings.UDP_PORT, listen_queue, pid, type="udp").start() # Start the roomba logger.info('%s :: starting Roomba' % skyline_app) Roomba(pid, skip_mini).start() # Warn the Mac users try: listen_queue.qsize() except NotImplementedError: logger.info( 'WARNING: Queue().qsize() not implemented on Unix platforms like Mac OS X. Queue size logging will be unavailable.' ) # Keep yourself occupied, sucka while 1: time.sleep(100)
class PublishMission: def __init__(self): rospy.init_node("mission_publisher", anonymous=True) config_path = rospy.get_param("~config") try: with open(config_path) as f: content = f.read() config = yaml.load(content, Loader=yaml.FullLoader) rospy.logdebug(f"Configuration dict: {content}") except Exception as e: while True: rospy.logerr("Configuration file is broken or not readable!") rospy.logerr(e) rospy.sleep(5) self.myroomba = Roomba(config["roomba"]["IP"], config["roomba"]["blid"], config["roomba"]["password"]) rospy.Service("send_command", Command, self.send_command) self.pub_mission = rospy.Publisher("mission", Mission, queue_size=10) def send_command(self, req): if req.command == "Start": self.myroomba.send_command("start") return ("Starting cleaning") elif req.command == "Stop": self.myroomba.send_command("stop") return ("Stop cleaning") elif req.command == "Home": self.myroomba.send_command("dock") return ("Going back home") else: return ("Wrong command") def get_msg_data(self, data, data_state): miss_msg = Mission() miss_msg.name = data["name"] miss_msg.batteryPercentage = str(data["batPct"]) miss_msg.mission_cycle = data["cleanMissionStatus"]["cycle"] miss_msg.mission_phase = data["cleanMissionStatus"]["phase"] miss_msg.current_state = data_state miss_msg.error = str(data["cleanMissionStatus"]["error"]) miss_msg.mission_notReady = str(data["cleanMissionStatus"]["notReady"]) miss_msg.robotPositionXY[0] = data["pose"]["point"]["x"] miss_msg.robotPositionXY[1] = data["pose"]["point"]["y"] miss_msg.robotPositionAngle = data["pose"]["theta"] miss_msg.audio = str(data["audio"]["active"]) return (miss_msg) def spin(self): rate = rospy.Rate(1) while not rospy.is_shutdown(): data_state = self.myroomba.current_state data1 = self.myroomba.master_state data = data1["state"]["reported"] mission_msg = self.get_msg_data(data, data_state) self.pub_mission.publish(mission_msg) rate.sleep()
async def validate_input(hass: core.HomeAssistant, data): """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. """ roomba = Roomba( address=data[CONF_HOST], blid=data[CONF_BLID], password=data[CONF_PASSWORD], continuous=data[CONF_CONTINUOUS], delay=data[CONF_DELAY], ) info = await async_connect_or_timeout(hass, roomba) return { ROOMBA_SESSION: info[ROOMBA_SESSION], CONF_NAME: info[CONF_NAME], CONF_HOST: data[CONF_HOST], }
def main(): arg = parse_args() #----------- Local Routines ------------ def broker_on_connect(client, userdata, flags, rc): log.debug("Broker Connected with result code " + str(rc)) #subscribe to roomba feedback, if there is more than one roomba, the # roombaName is added to the topic to subscribe to if rc == 0: if brokerCommand != "": if len(roombas) == 1: mqttc.subscribe(brokerCommand) else: for myroomba in roomba_list: mqttc.subscribe(brokerCommand + "/" + myroomba.roombaName) if brokerSetting != "": if len(roombas) == 1: mqttc.subscribe(brokerSetting) else: for myroomba in roomba_list: mqttc.subscribe(brokerSetting + "/" + myroomba.roombaName) def broker_on_message(mosq, obj, msg): # publish to roomba, if there is more than one roomba, the roombaName # is added to the topic to publish to msg.payload = msg.payload.decode("utf-8") if "command" in msg.topic: log.info("Received COMMAND: %s" % str(msg.payload)) if len(roombas) == 1: roomba_list[0].send_command(str(msg.payload)) else: for myroomba in roomba_list: if myroomba.roombaName in msg.topic: myroomba.send_command(str(msg.payload)) elif "setting" in msg.topic: log.info("Received SETTING: %s" % str(msg.payload)) cmd = str(msg.payload).split() if len(roombas) == 1: roomba_list[0].set_preference(cmd[0], cmd[1]) else: for myroomba in roomba_list: if myroomba.roombaName in msg.topic: myroomba.set_preference(cmd[0], cmd[1]) else: log.warn("Unknown topic: %s" % str(msg.topic)) def broker_on_publish(mosq, obj, mid): pass def broker_on_subscribe(mosq, obj, mid, granted_qos): log.debug("Broker Subscribed: %s %s" % (str(mid), str(granted_qos))) def broker_on_disconnect(mosq, obj, rc): log.debug("Broker disconnected") if rc == 0: sys.exit(0) def broker_on_log(mosq, obj, level, string): log.info(string) def read_config_file(file="./config.ini"): #read config file Config = configparser.ConfigParser() try: Config.read(file) log.info("reading info from config file %s" % file) roombas = {} for address in Config.sections(): roomba_data = literal_eval(Config.get(address, "data")) roombas[address] = { "blid": Config.get(address, "blid"), "password": Config.get(address, "password"), "roombaName": roomba_data.get("robotname", None) } except Exception as e: log.warn("Error reading config file %s" % e) return roombas def create_html(myroomba, mapPath="."): ''' Create html files for live display of roomba maps - but only if they don't already exist ''' #default css and html css = '''body { background-color: white; color: white; margin: 0; padding: 0; } img,video { width: auto; max-height:100%; } ''' html = '''<!DOCTYPE html> <html> <head> <link href="style.css" rel="stylesheet" type="text/css"> </head> <script> function refresh(node) { var times = 1000; // gap in Milli Seconds; (function startRefresh() { var address; if(node.src.indexOf('?')>-1) address = node.src.split('?')[0]; else address = node.src; node.src = address+"?time="+new Date().getTime(); setTimeout(startRefresh,times); })(); } window.onload = function() { var node = document.getElementById('img'); refresh(node); // you can refresh as many images you want just repeat above steps } </script> <body> ''' html += '<img id="img" src="%smap.png" alt="Roomba Map Live" style="position:absolute;top:0;left:0"/>' % myroomba.roombaName html += ''' </body> </html> ''' #python 3 workaround try: FileNotFoundError except NameError: #py2 FileNotFoundError = PermissionError = IOError #check is style.css exists, if not create it css_path = mapPath + "/style.css" try: fn = open(css_path, "r") #check if file exists (or is readable) fn.close() except (IOError, FileNotFoundError): log.warn("CSS file not found, creating %s" % css_path) try: with open(css_path, "w") as fn: fn.write(css) except (IOError, PermissionError) as e: log.error("unable to create file %s, error: %s" % css_path, e) #check is html exists, if not create it html_path = mapPath + "/" + myroomba.roombaName + "roomba_map.html" try: fn = open(html_path, "r") #check if file exists (or is readable) fn.close() except (IOError, FileNotFoundError): log.warn("html file not found, creating %s" % html_path) try: with open(html_path, "w") as fn: fn.write(html) make_executable(html_path) except (IOError, PermissionError) as e: log.error("unable to create file %s, error: %s" % html_path, e) def make_executable(path): mode = os.stat(path).st_mode mode |= (mode & 0o444) >> 2 # copy R bits to X os.chmod(path, mode) def setup_logger(logger_name, log_file, level=logging.DEBUG, console=False): try: l = logging.getLogger(logger_name) if logger_name == __name__: formatter = logging.Formatter( '[%(levelname)1.1s %(asctime)s] %(message)s') else: formatter = logging.Formatter('%(message)s') if log_file: fileHandler = RotatingFileHandler(log_file, mode='a', maxBytes=2000000, backupCount=5) fileHandler.setFormatter(formatter) if console == True: streamHandler = logging.StreamHandler() l.setLevel(level) if log_file: l.addHandler(fileHandler) if console == True: streamHandler.setFormatter(formatter) l.addHandler(streamHandler) except IOError as e: if e[0] == 13: #errno Permission denied print("Error: %s: You probably don't have permission to " "write to the log file/directory - try sudo" % e) else: print("Log Error: %s" % e) sys.exit(1) args = parse_args() if arg.debug: log_level = logging.DEBUG else: log_level = logging.INFO #setup logging setup_logger(__name__, arg.log, level=log_level, console=arg.echo) log = logging.getLogger(__name__) log.info("*******************") log.info("* Program Started *") log.info("*******************") log.info("Roomba.py Version: %s" % __version__) log.info("Python Version: %s" % sys.version.replace('\n', '')) if HAVE_MQTT: import paho.mqtt # bit of a kludge, just to get the version number log.info("Paho MQTT Version: %s" % paho.mqtt.__version__) if (sys.version_info.major == 2 and sys.version_info.minor == 7 and sys.version_info.micro < 9 and int(paho.mqtt.__version__.split(".")[0]) >= 1 and int(paho.mqtt.__version__.split(".")[1]) > 2): log.error("NOTE: if your python version is less than 2.7.9, " "and Paho MQTT verion is not 1.2.3 or lower, this " "program will NOT WORK") log.error("Please use <sudo> pip install paho-mqtt==1.2.3 to " "downgrade paho-mqtt, or use a later version of python") sys.exit(1) if HAVE_CV2: log.info("CV Version: %s" % cv2.__version__) if HAVE_PIL: import PIL #bit of a kludge, just to get the version number log.info("PIL Version: %s" % PIL.__version__) if int(PIL.__version__.split(".")[0]) < 4: log.warn("WARNING: PIL version is %s, this is not the latest! " "You can get bad memory leaks with old versions of PIL" % Image.__version__) log.warn("run: 'pip install --upgrade pillow' to fix this") log.debug("-- DEBUG Mode ON -") log.info("<CNTRL C> to Exit") log.info("Roomba 980 MQTT data Interface") roombas = {} if arg.blid is None or arg.roombaPassword is None: roombas = read_config_file(arg.configfile) if len(roombas) == 0: log.warn("No roomba or config file defined, I will attempt to " "discover Roombas, please put the Roomba on the dock " "and follow the instructions:") if arg.roombaIP is None: Password(file=arg.configfile) else: Password(arg.roombaIP, file=arg.configfile) roombas = read_config_file(arg.configfile) if len(roombas) == 0: log.error("No Roombas found! You must specify RoombaIP, blid " "and roombaPassword to run this program, or have " "a config file, use -h to show options.") sys.exit(0) else: log.info("Success! %d Roombas Found!" % len(roombas)) else: roombas[arg.roombaIP] = { "blid": arg.blid, "password": arg.roombaPassword, "roombaName": arg.roombaName } # set broker = "127.0.0.1" # mosquitto broker is running on localhost mqttc = None if arg.broker is not None: brokerCommand = arg.brokerCommand brokerSetting = arg.brokerSetting # connect to broker mqttc = mqtt.Client() # Assign event callbacks mqttc.on_message = broker_on_message mqttc.on_connect = broker_on_connect mqttc.on_disconnect = broker_on_disconnect mqttc.on_publish = broker_on_publish mqttc.on_subscribe = broker_on_subscribe # uncomment to enable logging # mqttc.on_log = broker_on_log try: if arg.user != None: mqttc.username_pw_set(arg.user, arg.password) log.info("connecting to broker") # Ping MQTT broker every 60 seconds if no data is published # from this script. mqttc.connect(arg.broker, arg.port, 60) except socket.error: log.error("Unable to connect to MQTT Broker") mqttc = None roomba_list = [] for addr, info in six.iteritems(roombas): log.info("Creating Roomba object %s" % addr) #NOTE: cert_name is a default certificate. change this if your # certificates are in a different place. any valid certificate will # do, it's not used but needs to be there to enable mqtt TLS encryption # instansiate Roomba object # minnimum required to connect on Linux Debian system # myroomba = Roomba(address, blid, roombaPassword) roomba_list.append( Roomba(addr, blid=info["blid"], password=info["password"], topic=arg.topic, continuous=arg.continuous, clean=False, cert_name=args.cert, roombaName=info["roombaName"])) for myroomba in roomba_list: log.info("connecting Roomba %s" % myroomba.address) # all these are optional, if you don't include them, the defaults # will work just fine if arg.exclude != "": myroomba.exclude = arg.exclude myroomba.set_options(raw=arg.raw, indent=arg.indent, pretty_print=arg.pretty_print) if not arg.continuous: myroomba.delay = arg.delay // 1000 if arg.mapSize != "" and arg.mapPath != "": # auto create html files (if they don't exist) create_html(myroomba, arg.mapPath) # enable live maps, class default is no maps myroomba.enable_map(enable=True, mapSize=arg.mapSize, mapPath=arg.mapPath, iconPath=arg.iconPath, roomOutline=arg.roomOutline) if arg.broker is not None: # if you want to publish Roomba data to your own mqtt broker # (default is not to) if you have more than one roomba, and # assign a roombaName, it is addded to this topic # (ie brokerFeedback/roombaName) myroomba.set_mqtt_client(mqttc, arg.brokerFeedback) # finally connect to Roomba - (required!) myroomba.connect() try: if mqttc is not None: mqttc.loop_forever() else: while True: log.info("Roomba Data: %s" % json.dumps(myroomba.master_state, indent=2)) time.sleep(5) except (KeyboardInterrupt, SystemExit): log.info("System exit Received - Exiting program") mqttc.disconnect() sys.exit(0)
def run(self): """ Determine the `MAX_QUEUE_SIZE` for the listen process. Determine if horizon should populate the mini redis store for Oculus. Starts the defined number of `WORKER_PROCESSES`, with the first worker populating the canary metric. Start the pickle (and UDP) listen processes. Start roomba. """ logger.info('agent starting skyline %s' % skyline_app) listen_queue = Queue(maxsize=settings.MAX_QUEUE_SIZE) pid = getpid() # If we're not using oculus, don't bother writing to mini try: skip_mini = True if settings.OCULUS_HOST == '' else False except Exception: skip_mini = True # Start the workers for i in range(settings.WORKER_PROCESSES): if i == 0: # @modified 20201017 - Feature #3788: snab_flux_load_test # Feature #3680: horizon.worker.datapoints_sent_to_redis # Added worker_number logger.info( '%s :: starting Worker - canary, worker number %s' % (skyline_app, str(i))) Worker(listen_queue, pid, skip_mini, worker_number=i, canary=True).start() else: logger.info('%s :: starting Worker, worker number %s' % (skyline_app, str(i))) Worker(listen_queue, pid, skip_mini, worker_number=i, canary=False).start() # Start the listeners logger.info('%s :: starting Listen - pickle' % skyline_app) Listen(settings.PICKLE_PORT, listen_queue, pid, type="pickle").start() logger.info('%s :: starting Listen - udp' % skyline_app) Listen(settings.UDP_PORT, listen_queue, pid, type="udp").start() # @added 20201122 - Feature #3820: HORIZON_SHARDS # Add an additional listen process on a different port for the shard if HORIZON_SHARDS: if HORIZON_SHARD_PICKLE_PORT: logger.info( '%s :: starting Listen - pickle for horizon shard on port %s' % (skyline_app, str(settings.HORIZON_SHARD_PICKLE_PORT))) try: Listen(settings.HORIZON_SHARD_PICKLE_PORT, listen_queue, pid, type="pickle").start() except Exception as e: logger.error( 'error :: agent.py falied to start Listen for horizon shard - %s' % str(e)) else: logger.error( 'error :: agent.py could not start the horizon shard Listen process as no port' ) # Start the roomba logger.info('%s :: starting Roomba' % skyline_app) Roomba(pid, skip_mini).start() # Warn the Mac users try: listen_queue.qsize() except NotImplementedError: logger.info( 'WARNING: Queue().qsize() not implemented on Unix platforms like Mac OS X. Queue size logging will be unavailable.' ) # Keep yourself occupied, sucka while 1: time.sleep(100)
def main(): #----------- Local Routines ------------ def create_html(myroomba,mappath="."): ''' Create html files for live display of roomba maps - but only if they don't already exist NOTE add {{ for { in html where you need variable substitution ''' #default css and html css = '''\ body { background-color: white; margin: 0; color: white; padding: 0; } img,video { width: auto; max-height:100%; } ''' html = '''\ <!DOCTYPE html> <html> <head> <link href="style.css" rel="stylesheet" type="text/css"> </head> <script> function refresh(node) {{ var times = 1000; // gap in Milli Seconds; (function startRefresh() {{ var address; if(node.src.indexOf('?')>-1) address = node.src.split('?')[0]; else address = node.src; node.src = address+"?time="+new Date().getTime(); setTimeout(startRefresh,times); }})(); }} window.onload = function() {{ var node = document.getElementById('img'); refresh(node); // you can refresh as many images you want just repeat above steps }} </script> <body> <img id="img" src="{}map.png" alt="Roomba Map Live" style="position:absolute;top:0;left:0"/> </body> </html> '''.format(myroomba.roombaName) def write_file(fname, data, mode=0o666): if not os.path.isfile(fname): log.warn("{} file not found, creating".format(fname)) try: with open(fname , "w") as fn: fn.write(textwrap.dedent(data)) os.chmod(fname, mode) except (IOError, PermissionError) as e: log.error("unable to create file {}, error: {}".format(fname, e)) #check if style.css exists, if not create it css_path = '{}/style.css'.format(mappath) write_file(css_path, css) #check if html exists, if not create it html_path = '{}/{}roomba_map.html'.format(mappath, myroomba.roombaName) write_file(html_path, html, 0o777) def setup_logger(logger_name, log_file, level=logging.DEBUG, console=False): try: l = logging.getLogger(logger_name) formatter = logging.Formatter('[%(asctime)s][%(levelname)5.5s](%(name)-20s) %(message)s') if log_file is not None: fileHandler = logging.handlers.RotatingFileHandler(log_file, mode='a', maxBytes=10000000, backupCount=10) fileHandler.setFormatter(formatter) if console == True: #formatter = logging.Formatter('[%(levelname)1.1s %(name)-20s] %(message)s') streamHandler = logging.StreamHandler() streamHandler.setFormatter(formatter) l.setLevel(level) if log_file is not None: l.addHandler(fileHandler) if console == True: l.addHandler(streamHandler) except Exception as e: print("Error in Logging setup: %s - do you have permission to write the log file??" % e) sys.exit(1) arg = parse_args() #note: all options can be included in the config file if arg.debug: log_level = logging.DEBUG else: log_level = logging.INFO #setup logging setup_logger('Roomba', arg.log, level=log_level,console=arg.echo) #log = logging.basicConfig(level=logging.DEBUG, # format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') log = logging.getLogger('Roomba') log.info("*******************") log.info("* Program Started *") log.info("*******************") log.debug('Debug Mode') log.info("Roomba.py Version: %s" % Roomba.__version__) log.info("Python Version: %s" % sys.version.replace('\n','')) if HAVE_MQTT: import paho.mqtt log.info("Paho MQTT Version: %s" % paho.mqtt.__version__) if HAVE_CV2: log.info("CV Version: %s" % cv2.__version__) if HAVE_PIL: import PIL #bit of a kludge, just to get the version number log.info("PIL Version: %s" % PIL.__version__) log.debug("-- DEBUG Mode ON -") log.info("<CNTRL C> to Exit") log.info("Roomba MQTT data Interface") group = None options = vars(arg) #use args as dict if arg.blid is None or arg.password is None: get_passwd = Password(arg.roomba_ip,file=arg.configfile) roombas = get_passwd.get_roombas() else: roombas = {arg.roomba_ip: {"blid": arg.blid, "password": arg.password, "roomba_name": arg.roomba_name}} roomba_list = [] for addr, info in roombas.items(): log.info("Creating Roomba object {}, {}".format(addr, info.get("roomba_name", addr))) #get options from config (if they exist) this overrides command line options. for opt, value in options.copy().items(): config_value = info.get(opt) if config_value is None: options[opt] = value elif value is None or isinstance(value, str): options[opt] = config_value else: options[opt] = literal_eval(str(config_value)) # minnimum required to connect on Linux Debian system # myroomba = Roomba(address, blid, roombaPassword) myroomba = Roomba(addr, blid=arg.blid, password=arg.password, topic=arg.topic, roombaName=arg.roomba_name, webport=arg.webport) if arg.webport: arg.webport+=1 if arg.exclude: myroomba.exclude = arg.exclude #set various options myroomba.set_options(raw=arg.raw, indent=arg.indent, pretty_print=arg.pretty_print, max_sqft=arg.max_sqft) if arg.mappath and arg.mapsize and arg.drawmap: # auto create html files (if they don't exist) create_html(myroomba, arg.mappath) # enable live maps, class default is no maps myroomba.enable_map(enable=True, mapSize=arg.mapsize, mapPath=arg.mappath, iconPath=arg.iconpath, roomOutline=arg.room_outline, floorplan=arg.floorplan) if arg.broker is not None: # if you want to publish Roomba data to your own mqtt broker # (default is not to) if you have more than one roomba, and # assign a roombaName, it is addded to this topic # (ie brokerFeedback/roombaName) myroomba.setup_mqtt_client(arg.broker, arg.port, arg.user, arg.broker_password, arg.broker_feedback, arg.broker_command, arg.broker_setting) roomba_list.append(myroomba) loop = asyncio.get_event_loop() loop.set_debug(arg.debug) group = asyncio.gather(*[myroomba.async_connect() for myroomba in roomba_list]) if not group: for myroomba in roomba_list: myroomba.connect() #start each roomba connection individually try: loop.run_forever() except (KeyboardInterrupt, SystemExit): log.info("System exit Received - Exiting program") for myroomba in roomba_list: myroomba.disconnect() log.info('Program Exited') finally: pass
def build_matrix(row_count, column_count): matrix = [] counter = 1 for _ in range(row_count): row = [] matrix.append(row) for _ in range(column_count): row.append(counter) counter += 1 return matrix if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('rows', help='number of rows in the input matrix') parser.add_argument('columns', help='number of columns in the input matrix') args = parser.parse_args() try: rows = int(args.rows) cols = int(args.columns) except ValueError: parser.error('rows and columns must be integers') start = 0, 0 if rows < 1 or cols < 1: parser.error('rows and columns must be positive integers') r = Roomba(build_matrix(rows, cols)) r.start()
import json from roomba import Roomba #logging.basicConfig(level=logging.DEBUG) if len(sys.argv) < 4: print("Usage: roombaStatus.py <username> <password>") exit() os.chdir('./roomba') ip = sys.argv[1] username = sys.argv[2] password = sys.argv[3] #print("Roomba(" + ip + "," + username + "," + password + ")") myroomba = Roomba(ip, username, password) #print("myroomba.send_command(" + cmd + ")") myroomba.connect() for i in range(10): time.sleep(1) if myroomba.roomba_connected: break if myroomba.roomba_connected: print(json.dumps(myroomba.master_state)) time.sleep(1) else: print("Connection error") myroomba.disconnect()
mqttc.on_subscribe = broker_on_subscribe try: mqttc.username_pw_set( user, password ) # put your own mqtt user and password here if you are using them, otherwise comment out mqttc.connect( broker, 1883, 60 ) # Ping MQTT broker every 60 seconds if no data is published from this script. except Exception as e: print("Unable to connect to MQTT Broker: %s" % e) mqttc = None myroomba = ( Roomba() ) # minnimum required to connect on Linux Debian system, will read connection from config file # myroomba = Roomba(address, blid, roombaPassword, topic="#", continuous=True, clean=False, cert_name = "./ca-certificates.crt") #setting things manually # all these are optional, if you don't include them, the defaults will work just fine # if you are using maps myroomba.enable_map( enable=True, mapSize="(800,1650,-300,-50,2,0)", mapPath="./", iconPath="./") # enable live maps, class default is no maps if broker is not None: myroomba.set_mqtt_client( mqttc, brokerFeedback ) # if you want to publish Roomba data to your own mqtt broker (default is not to) if you have more than one roomba, and assign a roombaName, it is addded to this topic (ie brokerFeedback/roombaName) # finally connect to Roomba - (required!)
mqttc.on_publish = broker_on_publish mqttc.on_subscribe = broker_on_subscribe try: mqttc.username_pw_set( user, password ) #put your own mqtt user and password here if you are using them, otherwise comment out mqttc.connect( broker, 1883, 60 ) #Ping MQTT broker every 60 seconds if no data is published from this script. except Exception as e: print("Unable to connect to MQTT Broker: %s" % e) mqttc = None myroomba = Roomba( ) #minnimum required to connect on Linux Debian system, will read connection from config file #myroomba = Roomba(address, blid, roombaPassword, topic="#", continuous=True, clean=False, cert_name = "./ca-certificates.crt") #setting things manually #all these are optional, if you don't include them, the defaults will work just fine #if you are using maps myroomba.enable_map(enable=True, mapSize="(800,1650,-300,-50,2,0)", mapPath="./", iconPath="./") #enable live maps, class default is no maps if broker is not None: myroomba.set_mqtt_client( mqttc, brokerFeedback ) #if you want to publish Roomba data to your own mqtt broker (default is not to) if you have more than one roomba, and assign a roombaName, it is addded to this topic (ie brokerFeedback/roombaName) #finally connect to Roomba - (required!) myroomba.connect()
from roomba import Roomba #uncomment the option you want to run, and replace address, blid and roombaPassword with your own values address = "192.168.100.181" blid = "3115850251687850" roombaPassword = "******" myroomba = Roomba(address, blid, roombaPassword) #or myroomba = Roomba() #if you have a config file - will attempt discovery if you don't myroomba.connect() myroomba.set_preference("carpetBoost", "true") #myroomba.set_preference("twoPass", "false") #myroomba.send_command("start") #myroomba.send_command("stop") #myroomba.send_command("dock") import json, time for i in range(5): print json.dumps(myroomba.master_state, indent=2) time.sleep(1) myroomba.disconnect()
#!/usr/local/bin/python3 from roomba import Roomba if __name__ == '__main__': matrix = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]] r = Roomba(matrix) r.start() ''' 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 8 12 11 10 9 5 6 7 '''
# engine.runAndWait() # time.sleep(1) # x = 5 / 0 # Testing stopper def say(x): print(x) #engine.say(x) #engine.runAndWait() address = "192.168.86.41" blid = "3144400081327670" roombaPassword = "******" myroomba = Roomba(address, blid, roombaPassword, continuous=True) #or myroomba = Roomba() #if you have a config file - will attempt discovery if you don't myroomba.connect() say('I am starting the roomba.') myroomba.send_command("start") time.sleep(14) say('I am docking the roomba.') print("Docking...") myroomba.send_command("stop") time.sleep(2) say('I am docking the roomba.') myroomba.send_command("dock") time.sleep(2)
from roomba import Roomba #logging.basicConfig(level=logging.DEBUG) if len(sys.argv) < 5: print("Usage: roombaCmd.py <command> <ip> <username> <password>") exit() os.chdir('./roomba') cmd = sys.argv[1] ip = sys.argv[2] username = sys.argv[3] password = sys.argv[4] #print("Roomba(" + ip + "," + username + "," + password + ")") myroomba = Roomba(ip, username, password) #print("myroomba.send_command(" + cmd + ")") myroomba.connect() for i in range(10): time.sleep(1) if myroomba.roomba_connected: break if myroomba.roomba_connected: myroomba.send_command(cmd) time.sleep(1) else: print("Connection error") myroomba.disconnect()
mqttc.on_message = broker_on_message mqttc.on_connect = broker_on_connect mqttc.on_disconnect = broker_on_disconnect mqttc.on_publish = broker_on_publish mqttc.on_subscribe = broker_on_subscribe try: mqttc.username_pw_set(user, password) #put your own mqtt user and password here if you are using them, otherwise comment out mqttc.connect(broker, 1883, 60) #Ping MQTT broker every 60 seconds if no data is published from this script. except Exception as e: print("Unable to connect to MQTT Broker: %s" % e) mqttc = None #myroomba = Roomba() #minnimum required to connect on Linux Debian system, will read connection from config file myroomba = Roomba(address, blid, roombaPassword) #myroomba = Roomba(address, blid, roombaPassword, topic="#", continuous=True, clean=False, cert_name = "./ca-certificates.crt") #setting things manually #all these are optional, if you don't include them, the defaults will work just fine #if you are using maps myroomba.enable_map(enable=True, mapSize="(800,1650,-300,-50,2,0)", mapPath="./", iconPath="./") #enable live maps, class default is no maps if broker is not None: myroomba.set_mqtt_client(mqttc, brokerFeedback) #if you want to publish Roomba data to your own mqtt broker (default is not to) if you have more than one roomba, and assign a roombaName, it is addded to this topic (ie brokerFeedback/roombaName) #finally connect to Roomba - (required!) myroomba.connect() print("<CMTRL C> to exit") print("Subscribe to /roomba/feedback/# to see published data") try: if mqttc is not None:
#!/usr/bin/env python import rospy from roomba import Roomba import geometry_msgs.msg import roomba_msgs.msg import std_msgs.msg import sensor_msgs.msg import nav_msgs.msg rospy.init_node("roomba_hw") device_name = rospy.get_param("~dev", default="/dev/ttyACM0") rba = Roomba(device_name) drive = [0, 0] leds = [False, False, False, False, 0, 0] vacum = [False, False, False, False] def on_cmd_vel(m): global drive drive = [m.linear.x, m.angular.z] def on_leds(m): global leds leds = [ m.check, m.dock, m.spot, m.debris, m.clean_color, m.clean_intensity ] def on_vacum(m): global vacum vacum = [ m.vacum, m.main_brush, m.brush != 0, m.brush == 1 ]
user, password ) #put your own mqtt user and password here if you are using them, otherwise comment out mqttc.connect( broker, 1883, 60 ) #Ping MQTT broker every 60 seconds if no data is published from this script. except Exception as e: print("Unable to connect to MQTT Broker: %s" % e) mqttc = None #myroomba = Roomba() #minnimum required to connect on Linux Debian system, will read connection from config file myroomba = Roomba( address, blid, roombaPassword, topic="#", continuous=True, clean=False, cert_name="/etc/ssl/certs/Go_Daddy_Root_Certificate_Authority_-_G2.pem" ) #setting things manually #all these are optional, if you don't include them, the defaults will work just fine #if you are using maps # 11m x 11m + 5m Y DIFF to cover upper foor # 650 x 1020 # 1100 / 2 - 100 = 450 # 1370 / 2 - 335 = 350 #myroomba.enable_map(enable=True, enableMapWithText=False, roomOutline=False, rssiMap=True, rssiMapGoodSignal=-30, rssiMapBadSignal=-70, auto_rotate=False, mapSize="(1100,1370,-100,-240,0,0)", mapPath="/dataDisk/htdocs/roomba", iconPath="/dataDisk/Roomba980-Python/roomba/res/") #enable live maps, class default is myroomba.enable_map( enable=True, enableMapWithText=False,
from roomba import Roomba from simulation import * from state_machine import FiniteStateMachine, MoveForwardState pygame.init() window = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Lab 1 - Roomba Finite State Machine") clock = pygame.time.Clock() behavior = FiniteStateMachine(MoveForwardState()) # behavior = RoombaBehaviorTree() pose = Pose(PIX2M * SCREEN_WIDTH / 2.0, PIX2M * SCREEN_HEIGHT / 2.0, 0.0) roomba = Roomba(pose, 1.0, 2.0, 0.34 / 2.0, behavior) simulation = Simulation(roomba) run = True while run: clock.tick(FREQUENCY) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False simulation.update() draw(simulation, window) pygame.quit()
import logging from roomba import Roomba #Uncomment the following two lines to see logging output logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') #uncomment the option you want to run, and replace address, blid and roombaPassword with your own values address = "192.168.1.181" blid = "3835850251647850" roombaPassword = "******" #myroomba = Roomba(address, blid, roombaPassword) #or myroomba = Roomba(address) #if you have a config file - will attempt discovery if you don't myroomba = Roomba() async def test(): myroomba.connect() #myroomba.set_preference("carpetBoost", "true") #myroomba.set_preference("twoPass", "false") #myroomba.send_command("start") #myroomba.send_command("stop") #myroomba.send_command("dock") import json, time for i in range(10): print(json.dumps(myroomba.master_state, indent=2)) await asyncio.sleep(1) myroomba.disconnect()