How to flush the data stored in buffer in pysimplegui

Amritpal Singh 60 Reputation points
2023-11-05T02:50:15.6433333+00:00

How to flush the data in pysimplegui. As I want the response to be displayed immeadiatly as it is received instead of storing it in some kind of buffer and then displaying it. flush = true is not working over here as i am using Multiline element of pysimplegui to display the response , so it is not allowing me to use flush- true in this portion of code:

for ip in ip_list:    response = await ping(ip)    window.refresh()    await asyncio.sleep(2)    window['multi_pi_log'].print(f'res -> {response}', flush=True)


Here is my code:

import reimport PySimpleGUI as sgimport paramikoimport asyncioip_addresses = ['192.168.11.1', '192.168.12.1', '192.168.13.1', '192.162.14.1', '192.168.15.1', '192.168.16.1',                '192.168.101.1', '192.168.101.2', '192.168.101.3', '192.168.101.4', '192.168.101.5', '192.168.101.6',                '192.168.10.35', '192.168.10.36']async def ping(host):    """        Function to ping the host and get the result back.        param host: It is the ip address of the PI.    """    try:        result = await asyncio.create_subprocess_shell(            f'ping {host} -n 5',            stdout=asyncio.subprocess.PIPE,            stderr=asyncio.subprocess.PIPE        )        stdout, stderr = await result.communicate()        return stdout.decode()    except Exception:        return "Error while pinging."def get_average_latency(ping_output):    """        Function to extract average latency from ping output.        param ping_output: It is output after pinging the IP address.    """    match = re.search(r"Average = (\d+)ms", ping_output)    if match:        avg_latency = match.group(1)        return avg_latency    return Nonedef reboot_raspberry_pi(ip_address, username, password):    """        It is the function used to reboot raspberry PI.        param ip_address: The IP address of the raspberry pi.        param username: The username of the pi for the ssh connection.        param password: The password of the pi.    """    try:        ssh = paramiko.SSHClient()  # SSH connection to the Raspberry Pi        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())        ssh.connect(ip_address, username=username, password=password)        # Issue the reboot command for rebooting pi(s)        ssh.exec_command('sudo reboot')        ssh.close()        return True    except Exception:        return Falseasync def reboot_raspberry_pi_async(ip, username, password):    """        This function is created to make the reboot_raspberry_pi function async, as we are using this function        below in multi_pi_reboot function with async, await syntax, so we cannot use synchronous function with it.        param ip: The IP address of the raspberry pi.        param username: The username of the pi for the ssh connection.        param password: The password of the pi.    """    result = await asyncio.to_thread(reboot_raspberry_pi, ip, username, password)    return resultasync def check_multiple_pi_status(ip_list, window):    """        This function is created to check the status of multiple PI(s).        param ip_list: It is the list of IP address stored, which we are passing to this function to check                      the status of those ip(s).        param window: It is the screen of the GUI.    """    for ip in ip_list:        response = await ping(ip)        window.refresh()        await asyncio.sleep(2)        window['multi_pi_log'].print(f'res -> {response}', flush=True)        avg = get_average_latency(response)        if avg is not None:            window['multi_pi_log'].print(f'Raspberry Pi at {ip} is online.', text_color='green')        else:            window['multi_pi_log'].print(f'Raspberry Pi at {ip} is offline.', text_color='red')async def multiple_pi_reboot(ip_list, window):    """        This function is created to reboot multiple PI(s) together.        param ip_list: It is the list of IP address stored, which we are passing to this function to reboot                      those ip(s).        param window: It is the screen of the GUI.    """    reboot_success_count = 0    reboot_fail_count = 0    rebooted_ips = []    reboot_tasks = []    reboot_fail_ips = []    selected_ips_message = "\n".join([f'IP-{ip}' for ip in ip_list])    # Ask for confirmation with the list of IP addresses    confirm_reboot = sg.popup_yes_no(        f'Are you sure you want to reboot the following Raspberry Pi(s)?\n\n{selected_ips_message}',        title='Confirm Reboot')    for ip in ip_list:        response = await ping(ip)        avg = get_average_latency(response)        if avg is not None:            if confirm_reboot == 'Yes':                window['multi_pi_log'].print(f'Initiating reboot...\n', text_color='white')                window.refresh()                await asyncio.sleep(2)                reboot_tasks.append(asyncio.create_task(reboot_raspberry_pi_async(ip, 'lucidauto', 'Lucid@390')))                rebooted_ips.append(ip)    # Awaiting all reboot tasks outside the for loop    await asyncio.gather(*reboot_tasks)    if reboot_tasks:        window['multi_pi_log'].print(f'Reboot command sent to Raspberry Pi at \n{", ".join(rebooted_ips)}.\n')        window.refresh()        await asyncio.sleep(2)        window['multi_pi_log'].print('Rebooting...', text_color='white')        window.refresh()        await asyncio.sleep(2)        reboot_success_count += len(rebooted_ips)    for ip in ip_list:        response = await ping(ip)        avg = get_average_latency(response)        if avg is not None:            if ip in rebooted_ips:                window['multi_pi_log'].print(f'Raspberry Pi at {ip} has been successfully rebooted.\n')            else:                window['multi_pi_log'].print(f'Raspberry Pi at {ip} was not rebooted.\n', text_color='red')                reboot_fail_count += 1                reboot_fail_ips.append(ip)  # adding ip of the pi to the list which was failed to be rebooted.        else:            window['multi_pi_log'].print(f'Raspberry Pi at {ip} is offline. Cannot reboot.\n', text_color='red')            reboot_fail_count += 1            reboot_fail_ips.append(ip)    if reboot_success_count > 0:        rebooted_ip_message = ', '.join(rebooted_ips)        window['multi_pi_log'].print(            f'Successfully rebooted {reboot_success_count} Raspberry Pi(s) with IP Addresses: \n'            f'{rebooted_ip_message}.\n', text_color='green')    if reboot_fail_count > 0:        window['multi_pi_log'].print(f'Failed to reboot {reboot_fail_count} Raspberry Pi(s) with Ip:.\n '                                     f'{", ".join(reboot_fail_ips)}', text_color='red')# -----------------The layout of the GUI------------------sg.theme("DarkBlue")layout_left = [    [sg.Text('Raspberry PI Control Panel', font=('Bold', 24))],    [sg.Text('Select IP Addresses', font=('Bold', 14))],]# Creating a checkbox for each IP address and adding it to the layoutfor ip in ip_addresses:    layout_left.append([sg.Checkbox(ip, default=False, key=f'ip_{ip}', size=(16, 1),                                    font=('Arial', 12), background_color='black', text_color='white')])# Creating two buttons for Checking status of pi(s) and rebooting themlayout_left.append(    [sg.Button('Check Status', font=('Arial', 12), size=(12, 1), key='multi_status',               button_color=('White', 'Green'), pad=(5, 5)),     sg.Button('Reboot PI(s)', font=('Arial', 12), size=(12, 1), key='multi_reboot',               button_color=('White', 'Green'), pad=(5, 5))])layout_right = [    [sg.Text('Other Processes', font=('Bold', 22), pad=(0, 10))],    [sg.Text('System Uptime:', size=(12, 1), font=('Bold', 14)), sg.Text("", size=(12, 1), font=('Bold', 14),                                                                         key='Uptime')],    [sg.Text('Memory Usage:', size=(12, 1), font=('Bold', 14)), sg.Text("", size=(12, 1), font=('Bold', 14),                                                                        key='Usage')],    [sg.Text('Storage Space:', size=(12, 1), font=('Bold', 14)), sg.Text("", size=(12, 1), font=('Bold', 14),                                                                         key='Storage')],    [sg.Text('CPU Temperature:', size=(14, 1), font=('Bold', 14)), sg.Text("", size=(12, 1), key='CPU')],    [sg.Text("")],    [sg.Multiline(size=(70, 20), background_color='Black', font=('Bold', 11), key='multi_pi_log', autoscroll=True)]]layout = [    [        sg.Column(layout_left, size=(420, 600), pad=(0, 0)),        sg.VerticalSeparator(),        sg.Column(layout_right, size=(1000, 580), pad=(0, 0))    ]]window = sg.Window('Raspberry Pi Control', layout, finalize=True, size=(1000, 600), resizable=True)async def main():    while True:        event, values = window.read()        if event == sg.WIN_CLOSED:            break        if event == 'multi_status':  # if clicked on check status button then this event will get executed.            window['multi_pi_log'].print('')  # Clearing the console every time this event is called            window['multi_pi_log'].print('Checking...\n', text_color='white')            window.refresh()            selected_ips = [ip for ip in ip_addresses if values[f'ip_{ip}']]            await check_multiple_pi_status(selected_ips, window)        if event == 'multi_reboot':  # if clicked on reboot pi(s) button then this event is called.            window['multi_pi_log'].print('')            window['multi_pi_log'].print('Please wait...\n')            selected_ips_for_reboot = [ip for ip in ip_addresses if values[f'ip_{ip}']]            await multiple_pi_reboot(selected_ips_for_reboot, window)if __name__ == '__main__':    asyncio.run(main())    window.close()


In this code I have created the functionality of checking the status of multiple pi(s) and rebooting them.

Developer technologies Visual Studio Other
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Anna Xiu-MSFT 31,056 Reputation points Microsoft External Staff
    2023-11-06T03:42:58.9233333+00:00

    Hi @Amritpal Singh

    Welcome to Microsoft Q&A! 

    Your issue is related to Python and PySimpleGUI, please report it in Developer Community

    Thanks for your understanding! 

    Sincerely,

    Anna


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.