Python Forum
[Tkinter] Anyone know what happened to my button?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Anyone know what happened to my button?
#11
Basically this graphic interface is thought and designed to be able to show voltages of the sensors that are in the field and with this detect which sensor is showing a voltage value lower than the average of all the voltages that will reach my computer.

At the moment this interface will show the Date, the Time and the voltages of the first, second and third sensor, in addition to that it will show the average of these voltages and finally the lowest voltage.

I want that in the future when I go to add one or more sensors to the network, I can modify the interface so that it shows more voltage values.

The words in this interface are in Spanish. So I'm going to translate them for you.

Sistema de monitoreo de Paneles del Seslab = Seslab Panel monitoring system
Fecha de medicion = Measurement date
Hora de medicion = measurement time
Voltaje de Panel 1 = Panel Voltage 1
Voltaje de Panel 2 = Panel Voltage 2
Voltaje de Panel 3 = Panel Voltage 3
Pomedio = Average
Panel con menor voltaje = Lower voltage panel
Reply
#12
When I get a moment I will take another look at it and take the above into account.
IgnacioMora23 likes this post
Reply
#13
(May-29-2021, 09:23 PM)Yoriz Wrote: When I get a moment I will take another look at it and take the above into account.

Yeah, sure, no problem. Thank you very much Yoriz
Reply
#14
I have made it so that there is a variable to set the number of voltage panels NUMBER_OF_VOLTAGE_PANELS it uses this to automatically alter the GUI to have the right amount of widgets to display the data, it defaults to having at least 1 so the code won't break.

In the App update method you will need to alter the following lines to set the actual data from the xbee.
self.data.set_date('30/05/2021')
self.data.set_time('12:00')
self.data.set_voltages((0.12, 3.8, 1.3))
self.data.set_voltages takes a tuple of length to match the NUMBER_OF_VOLTAGE_PANELS
import dataclasses
import functools
import statistics
import tkinter as tk
from concurrent import futures

from digi.xbee.devices import XBeeDevice

PORT = "COM5"
BAUD_RATE = 9600
device = XBeeDevice(PORT, BAUD_RATE)

NUMBER_OF_VOLTAGE_PANELS = 3
DATE = 'Fecha de medición'
TIME = 'Hora de medición'
VOLTAGE = 'Voltage de Panel'
AVERAGE = 'Promedio'
LOWEST = 'Panel con Menor Voltaje'


@dataclasses.dataclass
class FloatData:
    label: str
    value: float


@dataclasses.dataclass
class StringData:
    label: str
    value: str


@dataclasses.dataclass
class Data:
    date: StringData = dataclasses.field(
        default=StringData(DATE, ''), init=False)
    time: StringData = dataclasses.field(
        default=StringData(TIME, ''), init=False)
    voltages: list[FloatData] = dataclasses.field(
        default_factory=list, init=False)
    average: FloatData = dataclasses.field(
        default=FloatData(AVERAGE, 0), init=False)
    lowest: FloatData = dataclasses.field(
        default=FloatData(LOWEST, 0), init=False)

    def __post_init__(self):
        end_range = max(2, NUMBER_OF_VOLTAGE_PANELS+1)
        for number in range(1, end_range):
            self.voltages.append(FloatData(f'{VOLTAGE} {number}', 0))

    def set_date(self, date: str):
        self.date.value = date

    def set_time(self, time: str):
        self.time.value = time

    def set_voltages(self, voltages: tuple[float]):
        for float_data, voltage in zip(self.voltages, voltages):
            float_data.value = voltage
        self.calculations()

    def calculations(self):
        volatages = [float_data.value for float_data in self.voltages]
        self.average.value = round(statistics.mean(volatages), 2)
        self.lowest.value = min(volatages)


thread_pool_executor = futures.ThreadPoolExecutor(max_workers=1)


def tk_after(target):

    @functools.wraps(target)
    def wrapper(self, *args, **kwargs):
        args = (self,) + args
        self.after(0, target, *args, **kwargs)

    return wrapper


def submit_to_pool_executor(executor):
    '''Decorates a method to be sumbited to the passed in executor'''
    def decorator(target):

        @functools.wraps(target)
        def wrapper(*args, **kwargs):
            result = executor.submit(target, *args, **kwargs)
            result.add_done_callback(executor_done_call_back)
            return result

        return wrapper

    return decorator


def executor_done_call_back(future):
    exception = future.exception()
    if exception:
        raise exception


