import subprocess import sys import asyncio import os async def run_remote_command(remote_host, command): ssh_command = ['ssh', f'root@{remote_host}', command] process = await asyncio.create_subprocess_exec( *ssh_command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await process.communicate() stdout_decoded = stdout.decode() stderr_decoded = stderr.decode() if process.returncode == 0: return stdout_decoded + stderr_decoded else: return f"Failed to run the command: {command}, error: {stderr_decoded}" async def check_GX_type(remote_host): command = "cat /etc/venus/machine" return await run_remote_command(remote_host, command) async def run_rclocal(remote_host): command = "chmod +x /data/rc.local && /data/rc.local" return await run_remote_command(remote_host, command) async def stop_battery_service(remote_host): command1 = "cd /opt/victronenergy/serial-starter && ./stop-tty.sh ttyUSB0" command2 = "cd /opt/victronenergy/serial-starter && ./stop-tty.sh ttyUSB1" result1 = await run_remote_command(remote_host, command1) result2 = await run_remote_command(remote_host, command2) return result1, result2 async def start_battery_service(remote_host): command1 = "cd /opt/victronenergy/serial-starter && ./start-tty.sh ttyUSB0" command2 = "cd /opt/victronenergy/serial-starter && ./start-tty.sh ttyUSB1" result1 = await run_remote_command(remote_host, command1) result2 = await run_remote_command(remote_host, command2) return result1, result2 async def stop_controller(remote_host): command = "svc -d /service/controller" result = await run_remote_command(remote_host, command) return result async def start_controller(remote_host): command = "svc -u /service/controller" result = await run_remote_command(remote_host, command) return result async def resize(remote_host): command = "sh /opt/victronenergy/swupdate-scripts/resize2fs.sh" return await run_remote_command(remote_host, command) async def reboot(remote_host): command = "reboot" return await run_remote_command(remote_host, command) async def upload_files(remote_host): file_location_mappings = { "rc.local": "/data/", "dbus-fzsonick-48tl": "/data/", "controller.py": "/data/", "aggregator": "/data/", "PageChargingStrategy.qml": "/data/", "pika-0.13.1": "/data/innovenergy/" } venus_release_files_folder = os.path.join(os.getcwd(), "VenusReleaseFiles") if not os.path.exists(venus_release_files_folder): return "VenusReleaseFiles folder does not exist." try: tasks = [] for file_name, remote_location in file_location_mappings.items(): file_path = os.path.join(venus_release_files_folder, file_name) if not os.path.exists(file_path): raise FileNotFoundError(f"File {file_name} not found in {venus_release_files_folder}.") command = [ "rsync", "-r", file_path, f"root@{remote_host}:{remote_location}" ] tasks.append(command) # Execute rsync commands asynchronously for task in tasks: subprocess.run(task, check=True) return "All files uploaded successfully." except FileNotFoundError as e: return str(e) except subprocess.CalledProcessError as e: return f"Error occurred while uploading files: {e}" except Exception as e: return f"An error occurred while uploading files: {str(e)}" async def import_pika(remote_host): change_dir_command = "cd /data/innovenergy/pika-0.13.1/" install_command = "python2 setup.py install --user" command = f"{change_dir_command} && {install_command}" return await run_remote_command(remote_host, command) async def make_rclocal_executable(remote_host): command = "chmod +x /data/rc.local" return await run_remote_command(remote_host, command) async def check_connection(remote_host): result = await run_remote_command(remote_host, 'echo Connection successful') return "Connection successful" in result async def restart_gui(remote_host): command1 = "svc -d /service/gui" command2 = "svc -u /service/gui" result1 = await run_remote_command(remote_host, command1) result2 = await run_remote_command(remote_host, command2) return result1, result2 async def main(remote_host): ##### 1. check connection ###### print("Check connection!") if not await check_connection(remote_host): sys.exit("Failed to ssh!") ##### 2. check whether it's Venus ###### gx_type = await check_GX_type(remote_host) # if gx_type == "beaglebone\n": ##### 3. upload VPN and battery files ###### print("Upload pika and battery files!") if(await upload_files(remote_host)!="All files uploaded successfully."): sys.exit("Failed to upload files!") else: print(await upload_files(remote_host)) #### 4. import pika #### print("Import pika!") print(await import_pika(remote_host)) #### 5. resize /dev/root ##### print("Resize /dev/root now!") print(await resize(remote_host)) #### 6. stop battery service ###### print("Stop battery service!") print(await stop_battery_service(remote_host)) #### 7. stop controller service ###### print("Stop controller service!") print(await stop_controller(remote_host)) ##### 8. run rc.local ###### print("Run rc.local!") print(await run_rclocal(remote_host)) ##### 9. start battery service ###### print("Start battery service!") print(await start_battery_service(remote_host)) ##### 10. start controller service ###### print("Start controller service!") print(await start_controller(remote_host)) ##### 11. restart gui ###### print("Restart gui!") print(await restart_gui(remote_host)) # else: # sys.exit("It's not Venus GX!") if __name__ == "__main__": remote_host = sys.argv[1] asyncio.run(main(remote_host))