async def write_encoded(self, data: bytes): if not self.connected: raise exceptions.NotConnected(f'{self} not connected') LOGGER.debug(f'{self} writing: {data}') self._writer.write(data + b'\n') await self._writer.drain()
async def write(self, msg: Union[str, bytes]): if isinstance(msg, str): msg = msg.encode() if not self.connected: raise exceptions.NotConnected(f'{self} not connected') LOGGER.debug(f'{self} writing: {msg}') self._writer.write(msg + b'\n') await self._writer.drain()
async def flash(self) -> dict: # pragma: no cover sender = ymodem.FileSender(self._notify) cmder = commander.fget(self.app) address = service_status.desc(self.app).device_address self._notify( f'Started updating {self.name}@{address} to version {self.version} ({self.date})' ) try: if not service_status.desc(self.app).is_connected: self._notify('Controller is not connected. Aborting update.') raise exceptions.NotConnected() if self.simulation: raise NotImplementedError( 'Firmware updates not available for simulation controllers' ) self._notify('Sending update command to controller') service_status.set_updating(self.app) await asyncio.sleep(FLUSH_PERIOD_S ) # Wait for in-progress commands to finish await cmder.execute(commands.FirmwareUpdateCommand.from_args()) self._notify('Shutting down normal communication') await cmder.shutdown(self.app) self._notify('Waiting for normal connection to close') await asyncio.wait_for(service_status.wait_disconnected(self.app), STATE_TIMEOUT_S) self._notify(f'Connecting to {address}') conn = await self._connect(address) with conn.autoclose(): await asyncio.wait_for(sender.transfer(conn), TRANSFER_TIMEOUT_S) except Exception as ex: self._notify(f'Failed to update firmware: {strex(ex)}') raise exceptions.FirmwareUpdateFailed(strex(ex)) finally: self._notify('Scheduling service reboot') await shutdown_soon(self.app, UPDATE_SHUTDOWN_DELAY_S) self._notify('Firmware updated!') return {'address': address, 'version': self.version}
async def flash(self) -> dict: # pragma: no cover ota = ymodem.OtaClient(self._notify) cmder = commander.fget(self.app) status_desc = service_status.desc(self.app) address = status_desc.device_address platform = status_desc.device_info.platform self._notify( f'Started updating {self.name}@{address} to version {self.version} ({self.date})' ) try: if not status_desc.is_connected: self._notify('Controller is not connected. Aborting update.') raise exceptions.NotConnected() if self.simulation: raise NotImplementedError( 'Firmware updates not available for simulation controllers' ) self._notify('Preparing update') service_status.set_updating(self.app) await asyncio.sleep(FLUSH_PERIOD_S ) # Wait for in-progress commands to finish if platform != 'esp32': # pragma: no cover self._notify('Sending update command to controller') await cmder.execute(commands.FirmwareUpdateCommand.from_args()) self._notify('Waiting for normal connection to close') await cmder.shutdown(self.app) await asyncio.wait_for(service_status.wait_disconnected(self.app), STATE_TIMEOUT_S) if platform == 'esp32': # pragma: no cover # ESP connections will always be a TCP address host, _ = address.split(':') self._notify(f'Sending update prompt to {host}') self._notify( 'The Spark will now download and apply the new firmware') self._notify('The update is done when the service reconnects') fw_url = ESP_URL_FMT.format(**self.app['ini']) await http.session(self.app ).post(f'http://{host}:80/firmware_update', data=fw_url) else: self._notify(f'Connecting to {address}') conn = await ymodem.connect(address) with conn.autoclose(): await asyncio.wait_for( ota.send(conn, f'firmware/brewblox-{platform}.bin'), TRANSFER_TIMEOUT_S) self._notify('Update done!') except Exception as ex: self._notify(f'Failed to update firmware: {strex(ex)}') raise exceptions.FirmwareUpdateFailed(strex(ex)) finally: self._notify('Restarting service...') await shutdown_soon(self.app, UPDATE_SHUTDOWN_DELAY_S) return {'address': address, 'version': self.version}