class App(tk.Tk):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.title("Sistema de Monitoreo de Paneles Solares del SESLab")
        self.config(bg="#919F89")
        self.data = Data()

        width_of_window = 600
        height_of_window = 280
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        x_coordinate = (screen_width/2)-(width_of_window/2)
        y_coordinate = (screen_height/2)-(height_of_window/2)
        self.geometry((f'{width_of_window}x{height_of_window}+'
                       f'{x_coordinate:.0f}+{y_coordinate:.0f}'))

        self.form_frame = FormFrame(self.data, self)
        self.form_frame.pack()
        self.btn = tk.Button(
            self, bg="#E2BBAC", text="Iniciar ", command=self.on_btn)
        self.btn.pack()

    @tk_after
    def btn_enable(self, enable: bool = True):
        self.btn.config(state='normal' if enable else 'disabled')

    def on_btn(self):
        self.btn_enable(False)
        self.update()

    @submit_to_pool_executor(thread_pool_executor)
    def update(self):
        device.open()
        DATA_TO_SEND = "Hola XBee!"
        device.send_data_broadcast(DATA_TO_SEND)

        try:
            device.flush_queues()
            while True:
                xbee_message = device.read_data()
                if xbee_message is not None:
                    data = xbee_message.data.decode()
                    self.data.set_date('30/05/2021')
                    self.data.set_time('12:00')
                    self.data.set_voltages((0.12, 3.8, 1.3))
                    self.form_frame.update()

        finally:
            if device is not None and device.is_open():
                device.close()
            self.btn_enable()


class FormFrame(tk.Frame):
    def __init__(self, data: Data, *args, **kwargs):
        self.data = data
        kwargs['width'] = '1200'
        kwargs['height'] = '600'
        super().__init__(*args, **kwargs)
        self.config(bg="#98A7AC")
        self.str_variables = {}

        label1 = tk.Label(
            self, text="Sistema de monitoreo de Paneles del SESLab", font=18)
        label1.grid(row=0, column=0, padx=5, pady=5, columnspan=2)

        self.data_objs = [self.data.date, self.data.time]
        self.data_objs += [obj for obj in self.data.voltages]
        self.data_objs += [self.data.average, self.data.lowest]

        for row_index, data_obj in enumerate(self.data_objs, 1):
            label = tk.Label(self, text=f'{data_obj.label} : ')
            label.grid(row=row_index, column=0, padx=2, pady=5)

            str_variable = tk.StringVar()
            entry = tk.Entry(self, textvariable=str_variable)
            entry.grid(row=row_index, column=1, padx=1, pady=5)
            entry.config(fg="black", justify="center", state='readonly')
            self.str_variables[data_obj.label] = str_variable

    @tk_after
    def update(self):
        for data_obj in self.data_objs:
            self.str_variables[data_obj.label].set(data_obj.value)


if __name__ == '__main__':
    app = App()
    app.mainloop()
IgnacioMora23 likes this post
Reply
#15
(May-30-2021, 11:37 AM)Yoriz Wrote: I have made it so that there is a variable to set the number of voltage panels NUMBER_OF_VOLTAGE_PANELS it uses this to automatically alter the GUI to have the right amount of widgets to display the data, it defaults to having at least 1 so the code won't break.

In the App update method you will need to alter the following lines to set the actual data from the xbee.
self.data.set_date('30/05/2021')
self.data.set_time('12:00')
self.data.set_voltages((0.12, 3.8, 1.3))
self.data.set_voltages takes a tuple of length to match the NUMBER_OF_VOLTAGE_PANELS
import dataclasses
import functools
import statistics
import tkinter as tk
from concurrent import futures

from digi.xbee.devices import XBeeDevice

PORT = "COM5"
BAUD_RATE = 9600
device = XBeeDevice(PORT, BAUD_RATE)

NUMBER_OF_VOLTAGE_PANELS = 3
DATE = 'Fecha de medición'
TIME = 'Hora de medición'
VOLTAGE = 'Voltage de Panel'
AVERAGE = 'Promedio'
LOWEST = 'Panel con Menor Voltaje'


@dataclasses.dataclass
class FloatData:
    label: str
    value: float


@dataclasses.dataclass
class StringData:
    label: str
    value: str


