Sign in to follow this  
Followers 0
Marklar

Displaying real-time data

14 posts in this topic

What's the best way of displaying realtime data, such as say an inventory system?

I would like the data to be shown in a Listview. Pulling the data and all is no problem. I can do that and click a refresh button to get the latest data. I can even do realtime because I have it redrawing the listbox inside a while loop. But the flicker is very annoying.

I can display it as a regular text label and get rid of the flicker. I found some code on these forums somewhere that lets you run constantly updated label, such as a timer, with no flicker.

I couldn't get that to work with a listbox. Using a listbox would be convenient because you can select the listed item and do more data manipulation using that selection.

Basically I want two columns in the listview

Column A is the item title

Column B is a number based on data entered earlier plus some math calculations. That number needs to be updated realtime, without really the need of redrawing the entire box. Anyway of doing this?

Share this post


Link to post
Share on other sites



Generally, if all you're doing is constantly polling for information and updating real time, you are going to get the constant flickers, because you are probably re-drawing it every time without an arguement.

In other words:

$a = 0
While 1
    If $a = 0 Then
        MsgBox(64, 'Info', 'The condition is true for this loop, but will not be after this If statement, so you will not get another msgbox.')
        $a = 1
    EndIf
    Sleep(10)
WEnd
The same could go for any control your going to draw, you should only draw it, if the information has changed, that will solve the flickering (unless the information changes every 10 milliseconds or so lol).

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Well, there are several different rows in the listview. Currently 9 and will continue to grow. Each number will change at different times. The numbers are also time sensitive. It figures a rate per hour.

I have this currently running in a PHP script on a web server. It uses AJAX to constantly update the realtime numbers.

I would like this to be run as a windows app. I'm hoping Autoit can do it before I start digging in (or wasting my time) with Visual basic.net

Share this post


Link to post
Share on other sites

Well, there are several different rows in the listview. Currently 9 and will continue to grow. Each number will change at different times. The numbers are also time sensitive. It figures a rate per hour.

I have this currently running in a PHP script on a web server. It uses AJAX to constantly update the realtime numbers.

I would like this to be run as a windows app. I'm hoping Autoit can do it before I start digging in (or wasting my time) with Visual basic.net

Without a recreation script to give as an example on what and how you want to work it, then I'm still having to go with what I said. If the information changes, then and only then re-draw the info.

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

it's time sensitive data so the statement

(unless the information changes every 10 milliseconds or so lol).

is somewhat true. lol

I work for a salt water disposal company. We only had paper,pen, and a calculator not too long ago, before I decided to automate it with PHP. Basically you get a guy to gauge the tanks. This tells you how much water is in there. This information is put into the database. He guages it again, say 3 hours later. This information is entered into the database. It figures the difference. So if there was 100 barrels of water in the tank at 8am and then 160 barrels in there at 11am then it produced 60 barrels over 3 hours, or 20 barrels an hour.

With that information, I know that around 6pm the tank will be full and need to be emptied.

Try that with pen and paper on 50 different tanks.

The way my php program is set up is

Tank Name A - 120 Barrels

Tank Name B - 270 Barrels

and so on

As time progresses those numbers increase. Each tank can hold different amounts. 1 can hold 600 while another can only hold 300. So, what it does, is it sorts the list by closest capacity. If tank a were producing at 30 barrels an hour and can only hold 300 and tank b was producing at 5 barrels an hour and only holds 300, then tank a will be on top, even though tank b has more, since tank a will hit capacity first. I need to show these numbers realtime so I can keep a good watch on it.

I got all that worked out. I just want to do it in AutoIT.. I love Autoit, plus I'm bored :D

Edited by Marklar

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

it's time sensitive data so the statement

is somewhat true. lol

I work for a salt water disposal company. We only had paper,pen, and a calculator not too long ago, before I decided to automate it with PHP. Basically you get a guy to gauge the tanks. This tells you how much water is in there. This information is put into the database. He guages it again, say 3 hours later. This information is entered into the database. It figures the difference. So if there was 100 barrels of water in the tank at 8am and then 160 barrels in there at 11am then it produced 60 barrels over 3 hours, or 20 barrels an hour.

With that information, I know that around 6pm the tank will be full and need to be emptied.

