def hid_on(self): try: # Pull the clock high to enable the USB interface self.clk.outputMode() self.clk.high() for i in range(5, 1): time.sleep(1) print(i, flush=True) dTimeout = 30 dPoll = 1 print('d') r, _ = output_shell(f'{cfg.paths.root}/apps/flash ') print(r) while not r.startswith('/dev/tty') and dTimeout > 0: time.sleep(dPoll) print('d') r, _ = output_shell(f'{cfg.paths.root}/apps/flash') dTimeout -= dPoll print('.') if dTimeout <= 0: print(f'Failed to find Moth: {r}') except: print('Error occurred while enabling USB HID') finally: self.clk.low() return True, r.strip()
def unmount_device(self, device_path: str): r, success = output_shell(f'sudo umount {device_path}') if not success: print(f'Unmount failed: {r}') parent_device_path = device_path.rstrip('1234567890') r, success = output_shell(f'sudo eject {parent_device_path}') return success
def flash(self): try: success, serial_path = self.hid_on() if not success: print('Flash failed. HID not enabled') raise EnvironmentError('HID not enabled') r, success = output_shell( f'{cfg.paths.root}/apps/flash -i {serial_path}') i_max = 5 for i in range(1, i_max): if success: serial_number = r.strip() print(f'{serial_number}') break else: print(f'Attempt {i} - Failed getting serial {r}') print('n') r, success = output_shell( f'{cfg.paths.root}/apps/flash -i {serial_path}') time.sleep(1) flash_image = f'{cfg.paths.root}/apps/AudioMoth-Project.bin' if success and os.path.exists(flash_image): print( f'Flashing {serial_path} ({serial_number}) with {flash_image}' ) for i in range(1, i_max): print('f') r, success = output_shell( f'{cfg.paths.root}/apps/flash -u {serial_path} {flash_image}' ) if success and not r.startswith('ERROR'): print(f'Flashed: {r}') break else: print(f'Attempt {i} - Failed flash {r}') r, success = output_shell( f'{cfg.paths.root}/apps/flash -u {serial_path} {flash_image}' ) time.sleep(1) if not success: print('Flashing failed. Exhausted max attempts.') except Exception: print('Flashing failed. Unexpected error') finally: self.hid_off()
def getTime(self): try: success, _ = self.hid_on() if success: buffer = [0x00, 0x01] getTimeCommand = "./apps/usbhidtool 0x10C4 0x0002 {0}".format( ''.join('0x{:02x} '.format(a) for a in buffer)) result, success = output_shell(getTimeCommand) logger.info("getTime {0}:{1}".format(getTimeCommand, result)) if success and result != 'NULL': print(result) hexValues = result.split(' ') if hexValues[0] == 'NULL\n': return False, None for hexValue in hexValues: buffer.append(int(hexValue, 16)) mothDate = self.bufferToDate(buffer, 3) print("{0}".format(mothDate)) except: print('Set time failed. Unexpected error') logger.warn("getTime failed due to unexpected error") finally: self.hid_off() return success, mothDate
def is_mounted(self, device_path): find_mount_command = f"mount | grep -F '{device_path}' | cut -d \" \" -f 3" mount_path, success = output_shell(find_mount_command) mount_path = mount_path[:-1] if (success and len(mount_path) > 3) else None return success, mount_path
def do_moth_flash(self): flash_image = f'{cfg.paths.root}/apps/AudioMoth-Project.bin' result, success = output_shell(f'{cfg.paths.root}/apps/flash -u {self.serial_path} {flash_image}') if result is not None: cfg.addOrUpdate('flash','crc', self.do_get_moth_firmware_crc()) return result.strip() if success and not result.startswith('ERROR') else None
def sync_files(self, from_path:str, to_path:str): logging.info("Transferring AudioMoth to Local") syncFilesCommand = "rsync -r {0}/ {1}".format(from_path, to_path) _, success = output_shell(syncFilesCommand) if success: logging.info("Transfer complete") return success
def remove_folder(self, path:str): logging.info("Remove Folder '{0}'".format(path)) createFolderCommand = "rm -rf {0}".format(path) _, success = output_shell(createFolderCommand) if success: logging.info("Remove Folder successful") else: logging.info("Remove Folder unsuccessful")
def sync_file(self, from_path:str, to_path:str): logging.info(f"File Transfer {from_path} to {to_path}") syncFilesCommand = f"rsync {from_path} {to_path}" e, success = output_shell(syncFilesCommand) if not success: logging.info(f"File Transfer failed: {e}") return success
def format_partition_fat32(self, moth_mount_path:str): target_device= os.popen("lsblk -l -f | grep vfat | grep sd | grep Moth | awk \'{print $1}\'").read() if moth_mount_path == f'/dev/{target_device}' and moth_mount_path.starts_with('/dev/sd'): _, success = output_shell(f'sudo mkfs.vfat -F 32 {moth_mount_path}') return success return False
def getMothMountPath(self): command = getMothMountPathCommand.format(self.device_path) mount_path, success = output_shell(command) self.mount_path = mount_path[:-1] if ( success and len(mount_path) > 3) else None logger.debug("getMothMountPath:{0}".format(self.mount_path)) return self.mount_path
def is_moth_unmounted(self): if self.mount_path is not None: r, _ = output_shell(f"lsblk | grep '{self.device_name}' | grep -c '{self.mount_path}'") if r is None or int(r) == 0: self.mount_path = None return True return False
def mount_device(self, device_path: str, mount_path: str): print(f'Mounting {device_path} at {mount_path}') #r, success = output_shell(f'sudo mount -o rw,remount {device_path} {mount_path}') r, success = output_shell(f'sudo mount {device_path} {mount_path}') if not success: print(f'Mount failed: {r}', flush=True) return success
def remove_files(self, path:str, pattern:str = "*.WAV", sudo:bool = False): logging.info(f"Removing files from '{path}/{pattern}'") actor = 'sudo ' if sudo else '' removeMothFilesCommand = f"{actor}rm -f {path}/{pattern}" _, success = output_shell(removeMothFilesCommand) if success: logging.info("Removal complete") return success
def is_moth_detected(self): find_moth_device_command = "ls -l /dev/ | grep 'moth' | grep -E 'sd[a-z]+[0-9]' | awk 'NF>1{print $NF}'" moth_device_name, success = output_shell(find_moth_device_command) self.device_name = moth_device_name[:-1] \ if (success and len(moth_device_name) > 3) else None self.device_path = f"/dev/{self.device_name}" \ if self.device_name is not None else None return self.device_name is not None
def getMothDeviceName(self): moth_device_name, success = output_shell(getMothDeviceNameCommand) self.device_name = moth_device_name[:-1] if ( success and len(moth_device_name) > 3) else None self.device_path = path_to_watch + '/' + moth_device_name[:-1] if ( success and len(moth_device_name) > 3) else None logger.debug("getMothDeviceName:{0}".format(self.device_name)) return self.device_name
def wifi_details(self): output, error = output_shell("sudo iwconfig") if output is None: output = "" results = [] for line in output.splitlines(): results.append(line.strip()) return " ".join(results)
def do_set_moth_time(self): now = datetime.now(timezone.utc) buffer = [0x00, 0x02, 0x00, 0x00, 0x00, 0x00] self.dateToBuffer(buffer, 2, now) setTimeCommand = "./apps/usbhidtool 0x10C4 0x0002 {0}".format(''.join('0x{:02x} '.format(a) for a in buffer)) result, success = output_shell(setTimeCommand) cfg.getOrAddFloat('time', 'set', float(now.timestamp())) if (success): print(result)
def wifi_networks(self): output, error = output_shell("sudo iwlist scan | grep ESSID") if output is None: output = "" results = [] for line in output.splitlines(): ssid = line.strip().strip('ESSID:').strip("\"") results.append(f"\'{ssid}\'") return "[" + ", ".join(results) + "]"
def list_files(self, path:str, pattern: str = "*.WAV"): listMothFilesCommand = "ls -1Ap {0}/{1}".format(path, pattern) logging.info("Fetching files list in '{0}/{1}'".format(path, pattern)) files, success = output_shell(listMothFilesCommand) fileList = [] if files is None else files.splitlines() if success and len(fileList) > 0: logging.info("Recordings count {0}".format(len(fileList))) logging.info(", ".join(fileList)) else: logging.warning("No recordings found") return False return success, fileList
def setTime(self): try: success, _ = self.hid_on() if success: buffer = [0x00, 0x02, 0x00, 0x00, 0x00, 0x00] self.dateToBuffer(buffer, 2, datetime.now(timezone.utc)) setTimeCommand = "./apps/usbhidtool 0x10C4 0x0002 {0}".format( ''.join('0x{:02x} '.format(a) for a in buffer)) print(setTimeCommand) result, success = output_shell(setTimeCommand) if (success): print(result) logger.info("setTime {0}:{1}".format(setTimeCommand, result)) print('Set time success.') else: print('Set time failed. USB HID not enabled.') except: print('Set time failed. Unexpected error') finally: self.hid_off() return success
def do_get_moth_time(self): buffer = [0x00, 0x01] getTimeCommand = "./apps/usbhidtool 0x10C4 0x0002 {0}".format(''.join('0x{:02x} '.format(a) for a in buffer)) result, success = output_shell(getTimeCommand) #logger.info("getTime {0}:{1}".format(getTimeCommand, result)) if success and result != 'NULL': print(result) hexValues = result.split(' ') if hexValues[0] == 'NULL\n': return False, None for hexValue in hexValues: buffer.append(int(hexValue, 16)) mothDate = self.bufferToDate(buffer, 3) print("{0}".format(mothDate)) cfg.getOrAddFloat('time', 'get', float(mothDate.timestamp())) return True, mothDate
def is_serial_online(self): find_moth_serial_command = "ls /dev | grep -E 'ttyACM[0-9]'" result, success = output_shell(find_moth_serial_command) self.serial_device = result.strip() if result is not None else None return success
def is_usbhid_online(self): find_moth_hid_command = 'lsusb | grep -q 10c4' _, success = output_shell(find_moth_hid_command) return success
def _remove_testpath(self): _, success = output_shell(f'rm -rf {cfg.paths.root}/tmp/') self.assertTrue(success)
def unmountMoth(self): mTimeout = 60 mPoll = 2 dTimeout = 10 dPoll = 1 if not self.is_detected(): logger.warning("unmountMoth: not connected") return print('\nUnmounting AudioMoth') # Get the folder content #before = dict ([(f, None) for f in os.listdir (path_to_watch)]) if self.is_mounted(): print("Moth currently mounted") # Umount the filesystem mount point (Lazily) command = f'sudo umount -l {self.device_path}' print(command) r, e = output_shell(command) print(f'Unmount {r} {e}') time.sleep(10) # Report failure while self.is_mounted() and mTimeout > 0: # Lift the SWDIO pin, to cause the AudioMoth to remove the USB MSD protocol support self.usbModeOff() time.sleep(mPoll) mTimeout -= mPoll if self.is_mounted(): print("Moth failed to unmount") logger.error("unmountMoth: failed to unmount") raise Exception("Failed to unmount moth") # Turn off the AudioMoth usb support while self.is_detected() and dTimeout > 0: self.usbModeOff() time.sleep(dPoll) dTimeout -= dPoll if self.is_detected(): print( "Moth failed to disable USB MSD within expected timeout (30s). Resetting" ) self.usbModeOff() time.sleep(10) if self.is_detected(): print("Moth failed to remove device") logger.warning("unmountMoth: failed to remove device") raise Exception("Failed to remove device") print("Moth successfully unmounted") logger.debug("unmountMoth: Complete") self.device_name = None self.device_path = None self.mount_path = None
def do_get_moth_serialnumber(self): if self.serial_path is None: return None result, success = output_shell(f'{cfg.paths.root}/apps/flash -i {self.serial_path}') return result.strip() if success and result is not None else None
def do_get_moth_firmware_crc(self): result, success = output_shell(f'{cfg.paths.root}/apps/flash -c {self.serial_path}') return result.strip() if success and result is not None else None
def _create_testfile(self): _, success = output_shell(f'touch {cfg.paths.root}/tmp/testfile') self.assertTrue(success)
def do_get_moth_serial_path(self): result, success = output_shell(f'{cfg.paths.root}/apps/flash ') self.serial_path = result.strip() if success and not result.startswith('No serial ports found') else None