@dataclasses.dataclass
class Data:
    date: StringData = dataclasses.field(
        default=StringData(DATE, ''), init=False)
    time: StringData = dataclasses.field(
        default=StringData(TIME, ''), init=False)
    voltages: list[FloatData] = dataclasses.field(
        default_factory=list, init=False)
    average: FloatData = dataclasses.field(
        default=FloatData(AVERAGE, 0), init=False)
    lowest: FloatData = dataclasses.field(
        default=FloatData(LOWEST, 0), init=False)

    def __post_init__(self):
        end_range = max(2, NUMBER_OF_VOLTAGE_PANELS+1)
        for number in range(1, end_range):
            self.voltages.append(FloatData(f'{VOLTAGE} {number}', 0))

    def set_date(self, date: str):
        self.date.value = date

    def set_time(self, time: str):
        self.time.value = time

    def set_voltages(self, voltages: tuple[float]):
        for float_data, voltage in zip(self.voltages, voltages):
            float_data.value = voltage
        self.calculations()

    def calculations(self):
        volatages = [float_data.value for float_data in self.voltages]
        self.average.value = round(statistics.mean(volatages), 2)
        self.lowest.value = min(volatages)


thread_pool_executor = futures.ThreadPoolExecutor(max_workers=1)


def tk_after(target):

    @functools.wraps(target)
    def wrapper(self, *args, **kwargs):
        args = (self,) + args
        self.after(0, target, *args, **kwargs)

    return wrapper


def submit_to_pool_executor(executor):
    '''Decorates a method to be sumbited to the passed in executor'''
    def decorator(target):

        @functools.wraps(target)
        def wrapper(*args, **kwargs):
            result = executor.submit(target, *args, **kwargs)
            result.add_done_callback(executor_done_call_back)
            return result

        return wrapper

    return decorator


def executor_done_call_back(future):
    exception = future.exception()
    if exception:
        raise exception


class App(tk.Tk):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.title("Sistema de Monitoreo de Paneles Solares del SESLab")
        self.config(bg="#919F89")
        self.data = Data()

        width_of_window = 600
        height_of_window = 280
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        x_coordinate = (screen_width/2)-(width_of_window/2)
        y_coordinate = (screen_height/2)-(height_of_window/2)
        self.geometry((f'{width_of_window}x{height_of_window}+'
                       f'{x_coordinate:.0f}+{y_coordinate:.0f}'))

        self.form_frame = FormFrame(self.data, self)
        self.form_frame.pack()
        self.btn = tk.Button(
            self, bg="#E2BBAC", text="Iniciar ", command=self.on_btn)
        self.btn.pack()

    @tk_after
    def btn_enable(self, enable: bool = True):
        self.btn.config(state='normal' if enable else 'disabled')

    def on_btn(self):
        self.btn_enable(False)
        self.update()

    @submit_to_pool_executor(thread_pool_executor)
    def update(self):
        device.open()
        DATA_TO_SEND = "Hola XBee!"
        device.send_data_broadcast(DATA_TO_SEND)

        try:
            device.flush_queues()
            while True:
                xbee_message = device.read_data()
                if xbee_message is not None:
                    data = xbee_message.data.decode()
                    self.data.set_date('30/05/2021')
                    self.data.set_time('12:00')
                    self.data.set_voltages((0.12, 3.8, 1.3))
                    self.form_frame.update()

        finally:
            if device is not None and device.is_open():
                device.close()
            self.btn_enable()


class FormFrame(tk.Frame):
    def __init__(self, data: Data, *args, **kwargs):
        self.data = data
        kwargs['width'] = '1200'
        kwargs['height'] = '600'
        super().__init__(*args, **kwargs)
        self.config(bg="#98A7AC")
        self.str_variables = {}

        label1 = tk.Label(
            self, text="Sistema de monitoreo de Paneles del SESLab", font=18)
        label1.grid(row=0, column=0, padx=5, pady=5, columnspan=2)

        self.data_objs = [self.data.date, self.data.time]
        self.data_objs += [obj for obj in self.data.voltages]
        self.data_objs += [self.data.average, self.data.lowest]

        for row_index, data_obj in enumerate(self.data_objs, 1):
            label = tk.Label(self, text=f'{data_obj.label} : ')
            label.grid(row=row_index, column=0, padx=2, pady=5)

            str_variable = tk.StringVar()
            entry = tk.Entry(self, textvariable=str_variable)
            entry.grid(row=row_index, column=1, padx=1, pady=5)
            entry.config(fg="black", justify="center", state='readonly')
            self.str_variables[data_obj.label] = str_variable

    @tk_after
    def update(self):
        for data_obj in self.data_objs:
            self.str_variables[data_obj.label].set(data_obj.value)