Try that with pen and paper on 50 different tanks.

The way my php program is set up is

Tank Name A - 120 Barrels

Tank Name B - 270 Barrels

and so on

As time progresses those numbers increase. Each tank can hold different amounts. 1 can hold 600 while another can only hold 300. So, what it does, is it sorts the list by closest capacity. If tank a were producing at 30 barrels an hour and can only hold 300 and tank b was producing at 5 barrels an hour and only holds 300, then tank a will be on top, even though tank b has more, since tank a will hit capacity first. I need to show these numbers realtime so I can keep a good watch on it.

:D

I got all that worked out. I just want to do it in AutoIT.. I love Autoit, plus I'm bored :wacko:

Unless I miss-understand, you are entering the results of manual tank soundings? That data will change very slowly and not present a problem, in fact the display only need be updated when a new data point is entered. If you had instrumented tanks with digital float gauges connected by serial lines or WiFi, then the data rate might show some visible flickering (if there are a lot of tanks). You would still only have the individual controls flickering since there is no reason to redraw the entire GUI when changing the data in a single control.

P.S. I would display percentage full, and estimated time remaining to reach 90% for each tank. Have you got any code done on the GUI you want yet?

:D

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I started to make something to do this with a GUI, enter the data, store the data, compare the data, but the PHP thing kept making me wonder if the PHP was "necessary" if you could just do it all from AutoIt? I stopped working on it because of that.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Unless I miss-understand, you are entering the results of manual tank soundings? That data will change very slowly and not present a problem, in fact the display only need be updated when a new data point is entered. If you had instrumented tanks with digital float gauges connected by serial lines or WiFi, then the data rate might show some visible flickering (if there are a lot of tanks). You would still only have the individual controls flickering since there is no reason to redraw the entire GUI when changing the data in a single control.

P.S. I would display percentage full, and estimated time remaining to reach 90% for each tank. Have you got any code done on the GUI you want yet?

:D

Yes they are manual readings. But now they are only guaged when we go to empty them. We only go to empty them when they get near capacity.

It's like this. Say there's 15 tanks listed. Three on top are colored in red and the rest are blue. Red indicates that it's getting near capacity. That's how i have it setup on the php thing.

I send three people out there to empty those tanks. New readings are entered into the database and the counter starts over. The point is to get accurate readings and 'predictions' on when we need to get out there. One overflowed once. It started picking up speed on it's production rate since the last time we were out there. It's new readings were entered, in which it computed its new production rate and added it into the average. Now it hasn't overflowed since.

I can add an "update" button to redraw it manually. But it would be cooler if it did it by itself. Maybe I can just ignore the flickering for now :wacko:

Edited by Marklar

Share this post


Link to post
Share on other sites

Yes they are manual readings. But now they are only guaged when we go to empty them. We only go to empty them when they get near capacity.

It's like this. Say there's 15 tanks listed. Three on top are colored in red and the rest are blue. Red indicates that it's getting near capacity. That's how i have it setup on the php thing.

I send three people out there to empty those tanks. New readings are entered into the database and the counter starts over. The point is to get accurate readings and 'predictions' on when we need to get out there. One overflowed once. It started picking up speed on it's production rate since the last time we were out there. It's new readings were entered, in which it computed its new production rate and added it into the average. Now it hasn't overflowed since.

I can add an "update" button to redraw it manually. But it would be cooler if it did it by itself. Maybe I can just ignore the flickering for now :wacko:

A begining to get you started. Doesn't have all the features you want yet but it's a starting place. The script automaticaly increments the tank levels, but that mechanism can be changed to reflect what you need. The progress bars can be colored based on their percentage, or time left to full, or whatever, but you have to do a tweak to XP for it to display properly on that OS (don't have that in front of me right now).

Tell me how far off this is from what you want for a GUI display:

; TankLevelMonitor.au3  --  By PsaltyDS of www.autoitscript.com/forum
; v0.1  --  04 July, 2006  --  AutoIT 3.1.128 Beta
#include <GuiConstants.au3>
#include <array.au3>

; Array of tank properties
;   Edit this list of _AddTank($sName, $iCapacity) statements to add/remove tanks
;   [0][0] = count of tanks
;       [n][0] = name of tank
;       [n][1] = max capacity (in barrels)
;       [n][2] = current level (in barrels)
;       [n][3] = name button CtrlID
;       [n][4] = progress bar CtrlID
;       [n][5] = stats label CtrlID
Global $aTankData[1][6]
$aTankData[0][0] = 0
_AddTank("Alpha", 300)
_AddTank("Bravo", 300)
_AddTank("Charlie", 350)
_AddTank("Delta", 350)
_AddTank("Echo", 400)
_AddTank("Foxtrot", 400)
_AddTank("Golf", 450)
_AddTank("Hotel", 450)
_AddTank("India", 500)
_AddTank("Juliet", 500)
_AddTank("Kilo", 525)
_AddTank("Lima", 525)
_AddTank("Mike", 550)
_AddTank("November", 575)
_AddTank("Oscar", 600)
_AddTank("Romeo", 600)

; Create GUI
Opt("GuiOnEventMode", 1)
$Title = "Tank Level Monitor"
$Gui_W = 800
$Gui_H = 50 + (40 * $aTankData[0][0]) ; 50 for title, 40 for buttons, plus 40 per tank
$hGui = GUICreate($Title, $Gui_W, $Gui_H, 50, 50)
$Label_Title = GUICtrlCreateLabel($Title, 10, 10, 780, 30, $SS_CENTER)
GUICtrlSetFont($Label_Title, 20, 600)

; Add tanks to GUI
$Tank_Top = 50 ; Top of first tank's GUI display
For $t = 1 To $aTankData[0][0]
    $aTankData[$t][3] = GUICtrlCreateButton($aTankData[$t][0], 10, $Tank_Top, 100, 30) ; Name button
    GUICtrlSetOnEvent(-1, "_TankButton")
    $aTankData[$t][2] = 0 ; Initial level = 0
    $aTankData[$t][4] = GUICtrlCreateProgress(120, $Tank_Top, 460, 30, $PBS_SMOOTH) ; Fill level progress bar
    $aTankData[$t][5] = GUICtrlCreateLabel("0 / 0 = 0%", 590, $Tank_Top, 200, 30, $SS_CENTER) ; Statistics label
    $Tank_Top += 40
Next

; Display GUI
GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiClose", $hGui)
GUISetState()

While 1
    For $t = 1 To $aTankData[0][0]
        $aTankData[$t][2] += Random(0, 5, 1) ; add random value from 0 to 5
        If $aTankData[$t][2] > $aTankData[$t][1] Then $aTankData[$t][2] = $aTankData[$t][1] ; Prevent run away values
        $TankPercent = Int($aTankData[$t][2] / $aTankData[$t][1] * 100)
        GUICtrlSetData($aTankData[$t][4], $TankPercent)
        GUICtrlSetData($aTankData[$t][5], $aTankData[$t][2] & " / " & $aTankData[$t][1] & " = " & $TankPercent & "%")
    Next
    Sleep(200)
WEnd


; ===================================
;   Local Functions
; ===================================

; _AddTank($sName, $iCapacity)
;   Where: $sName = String name, $iCapacity = max cap of tank (in barrels)
;   Adds a tank to the $aTankData array
Func _AddTank($sName, $iCapacity)
    $aTankData[0][0] = UBound($aTankData) ; Increments count by 1
    ReDim $aTankData[$aTankData[0][0] + 1][6]
    $aTankData[$aTankData[0][0]][0] = $sName
    $aTankData[$aTankData[0][0]][1] = $iCapacity
EndFunc   ;==>_AddTank


; _GuiClose()
;   Handles $GUI_EVENT_CLOSE
Func _GuiClose()
    Exit
EndFunc   ;==>_GuiClose


; _TankButton()
;   Handles clicking on the tank's name button to enter a new sounding
Func _TankButton()
    Local $Ctrl_ID = @GUI_CtrlId, $t, $sInput
    ; Find the tank that was clicked
    For $t = 1 To $aTankData[0][0]
        If $aTankData[$t][3] = $Ctrl_ID Then
            If MsgBox(32 + 4, $Title, 'You clicked on tank "' & $aTankData[$t][0] & '" --' & @CRLF & @CRLF & _
                    'Currently at ' & $aTankData[$t][2] & ' / ' & $aTankData[$t][1] & ' = ' & Int($aTankData[$t][2] / $aTankData[$t][1] * 100) & '% of capacity.' & @CRLF & @CRLF & _
                    'Do you want to enter a new sounding?') = 6 Then
                $sInput = InputBox($Title, 'Enter new sounding for tank "' & $aTankData[$t][0] & '", in barrels: ', '')
                If $sInput <> '' Then
                    If Number($sInput) >= 0 And Number($sInput) <= $aTankData[$t][1] Then $aTankData[$t][2] = Number($sInput)
                EndIf
            EndIf
            Return
        EndIf
    Next
EndFunc   ;==>_TankButton

:D


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Didn't have to do that , but thanks

Initially I had something similar set up. The reason I want to use a listview is because it scrolls.. That way it doesn't fill up the entire screen, or just simply run out of room.

If i could update the data in the listview without have to redraw the listview it would work. Currently I use something along the lines of

for $i = 0 to $num_tanks
  $list[$i] = GUICtrlCreateListViewItem("",$prioritylist)
Next
then in a while loop
while 1
  $a = 0
  while $a < $num_tanks
    GUICtrlSetData($list[$a],$pri[$a][$name]&"|"&$pri[$a][$expected]);tank name on left. Expected barrels on right
    $a = $a + 1
  wend
wend
Edited by Marklar

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Didn't have to do that , but thanks

Initially I had something similar set up. The reason I want to use a listview is because it scrolls.. That way it doesn't fill up the entire screen, or just simply run out of room.

If i could update the data in the listview without have to redraw the listview it would work. Currently I use something along the lines of

for $i = 0 to $num_tanks
  $list[$i] = GUICtrlCreateListViewItem("",$prioritylist)
Next
then in a while loop
while 1
  $a = 0
  while $a < $num_tanks
    GUICtrlSetData($list[$a],$pri[$a][$name]&"|"&$pri[$a][$expected]);tank name on left. Expected barrels on right
    $a = $a + 1
  wend
wend
Ahh, so! I'll take another stab at it tonight. Projects like this help me with my AutoIT edumacation... :D

I thought the important point was to see immediately if any tank was close to full, hence the big progress bars. I'm picturing a pull-down list of all the tanks, and the one selected shows its (one) progress bar and the relavent statistics, plus maybe the sounding input box. That would be much cleaner, but I think some code to warn about tanks that are getting close, currently displayed or not, would be prudent.

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I have a script where I ping 8 test computers every 500 ms and was updating a GUI with an Online or Offline every time and the flicker was REALLY annoying.

So, what I did was write the results into a temporary value, then every time you poll for new data see if it matches the current data. if it does match then do not refresh the screen. if they don't match then refresh the screen with the new data and overwrite the temporary value with the now current data so you can match against the new data next time around.

Mike


Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

If you're using a ListView, what I did was create an array that held all the items. Then I constantly updated the items using _GUICtrlListViewSetItemText found in the beta. However, if the amount of items changed, I cleared the array and cleared the ListView using _GUICtrlListViewDeleteAllItems, and re-created it with all the items.

That way you do not have to redraw the whole ListView, you just change either the string label, which doesn't flicker, or relist the items which shows a little movement, but thats expected. Plus, its not a problem unless you're constantly changing the amount of items.

Note: I run this updating function constantly with no sleep times and it doesn't flicker.

Edited by ending

Share this post


Link to post
Share on other sites

If you're using a ListView, what I did was create an array that held all the items. Then I constantly updated the items using _GUICtrlListViewSetItemText found in the beta. However, if the amount of items changed, I cleared the array and cleared the ListView using _GUICtrlListViewDeleteAllItems, and re-created it with all the items.

That way you do not have to redraw the whole ListView, you just change either the string label, which doesn't flicker, or relist the items which shows a little movement, but thats expected. Plus, its not a problem unless you're constantly changing the amount of items.

Note: I run this updating function constantly with no sleep times and it doesn't flicker.

Hmm.. I'll give that a try. It sounds like it could work.

PsaltyDS, the way I warn that a tank is near capacity is that if it is 1.5 hours within capacity the text of the tank/barrels in the listview turns red.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0