From c4ef4f5db282c1d673a2050eb3d159565f0660b7 Mon Sep 17 00:00:00 2001 From: gbamber Date: Mon, 9 Jan 2017 11:34:34 +0000 Subject: [PATCH] To V0.2.2.0: Traffic light health added. ToDo: Trigger config form git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5613 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- applications/foobot/foobot_utility.pas | 34 +- applications/foobot/monitor/foobotmonitor.lpi | 7 +- applications/foobot/monitor/foobotmonitor.lps | 142 ++++--- applications/foobot/monitor/foobotmonitor.res | Bin 71028 -> 71028 bytes applications/foobot/monitor/umainform.lfm | 384 +++++++++++++++++- applications/foobot/monitor/umainform.pas | 266 ++++++++---- 6 files changed, 658 insertions(+), 175 deletions(-) diff --git a/applications/foobot/foobot_utility.pas b/applications/foobot/foobot_utility.pas index 4c52be8bd..758b350e8 100644 --- a/applications/foobot/foobot_utility.pas +++ b/applications/foobot/foobot_utility.pas @@ -354,16 +354,32 @@ begin end; end; -// Function to make the Foobot data accessible -// Also sets the HighLow array values -// Also sets triggers +// Use FoobotDataObjectToArrays function to make the Foobot data accessible +// after a call to FetchFoobotData +// * Sets the HighLow array values +// * Sets triggers { -TAlertRec = Record - Triggered:Boolean; - AlertTime:TDateTime; - AlertType:TAlertType; - AlertValue:Variant; -end; +Here's calling code to use the triggers: +// Process Trigger Alerts on each call to FoobotDataObjectToArrays +if UseTriggers then + // Look for alerts in each sensor + for iCount := C_PM to C_ALLPOLLU do + begin + if (AlertRec[iCount].AlertTriggered=TRUE) then + begin + // Alert found. High or low? + if (AlertRec[iCount].AlertType = C_HIGH) then + begin + // A high alert - do something + DoHighTriggerAlert(iCount,AlertRec[iCount].AlertValue); + end + else + begin + // A low alert - do something + DoLowTriggerAlert(iCount,AlertRec[iCount].AlertValue); + end; + end; + end; } function FoobotDataObjectToArrays: boolean; var diff --git a/applications/foobot/monitor/foobotmonitor.lpi b/applications/foobot/monitor/foobotmonitor.lpi index 3cec7719c..20352c9bb 100644 --- a/applications/foobot/monitor/foobotmonitor.lpi +++ b/applications/foobot/monitor/foobotmonitor.lpi @@ -23,7 +23,7 @@ - + @@ -97,11 +97,6 @@ - - - - - diff --git a/applications/foobot/monitor/foobotmonitor.lps b/applications/foobot/monitor/foobotmonitor.lps index 0e0121a0d..3103beff6 100644 --- a/applications/foobot/monitor/foobotmonitor.lps +++ b/applications/foobot/monitor/foobotmonitor.lps @@ -3,14 +3,14 @@ - - + + - + @@ -19,9 +19,10 @@ - - - + + + + @@ -34,7 +35,7 @@ - + @@ -44,7 +45,7 @@ - + @@ -53,16 +54,15 @@ - + - - - - + + + @@ -72,7 +72,7 @@ - + @@ -80,7 +80,7 @@ - + @@ -91,7 +91,7 @@ - + @@ -101,8 +101,8 @@ - - + + @@ -111,7 +111,7 @@ - + @@ -119,7 +119,7 @@ - + @@ -190,7 +190,7 @@ - + @@ -219,14 +219,14 @@ - + - + @@ -270,130 +270,138 @@ - + + + + + + + + + - + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - + - + - - + + - + - - + + - + - + - + - + - - + + - - + + diff --git a/applications/foobot/monitor/foobotmonitor.res b/applications/foobot/monitor/foobotmonitor.res index 0cce42ae644e8be74cccfa65c83b1f8b62ee22d2..912d4d7de08c086220c5a59b849b29c1b1fbf6c0 100644 GIT binary patch delta 27 jcmeyeisj2HmJR3F7@0PoXWPoeXw=-wxxJN>@jW*HrVR>@ delta 27 jcmeyeisj2HmJR3F7#TO8XWPoeXxQA!xxJN>@jW*HrSb}m diff --git a/applications/foobot/monitor/umainform.lfm b/applications/foobot/monitor/umainform.lfm index 3e11e7507..1c0fa8eee 100644 --- a/applications/foobot/monitor/umainform.lfm +++ b/applications/foobot/monitor/umainform.lfm @@ -1,12 +1,12 @@ object mainform: Tmainform - Left = 516 - Height = 451 - Top = 144 + Left = 589 + Height = 506 + Top = 145 Width = 784 BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'mainform' - ClientHeight = 431 + ClientHeight = 486 ClientWidth = 784 DefaultMonitor = dmDesktop Font.Height = -12 @@ -140,27 +140,368 @@ object mainform: Tmainform AnalogKind = akAnalog end end + object grp_health: TGroupBox + Left = 0 + Height = 72 + Top = 120 + Width = 784 + Align = alTop + Caption = 'Health' + ClientHeight = 52 + ClientWidth = 780 + TabOrder = 3 + object pnl_healthpm: TPanel + Left = 0 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 0 + object sls_pm: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlightpm: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlightpm: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlightpm: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + object pnl_healthallpollu: TPanel + Left = 650 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 1 + object sls_allpollu: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlightallpollu: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlightallpollu: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlightallpollu: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + object pnl_healthvoc: TPanel + Left = 520 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 2 + object sls_voc: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlightvoc: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlightvoc: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlightvoc: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + object pnl_healthco2: TPanel + Left = 390 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 3 + object sls_co2: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlightco2: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlightco2: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlightco2: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + object pnl_healthhum: TPanel + Left = 260 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 4 + object sls_hum: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlighthum: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlighthum: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlighthum: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + object pnl_healthtmp: TPanel + Left = 130 + Height = 52 + Top = 0 + Width = 130 + Align = alLeft + ClientHeight = 52 + ClientWidth = 130 + TabOrder = 5 + object sls_tmp: TStopLightSensor + Left = 4 + Height = 43 + Top = 4 + Width = 23 + Picture.Data = { + 1754506F727461626C654E6574776F726B47726170686963F400000089504E47 + 0D0A1A0A0000000D49484452000000150000002B08020000001805541C000000 + BB49444154789CED95D10A80200C45FD743FAD3F33D3D2E972F34E7A281A04A2 + 9CB3619772DB5AB9F8786B85104EDEE115C187F932A785CF9B9EAC01BE81078A + 215FE0782C28243EC3C7319902E0FBE10DFDB96296BF5500F7C715F0FBAB0A73 + 7ED47A47FE7D5D037C0BDF2BB4FCF97C345488F94BF0F179235380F96F3AE3FD + B902CCBF082B7CA7F8F38FF3D7ED91F53C4FE19142C99F4B111614224FF25F14 + 58FEF90F00EBCF1558FE6558E13BC5F7F3BF99EAE4C342D54BB2D50EA0FED6E2 + 5B12FB970000000049454E44AE426082 + } + State = slUNKNOWN + end + object lbl_redlighttmp: TLabel + Left = 32 + Height = 15 + Top = 4 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_yellowlighttmp: TLabel + Left = 32 + Height = 15 + Top = 18 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + object lbl_greenlighttmp: TLabel + Left = 32 + Height = 15 + Top = 32 + Width = 96 + AutoSize = False + Caption = 'No Stats' + ParentColor = False + end + end + end object grp_highlow: TGroupBox Left = 0 - Height = 119 - Top = 120 + Height = 112 + Top = 192 Width = 784 Align = alTop Caption = 'All-time Highs and Lows' ChildSizing.EnlargeHorizontal = crsHomogenousChildResize ChildSizing.EnlargeVertical = crsScaleChilds ChildSizing.ControlsPerLine = 6 - ClientHeight = 99 + ClientHeight = 92 ClientWidth = 780 TabOrder = 1 object grp_pm: TGroupBox Left = 0 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'Particulates' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 0 object lbl_pmhigh: TLabel @@ -182,12 +523,12 @@ object mainform: Tmainform end object grp_tmp: TGroupBox Left = 130 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'Temperature' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 1 object lbl_tmphigh: TLabel @@ -209,12 +550,12 @@ object mainform: Tmainform end object grp_hum: TGroupBox Left = 260 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'Humidity' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 2 object lbl_humhigh: TLabel @@ -236,12 +577,12 @@ object mainform: Tmainform end object grp_co2: TGroupBox Left = 390 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'CO2' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 3 object lbl_co2high: TLabel @@ -263,12 +604,12 @@ object mainform: Tmainform end object grp_voc: TGroupBox Left = 520 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'Volatile VOC' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 4 object lbl_vochigh: TLabel @@ -290,12 +631,12 @@ object mainform: Tmainform end object grp_allpollu: TGroupBox Left = 650 - Height = 99 + Height = 92 Top = 0 Width = 130 Align = alLeft Caption = 'All Pollution' - ClientHeight = 79 + ClientHeight = 72 ClientWidth = 126 TabOrder = 5 object lbl_allpolluhigh: TLabel @@ -319,7 +660,7 @@ object mainform: Tmainform object grp_chart: TGroupBox Left = 0 Height = 179 - Top = 239 + Top = 304 Width = 784 Align = alTop Caption = 'History' @@ -395,8 +736,7 @@ object mainform: Tmainform Left = 16 end object MainMenu1: TMainMenu - Left = 56 - Top = 8 + Left = 200 object mnu_file: TMenuItem Caption = '&File' object mnu_fileExit: TMenuItem diff --git a/applications/foobot/monitor/umainform.pas b/applications/foobot/monitor/umainform.pas index 863d465a2..196231d76 100644 --- a/applications/foobot/monitor/umainform.pas +++ b/applications/foobot/monitor/umainform.pas @@ -38,9 +38,9 @@ V0.2.1.0: Triggers,Multiple Foobots interface uses // If Lazarus auto-inserts 'sensors' in the clause then delete it - SysUtils, TAGraph, TAIntervalSources, TASeries, foobot_sensors, - Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, Menus, lclIntf, - foobot_utility, uCryptIni, dateutils, uconfigform, utriggersform, Classes; + SysUtils, TAGraph, TAIntervalSources, TASeries, + foobot_sensors, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, Menus, + lclIntf, foobot_utility, uCryptIni, dateutils, uconfigform, utriggersform; const // Timer milliseconds @@ -95,6 +95,25 @@ type as_voc: TAnalogSensor; Chart1: TChart; DateTimeIntervalChartSource1: TDateTimeIntervalChartSource; + grp_health: TGroupBox; + lbl_greenlighttmp: TLabel; + lbl_greenlighthum: TLabel; + lbl_greenlightco2: TLabel; + lbl_greenlightvoc: TLabel; + lbl_greenlightallpollu: TLabel; + lbl_redlightpm: TLabel; + lbl_redlighttmp: TLabel; + lbl_redlighthum: TLabel; + lbl_redlightco2: TLabel; + lbl_redlightvoc: TLabel; + lbl_redlightallpollu: TLabel; + lbl_yellowlightpm: TLabel; + lbl_greenlightpm: TLabel; + lbl_yellowlighttmp: TLabel; + lbl_yellowlighthum: TLabel; + lbl_yellowlightco2: TLabel; + lbl_yellowlightvoc: TLabel; + lbl_yellowlightallpollu: TLabel; lineseries_allpollu: TLineSeries; lineseries_voc: TLineSeries; lineseries_co2: TLineSeries; @@ -152,6 +171,18 @@ type mnu_options: TMenuItem; mnu_fileExit: TMenuItem; mnu_file: TMenuItem; + pnl_healthpm: TPanel; + pnl_healthallpollu: TPanel; + pnl_healthvoc: TPanel; + pnl_healthco2: TPanel; + pnl_healthhum: TPanel; + pnl_healthtmp: TPanel; + sls_pm: TStopLightSensor; + sls_allpollu: TStopLightSensor; + sls_voc: TStopLightSensor; + sls_co2: TStopLightSensor; + sls_hum: TStopLightSensor; + sls_tmp: TStopLightSensor; traypopup: TPopupMenu; tmr_foobot: TTimer; TrayIcon1: TTrayIcon; @@ -187,7 +218,7 @@ type bDisplayGuagesOnly, bDisplayYellowLines, bDisplayRedLines: boolean; iFudgeFactor: integer; iCurrentFoobot: integer; - HighTriggerColor,LowTriggerColor:TColor; + HighTriggerColor, LowTriggerColor: TColor; foobotmenuarray: array of TMenuItem; procedure DisplayReadings; procedure UpdateGuage(Sender: TAnalogSensor; SensorNumber: integer); @@ -196,14 +227,16 @@ type procedure GraphCurrentReading; procedure SetYellowRecommendedLevels; procedure SetRedSessionMax; + procedure UpdateHealth; procedure PopulateFoobotMenu; procedure ChangeCurrentFoobot(Sender: TObject); procedure SaveConfig; procedure LoadConfig; procedure SetMinMaxTriggers; - procedure DoHighTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant); - procedure DoLowTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant); - procedure RestoreNormalColour(Const iSensorNum:Integer); + procedure SetTrafficLightStats; + procedure DoHighTriggerAlert(const iSensorNum: integer; const aValue: variant); + procedure DoLowTriggerAlert(const iSensorNum: integer; const aValue: variant); + procedure RestoreNormalColour(const iSensorNum: integer); public INI: TCryptINIfile; end; @@ -241,8 +274,8 @@ begin iFudgeFactor := 20; // only needed if height set in form.create bDisplayGuagesOnly := False; INI.PlainTextMode := True; - HighTriggerColor:=clYellow; - LowTriggerColor:=clAqua; + HighTriggerColor := clYellow; + LowTriggerColor := clAqua; bDisplayYellowLines := INI.ReadBool('Config', 'DisplayYellowLines', False); mnu_optionsDisplayYellowLines.Checked := bDisplayYellowLines; bDisplayRedLines := INI.ReadBool('Config', 'DisplayRedLines', False); @@ -257,11 +290,11 @@ begin {$IFDEF DEBUGMODE} UseTriggers := False; {$ENDIF} - If UseTriggers then + if UseTriggers then begin - mnu_options_triggersActivateTriggers.Enabled:=TRUE; - mnu_options_triggersActivateTriggers.Checked:=TRUE; - mnu_options_triggersActivateTriggers.Caption:='Set Triggers Off'; + mnu_options_triggersActivateTriggers.Enabled := True; + mnu_options_triggersActivateTriggers.Checked := True; + mnu_options_triggersActivateTriggers.Caption := 'Set Triggers Off'; end; end; @@ -270,7 +303,8 @@ var sTempFoobotUserName, sTempSecretKey: string; begin - ClientHeight := grp_sensorDisplay.Height + grp_highlow.Height + grp_chart.Height; + ClientHeight := grp_sensorDisplay.Height + grp_highlow.Height + + grp_health.Height + grp_chart.Height; Application.ProcessMessages; // Allow user to enter values in INIFile sTempFoobotUserName := INI.ReadUnencryptedString('Config', 'Foobot User', 'unknown'); @@ -309,6 +343,7 @@ begin LoadTriggers; // This can only be done if we have a Foobot Identity // as each Foobot has its own trigger values SetMinMaxTriggers; // Adjust if necesarry for Guage High/Low limits + SetTrafficLightStats; Show; {$IFNDEF DEBUGMODE} mnu_optionsTakeReadingNow.Click; @@ -361,6 +396,52 @@ begin mnu_optionsTakeReadingNow.Click; end; +procedure Tmainform.SetTrafficLightStats; +begin + lbl_redlightpm.Caption := Format('> %.1f %s', [double(FooBotTriggerArray[C_HIGH, C_PM]), + FoobotDataObject.Units[C_PM]]); + lbl_yellowlightpm.Caption := Format('> %.1f %s', [double(REC_PM), + FoobotDataObject.Units[C_PM]]); + lbl_greenlightpm.Caption := Format('< %.1f %s', [double(REC_PM), + FoobotDataObject.Units[C_PM]]); + + lbl_redlighttmp.Caption := Format('> %.1f %s', [double(FooBotTriggerArray[C_HIGH, C_TMP]), + FoobotDataObject.Units[C_TMP]]); + lbl_yellowlighttmp.Caption := + Format('> %.1f %s', [double(REC_TMP), FoobotDataObject.Units[C_TMP]]); + lbl_greenlighttmp.Caption := Format('< %.1f %s', [double(REC_TMP), + FoobotDataObject.Units[C_TMP]]); + + lbl_redlighthum.Caption := Format('> %.1f %s', [double(FooBotTriggerArray[C_HIGH, C_HUM]), + FoobotDataObject.Units[C_HUM]]); + lbl_yellowlighthum.Caption := + Format('> %.1f %s', [double(REC_HUM), FoobotDataObject.Units[C_HUM]]); + lbl_greenlighthum.Caption := Format('< %.1f %s', [double(REC_HUM), + FoobotDataObject.Units[C_HUM]]); + + lbl_redlightco2.Caption := Format('> %.0f %s', [double(FooBotTriggerArray[C_HIGH, C_CO2]), + FoobotDataObject.Units[C_CO2]]); + lbl_yellowlightco2.Caption := + Format('> %.0f %s', [double(REC_CO2), FoobotDataObject.Units[C_CO2]]); + lbl_greenlightco2.Caption := Format('< %.0f %s', [double(REC_CO2), + FoobotDataObject.Units[C_CO2]]); + + lbl_redlightvoc.Caption := Format('> %.0f %s', [double(FooBotTriggerArray[C_HIGH, C_VOC]), + FoobotDataObject.Units[C_VOC]]); + lbl_yellowlightvoc.Caption := + Format('> %.0f %s', [double(REC_VOC), FoobotDataObject.Units[C_VOC]]); + lbl_greenlightvoc.Caption := Format('< %.0f %s', [double(REC_VOC), + FoobotDataObject.Units[C_VOC]]); + + lbl_redlightallpollu.Caption := + Format('> %.1f %s', [double(FooBotTriggerArray[C_HIGH, C_ALLPOLLU]), + FoobotDataObject.Units[C_ALLPOLLU]]); + lbl_yellowlightallpollu.Caption := + Format('> %.1f %s', [double(REC_ALLPOLLU), FoobotDataObject.Units[C_ALLPOLLU]]); + lbl_greenlightallpollu.Caption := + Format('< %.1f %s', [double(REC_ALLPOLLU), FoobotDataObject.Units[C_ALLPOLLU]]); +end; + procedure Tmainform.PopulateFoobotMenu; // Uses dynamic foobotmenuarray var @@ -403,7 +484,7 @@ end; procedure Tmainform.SaveConfig; // For all Foobots begin - With INI do + with INI do begin PlainTextMode := True; // Colours @@ -428,7 +509,7 @@ begin WriteFloat('Config', 'allpolluMaxValue', as_allpollu.ValueMax); WriteBool('Config', 'DisplayYellowLines', bDisplayYellowLines); WriteBool('Config', 'DisplayRedLines', bDisplayRedLines); - // Triggers + // Triggers WriteBool('Config', 'UseTriggers', UseTriggers); WriteString('Config', 'HighTriggerColour', ColorToString(HighTriggerColor)); WriteString('Config', 'LowTriggerColour', ColorToString(LowTriggerColor)); @@ -504,10 +585,11 @@ begin as_allpollu.ValueMin := INI.ReadFloat('Config', 'allpolluMinValue', MIN_ALLPOLLU); as_allpollu.ValueMax := INI.ReadFloat('Config', 'allpolluMaxValue', MAX_ALLPOLLU); // Triggers - UseTriggers:=INI.ReadBool('Config', 'UseTriggers', False); - HighTriggerColor:=StringToColor(INI.ReadString('Config', 'HighTriggerColour', 'clYellow')); - LowTriggerColor:=StringToColor(INI.ReadString('Config', 'LowTriggerColour', 'clAqua')); -INI.PlainTextMode := False; + UseTriggers := INI.ReadBool('Config', 'UseTriggers', False); + HighTriggerColor := StringToColor(INI.ReadString('Config', 'HighTriggerColour', + 'clYellow')); + LowTriggerColor := StringToColor(INI.ReadString('Config', 'LowTriggerColour', 'clAqua')); + INI.PlainTextMode := False; end; procedure Tmainform.FormWindowStateChange(Sender: TObject); @@ -561,10 +643,10 @@ procedure Tmainform.mnu_optionsDisplayGuagesOnlyClick(Sender: TObject); begin bDisplayGuagesOnly := mnu_optionsDisplayGuagesOnly.Checked; if bDisplayGuagesOnly then - mainform.ClientHeight := grp_sensorDisplay.Height// + iFudgeFactor + mainform.ClientHeight := grp_sensorDisplay.Height + grp_health.Height else - mainform.ClientHeight := grp_sensorDisplay.Height + grp_chart.Height + - grp_highlow.Height;// + iFudgeFactor; + mainform.ClientHeight := grp_sensorDisplay.Height + grp_health.Height + + grp_chart.Height + grp_highlow.Height; end; procedure Tmainform.mnu_optionsDisplayRedLinesClick(Sender: TObject); @@ -628,7 +710,7 @@ begin begin mnu_options_triggersActivateTriggers.Caption := 'Set Triggers Off'; LoadTriggers; - SetMinMaxTriggers + SetMinMaxTriggers; end else mnu_options_triggersActivateTriggers.Caption := 'Set Triggers On'; @@ -796,22 +878,22 @@ begin C_CO2: begin lbl_co2high.Caption := Format('High: %d %s', - [Integer(FoobotDataHighs[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + + [integer(FoobotDataHighs[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber])); lbl_co2Low.Caption := Format('Low: %d %s', - [Integer(FoobotDataLows[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + + [integer(FoobotDataLows[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime( FoobotDataLowTimes[SensorNumber])); end; C_VOC: begin lbl_vochigh.Caption := Format('High: %d %s', - [Integer(FoobotDataHighs[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + + [integer(FoobotDataHighs[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber])); lbl_vocLow.Caption := Format('Low: %d %s', - [Integer(FoobotDataLows[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + + [integer(FoobotDataLows[SensorNumber]), FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime( FoobotDataLowTimes[SensorNumber])); end; @@ -876,41 +958,77 @@ begin SetYellowRecommendedLevels; end; end; -procedure Tmainform.DoHighTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant); -begin - Case iSensorNum of - C_PM:as_pm.Color:=HighTriggerColor; - C_TMP:as_tmp.Color:=HighTriggerColor; - C_HUM:as_hum.Color:=HighTriggerColor; - C_CO2:as_co2.Color:=HighTriggerColor; - C_VOC:as_voc.Color:=HighTriggerColor; - C_ALLPOLLU:as_allpollu.Color:=HighTriggerColor; - end; -end; -procedure Tmainform.DoLowTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant); +procedure Tmainform.DoHighTriggerAlert(const iSensorNum: integer; const aValue: variant); begin - Case iSensorNum of - C_PM:as_pm.Color:=LowTriggerColor; - C_TMP:as_tmp.Color:=LowTriggerColor; - C_HUM:as_hum.Color:=LowTriggerColor; - C_CO2:as_co2.Color:=LowTriggerColor; - C_VOC:as_voc.Color:=LowTriggerColor; - C_ALLPOLLU:as_allpollu.Color:=LowTriggerColor; + case iSensorNum of + C_PM: as_pm.Color := HighTriggerColor; + C_TMP: as_tmp.Color := HighTriggerColor; + C_HUM: as_hum.Color := HighTriggerColor; + C_CO2: as_co2.Color := HighTriggerColor; + C_VOC: as_voc.Color := HighTriggerColor; + C_ALLPOLLU: as_allpollu.Color := HighTriggerColor; end; end; -procedure Tmainform.RestoreNormalColour(Const iSensorNum:Integer); +procedure Tmainform.DoLowTriggerAlert(const iSensorNum: integer; const aValue: variant); begin - Case iSensorNum of - C_PM:as_pm.Color:=clDefault; - C_TMP:as_tmp.Color:=clDefault; - C_HUM:as_hum.Color:=clDefault; - C_CO2:as_co2.Color:=clDefault; - C_VOC:as_voc.Color:=clDefault; - C_ALLPOLLU:as_allpollu.Color:=clDefault; + case iSensorNum of + C_PM: as_pm.Color := LowTriggerColor; + C_TMP: as_tmp.Color := LowTriggerColor; + C_HUM: as_hum.Color := LowTriggerColor; + C_CO2: as_co2.Color := LowTriggerColor; + C_VOC: as_voc.Color := LowTriggerColor; + C_ALLPOLLU: as_allpollu.Color := LowTriggerColor; end; end; + +procedure Tmainform.RestoreNormalColour(const iSensorNum: integer); +begin + case iSensorNum of + C_PM: as_pm.Color := clDefault; + C_TMP: as_tmp.Color := clDefault; + C_HUM: as_hum.Color := clDefault; + C_CO2: as_co2.Color := clDefault; + C_VOC: as_voc.Color := clDefault; + C_ALLPOLLU: as_allpollu.Color := clDefault; + end; +end; + +procedure Tmainform.UpdateHealth; +begin + if (as_pm.Value > REC_PM) then + sls_pm.State := slYELLOW + else + sls_pm.State := slGREEN; + + if (as_tmp.Value > REC_TMP) then + sls_tmp.State := slYELLOW + else + sls_tmp.State := slGREEN; + + if (as_hum.Value > REC_HUM) then + sls_hum.State := slYELLOW + else + sls_hum.State := slGREEN; + + if (as_co2.Value > REC_CO2) then + sls_co2.State := slYELLOW + else + sls_co2.State := slGREEN; + + if (as_voc.Value > REC_VOC) then + sls_voc.State := slYELLOW + else + sls_voc.State := slGREEN; + + if (as_allpollu.Value > REC_ALLPOLLU) then + sls_allpollu.State := slYELLOW + else + sls_allpollu.State := slGREEN; + +end; + procedure Tmainform.DisplayReadings; var iCount: integer; @@ -926,31 +1044,37 @@ begin UpdateGuage(as_co2, C_CO2); UpdateGuage(as_voc, C_VOC); UpdateGuage(as_allpollu, C_ALLPOLLU); + UpdateHealth; // Process Trigger Alerts on each call to FoobotDataObjectToArrays if UseTriggers then try // Look for alerts in each sensor for iCount := C_PM to C_ALLPOLLU do begin - if (AlertRec[iCount].AlertTriggered=TRUE) then + if (AlertRec[iCount].AlertTriggered = True) then begin + case iCount of + C_PM: sls_pm.State := slRED; + C_TMP: sls_tmp.State := slRED; + C_HUM: sls_hum.State := slRED; + C_CO2: sls_co2.State := slRED; + C_VOC: sls_voc.State := slRED; + C_ALLPOLLU: sls_allpollu.State := slRED; + end; // Alert found. High or low? if (AlertRec[iCount].AlertType = C_HIGH) then begin // A high alert - do something - DoHighTriggerAlert(iCount,AlertRec[iCount].AlertValue); + DoHighTriggerAlert(iCount, AlertRec[iCount].AlertValue); end else begin // A low alert - do something - DoLowTriggerAlert(iCount,AlertRec[iCount].AlertValue); - { - ShowMessageFmt('Low alert member %d (value %f) exceeded', - [iCount, double(AlertRec[iCount].AlertValue)]); - } + DoLowTriggerAlert(iCount, AlertRec[iCount].AlertValue); end; end - else RestoreNormalColour(iCount); + else + RestoreNormalColour(iCount); end; except raise Exception.Create('Unable to process triggers in DisplayReadings'); @@ -962,7 +1086,6 @@ begin end; GraphCurrentReading; - end else raise Exception.Create('FoobotDataObjectToArrays error in DisplayReadings'); @@ -984,8 +1107,8 @@ begin try lineseries_pm.AddXY(FoobotData_time[iCurrentFoobot], AsPercent(FoobotData_pm[iCurrentFoobot], as_pm.ValueMin, as_pm.ValueMax)); - lineseries_tmp.AddXY(FoobotData_time[iCurrentFoobot], AsPercent(FoobotData_tmp[iCurrentFoobot], - as_tmp.ValueMin, as_tmp.ValueMax)); + lineseries_tmp.AddXY(FoobotData_time[iCurrentFoobot], + AsPercent(FoobotData_tmp[iCurrentFoobot], as_tmp.ValueMin, as_tmp.ValueMax)); lineseries_hum.AddXY(FoobotData_time[iCurrentFoobot], AsPercent(FoobotData_hum[iCurrentFoobot], as_hum.ValueMin, as_hum.ValueMax)); lineseries_co2.AddXY(FoobotData_time[iCurrentFoobot], @@ -993,7 +1116,8 @@ begin lineseries_voc.AddXY(FoobotData_time[iCurrentFoobot], AsPercent(FoobotData_voc[iCurrentFoobot], as_voc.ValueMin, as_voc.ValueMax)); lineseries_allpollu.AddXY(FoobotData_time[iCurrentFoobot], - AsPercent(FoobotData_allpollu[iCurrentFoobot], as_allpollu.ValueMin, as_allpollu.ValueMax)); + AsPercent(FoobotData_allpollu[iCurrentFoobot], as_allpollu.ValueMin, + as_allpollu.ValueMax)); except raise Exception.Create('Unable to update graph in GraphCurrentReading'); end; @@ -1005,14 +1129,14 @@ procedure Tmainform.GraphHistory; var iCount: integer; iStartSeconds, iEndSeconds: int64; - bTempUseTriggers:Boolean; + bTempUseTriggers: boolean; begin {$IFDEF DEBUGMODE} Exit; {$ENDIF} // Turn off triggers (if on) - bTempUseTriggers:=UseTriggers; - UseTriggers:=FALSE; + bTempUseTriggers := UseTriggers; + UseTriggers := False; iEndSeconds := DateTimeToUnix(Now) - 3600; iStartSeconds := iEndSeconds - (2 * (24 * 3600)); // 49 hours before Now @@ -1040,7 +1164,7 @@ begin as_allpollu.ValueMax)); end; finally - UseTriggers:=bTempUseTriggers; + UseTriggers := bTempUseTriggers; ResetArrays; // at end end; end;