if __name__ == '__main__':
    app = App()
    app.mainloop()

Morning Yoriz

Thanks for that. I had a problem adding the Panel voltage. I think I know that the problem happens because when the frame is sent, the voltage is sent as a string, and then when it arrives here at the PC, I need to convert that voltage to an integer to be able to handle them in the operation to sacrifice the average.

I don't know why it stopped working when I told him that
data.split (",") [0] be an integer by appending int forward
int (data.split (",") [0]) .

The other thing I wanted to tell you is how the program realizes that the frame that enters the PC is from the Panel that I assign as Panel 1 or 2 or 3. Now it is very easy because I can only test one antenna at a time but when put this system to work, I am going to receive 3 frames of data from 3 different sensors.

So I'm going to tell you that Xbee made a library for Xbee, well as you have seen there are several functions here that have served to send, receive and subtract the data from the Xbee.

There is a function called xbee_message.remote_device.get_64bit_addr ()

This function will give me the direction of the sensor in this way I will know according to how I place the sensors in the field, to which sensor each direction belongs.

Next this is the result of printing in the console the code that gives me the address of the sensor, the data frame and the separated data.

30.00,09:18:36,30/05/2021 This is the data frame that all Xbee will send to the PC.

Xbee address 0013A20040D7B01E >> 30.00,09:18:36,30/05/2021
voltage 30.00
hour 09:18:36
date 30/05/2021

Regarding the direction of the devices as I have told you, at the time of the test I will do it with 3 Xbee. Each Xbee on the back has its address.
For example sensor 1 would be
0013A20040D7B01E
sensor 2 would be
0013A200414EF124
sensor 3 would be
0013A20040D7AEA4

What I thought is that if in the future I add more devices to the network. what you should do is modify the code and add more sensor addresses before placing them.

In the graphical interface, it does not matter if only sensor 1 takes the time and date, but from all the others it takes the voltage from them, which would be taken from data data.split (",") [0]

Attached Files

Thumbnail(s)
   
Reply
#16
'29.97' will not convert to an int, use float instead float('29.97')
Reply
#17
(May-30-2021, 03:48 PM)Yoriz Wrote: '29.97' will not convert to an int, use float instead float('29.97')

hahaha Omg my bad.
Reply
#18
(May-30-2021, 03:34 PM)IgnacioMora23 Wrote:
(May-30-2021, 11:37 AM)Yoriz Wrote: I have made it so that there is a variable to set the number of voltage panels NUMBER_OF_VOLTAGE_PANELS it uses this to automatically alter the GUI to have the right amount of widgets to display the data, it defaults to having at least 1 so the code won't break.

In the App update method you will need to alter the following lines to set the actual data from the xbee.
self.data.set_date('30/05/2021')
self.data.set_time('12:00')
self.data.set_voltages((0.12, 3.8, 1.3))
self.data.set_voltages takes a tuple of length to match the NUMBER_OF_VOLTAGE_PANELS
import dataclasses
import functools
import statistics
import tkinter as tk
from concurrent import futures

from digi.xbee.devices import XBeeDevice

PORT = "COM5"
BAUD_RATE = 9600
device = XBeeDevice(PORT, BAUD_RATE)

NUMBER_OF_VOLTAGE_PANELS = 3
DATE = 'Fecha de medición'
TIME = 'Hora de medición'
VOLTAGE = 'Voltage de Panel'
AVERAGE = 'Promedio'
LOWEST = 'Panel con Menor Voltaje'


@dataclasses.dataclass
class FloatData:
    label: str
    value: float


@dataclasses.dataclass
class StringData:
    label: str
    value: str


@dataclasses.dataclass
class Data:
    date: StringData = dataclasses.field(
        default=StringData(DATE, ''), init=False)
    time: StringData = dataclasses.field(
        default=StringData(TIME, ''), init=False)
    voltages: list[FloatData] = dataclasses.field(
        default_factory=list, init=False)
    average: FloatData = dataclasses.field(
        default=FloatData(AVERAGE, 0), init=False)
    lowest: FloatData = dataclasses.field(
        default=FloatData(LOWEST, 0), init=False)

    def __post_init__(self):
        end_range = max(2, NUMBER_OF_VOLTAGE_PANELS+1)
        for number in range(1, end_range):
            self.voltages.append(FloatData(f'{VOLTAGE} {number}', 0))

    def set_date(self, date: str):
        self.date.value = date

    def set_time(self, time: str):
        self.time.value = time

    def set_voltages(self, voltages: tuple[float]):
        for float_data, voltage in zip(self.voltages, voltages):
            float_data.value = voltage
        self.calculations()

    def calculations(self):
        volatages = [float_data.value for float_data in self.voltages]
        self.average.value = round(statistics.mean(volatages), 2)
        self.lowest.value = min(volatages)


thread_pool_executor = futures.ThreadPoolExecutor(max_workers=1)


def tk_after(target):

    @functools.wraps(target)
    def wrapper(self, *args, **kwargs):
        args = (self,) + args
        self.after(0, target, *args, **kwargs)

    return wrapper


def submit_to_pool_executor(executor):
    '''Decorates a method to be sumbited to the passed in executor'''
    def decorator(target):

        @functools.wraps(target)
        def wrapper(*args, **kwargs):
            result = executor.submit(target, *args, **kwargs)
            result.add_done_callback(executor_done_call_back)
            return result

        return wrapper

    return decorator


def executor_done_call_back(future):
    exception = future.exception()
    if exception:
        raise exception


class App(tk.Tk):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.title("Sistema de Monitoreo de Paneles Solares del SESLab")
        self.config(bg="#919F89")
        self.data = Data()

        width_of_window = 600
        height_of_window = 280
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        x_coordinate = (screen_width/2)-(width_of_window/2)
        y_coordinate = (screen_height/2)-(height_of_window/2)
        self.geometry((f'{width_of_window}x{height_of_window}+'
                       f'{x_coordinate:.0f}+{y_coordinate:.0f}'))

        self.form_frame = FormFrame(self.data, self)
        self.form_frame.pack()
        self.btn = tk.Button(
            self, bg="#E2BBAC", text="Iniciar ", command=self.on_btn)
        self.btn.pack()

    @tk_after
    def btn_enable(self, enable: bool = True):
        self.btn.config(state='normal' if enable else 'disabled')

    def on_btn(self):
        self.btn_enable(False)
        self.update()

    @submit_to_pool_executor(thread_pool_executor)
    def update(self):
        device.open()
        DATA_TO_SEND = "Hola XBee!"
        device.send_data_broadcast(DATA_TO_SEND)

        try:
            device.flush_queues()
            while True:
                xbee_message = device.read_data()
                if xbee_message is not None:
                    data = xbee_message.data.decode()
                    self.data.set_date('30/05/2021')
                    self.data.set_time('12:00')
                    self.data.set_voltages((0.12, 3.8, 1.3))
                    self.form_frame.update()

        finally:
            if device is not None and device.is_open():
                device.close()
            self.btn_enable()


class FormFrame(tk.Frame):
    def __init__(self, data: Data, *args, **kwargs):
        self.data = data
        kwargs['width'] = '1200'
        kwargs['height'] = '600'
        super().__init__(*args, **kwargs)
        self.config(bg="#98A7AC")
        self.str_variables = {}

        label1 = tk.Label(
            self, text="Sistema de monitoreo de Paneles del SESLab", font=18)
        label1.grid(row=0, column=0, padx=5, pady=5, columnspan=2)

        self.data_objs = [self.data.date, self.data.time]
        self.data_objs += [obj for obj in self.data.voltages]
        self.data_objs += [self.data.average, self.data.lowest]

        for row_index, data_obj in enumerate(self.data_objs, 1):
            label = tk.Label(self, text=f'{data_obj.label} : ')
            label.grid(row=row_index, column=0, padx=2, pady=5)

            str_variable = tk.StringVar()
            entry = tk.Entry(self, textvariable=str_variable)
            entry.grid(row=row_index, column=1, padx=1, pady=5)
            entry.config(fg="black", justify="center", state='readonly')
            self.str_variables[data_obj.label] = str_variable

    @tk_after
    def update(self):
        for data_obj in self.data_objs:
            self.str_variables[data_obj.label].set(data_obj.value)


if __name__ == '__main__':
    app = App()
    app.mainloop()

Morning Yoriz

Thanks for that. I had a problem adding the Panel voltage. I think I know that the problem happens because when the frame is sent, the voltage is sent as a string, and then when it arrives here at the PC, I need to convert that voltage to an integer to be able to handle them in the operation to sacrifice the average.

I don't know why it stopped working when I told him that
data.split (",") [0] be an integer by appending int forward
int (data.split (",") [0]) .

The other thing I wanted to tell you is how the program realizes that the frame that enters the PC is from the Panel that I assign as Panel 1 or 2 or 3. Now it is very easy because I can only test one antenna at a time but when put this system to work, I am going to receive 3 frames of data from 3 different sensors.

So I'm going to tell you that Xbee made a library for Xbee, well as you have seen there are several functions here that have served to send, receive and subtract the data from the Xbee.

There is a function called xbee_message.remote_device.get_64bit_addr ()

This function will give me the direction of the sensor in this way I will know according to how I place the sensors in the field, to which sensor each direction belongs.

Next this is the result of printing in the console the code that gives me the address of the sensor, the data frame and the separated data.

30.00,09:18:36,30/05/2021 This is the data frame that all Xbee will send to the PC.

Xbee address 0013A20040D7B01E >> 30.00,09:18:36,30/05/2021
voltage 30.00
hour 09:18:36
date 30/05/2021

Regarding the direction of the devices as I have told you, at the time of the test I will do it with 3 Xbee. Each Xbee on the back has its address.
For example sensor 1 would be
0013A20040D7B01E
sensor 2 would be
0013A200414EF124
sensor 3 would be
0013A20040D7AEA4

What I thought is that if in the future I add more devices to the network. what you should do is modify the code and add more sensor addresses before placing them.

In the graphical interface, it does not matter if only sensor 1 takes the time and date, but from all the others it takes the voltage from them, which would be taken from data data.split (",") [0]



To add a new module I am very clear that I only change the variable NUMBER_OF_VOLTAGE_PANELS. I already tried it and it works wonders.

I don't want to make an interface that is very, very designed or very incredible. I only think of something basic that works and that is friendly with the user. Have I been thinking about which is better? If you add the addresses by entering the code and writing it, I don't know, in a tuple or list.
Or if it is easier to have a label through which a new address is entered and depending on how many addresses I enter, the system grows larger. What do I want to say with that. Well at the moment I have 3 sensors, I mean 3 addresses. I am going to locate in sensor 1 the address that I chose for sensor 1 and so on for the other sensors.
But when I enter the following address it is already known that this is going to be the fourth and therefore there is a new "window" in the interface whose name would be, Panel 4 Voltage and its "window where the voltage that measures it is displayed. sensor.
Reply
#19
I'm finding it hard to understand what you are looking for, how many sensors is it likely to go up to.
Did you want to display them in a different way maybe a list with headers
Output:
Xbee address | voltage | hour | date 0013A20040D7B01E | 30.00 | 09:18:36 | 30/05/2021 0013A200414EF124 | 25.00 | 09:18:36 | 30/05/2021 0013A20040D7AEA4 | 22.70 | 09:18:36 | 30/05/2021
And then underneath the average and the lowest

I don't really understand how the data comes in, does all the data for all sensor come in at once or do you obtain them separately?
Reply
#20
(May-30-2021, 11:02 PM)Yoriz Wrote: I'm finding it hard to understand what you are looking for, how many sensors is it likely to go up to.
Did you want to display them in a different way maybe a list with headers
Output:
Xbee address | voltage | hour | date 0013A20040D7B01E | 30.00 | 09:18:36 | 30/05/2021 0013A200414EF124 | 25.00 | 09:18:36 | 30/05/2021 0013A20040D7AEA4 | 22.70 | 09:18:36 | 30/05/2021
And then underneath the average and the lowest

I don't really understand how the data comes in, does all the data for all sensor come in at once or do you obtain them separately?


Good night Yoriz.

It is likely that the system can be extended to 20 sensors.
The same could be used as a recommendation if you need to expand to more, redo a new interface. But we can leave it at 20 just enough to offer the option that it can be expanded to 20 sensors.

No no, the truth is, the interface like this one at the moment seems super good to me, I love it. Show the information I need and the most important to you.

Data are information packages that enter the computer through the serial port, these data enter at the same time.
The Xbees have a communication mode for their Xbees on the same network by means of which they pack information into frames, these frames have the address of the xbee and the data, the data is where the voltage, the time and the date are. And the address of the Xbee is the one that will help me determine which Xbee is the one that I am reading.


When I click the button, the program tells the Xbee to send a message to all the sensors. When all the sensors receive the message, they begin to send the information.
What information? They send the voltage, the time and the date.
At the same time, since that is the idea, to know the voltage of the panels in real time and determine which panel is the one that is generating the lowest voltage. With this I can tell if it is presenting a fault.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PySimpleGui] How to alter mouse click button of a standard submit button? skyerosebud 3 4,952 Jul-21-2019, 06:02 PM
Last Post: FullOfHelp

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020