V0.2.1.0: Work-in-progress Trigger alerts working

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5611 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
gbamber 2017-01-08 21:18:05 +00:00
parent aad378487c
commit 548670509f
3 changed files with 298 additions and 177 deletions

View File

@ -52,13 +52,16 @@ const
type
TDataFetchType = (dfLast, dfStartEnd); // FetchFoobotData
// Unused
TSensorType = (st_time, st_pm, st_tmp, st_hum, st_co2, st_voc, st_allpollu); // Unused
// Unused
TAlertType = (at_high, at_low); // TAlertRec
TAlertRec = record
AlertTriggered: boolean;
AlertTime: TDateTime;
AlertType: TAlertType;
AlertType: Integer;
AlertValue: variant;
end;
@ -78,10 +81,12 @@ function FetchFoobotData(DataFetchType: TDataFetchType = dfLast;
// - also populates HighLow arrays
function FoobotDataObjectToArrays: boolean;
// Sets internal FooBotTriggerArray which can be tested against in FoobotDataObjectToArrays
// Gets/Sets internal FooBotTriggerArray which can be tested against in FoobotDataObjectToArrays
// aSensor use consts: C_PM,C_TMP etc.
function SetHighTrigger(const aSensor: integer; const aValue: variant): boolean;
function SetLowTrigger(const aSensor: integer; const aValue: variant): boolean;
function GetHighTrigger(Const aSensor:Integer):Variant;
function GetLowTrigger(Const aSensor:Integer):Variant;
// Utility functions
function ResetArrays: boolean;
@ -152,29 +157,29 @@ begin
WriteInteger('Foobot', 'CurrentFoobot', TheCurrentFoobot);
WriteString('Foobot', 'CurrentFoobotName', sFoobotName);
WriteFloat(sFoobotName, 'pmTriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_PM]));
double(FooBotTriggerArray[0, C_PM]));
WriteFloat(sFoobotName, 'pmTriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_PM]));
double(FooBotTriggerArray[1, C_PM]));
WriteFloat(sFoobotName, 'tmpTriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_TMP]));
double(FooBotTriggerArray[0, C_TMP]));
WriteFloat(sFoobotName, 'tmpTriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_TMP]));
double(FooBotTriggerArray[1, C_TMP]));
WriteFloat(sFoobotName, 'humTriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_HUM]));
double(FooBotTriggerArray[0, C_HUM]));
WriteFloat(sFoobotName, 'humTriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_HUM]));
double(FooBotTriggerArray[1, C_HUM]));
WriteFloat(sFoobotName, 'co2TriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_CO2]));
double(FooBotTriggerArray[0, C_CO2]));
WriteFloat(sFoobotName, 'co2TriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_CO2]));
double(FooBotTriggerArray[1, C_CO2]));
WriteFloat(sFoobotName, 'vocTriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_VOC]));
double(FooBotTriggerArray[0, C_VOC]));
WriteFloat(sFoobotName, 'vocTriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_VOC]));
double(FooBotTriggerArray[1, C_VOC]));
WriteFloat(sFoobotName, 'allpolluTriggerHigh',
double(FooBotTriggerArray[Ord(at_high), C_ALLPOLLU]));
double(FooBotTriggerArray[0, C_ALLPOLLU]));
WriteFloat(sFoobotName, 'allpolluTriggerLow',
double(FooBotTriggerArray[Ord(at_Low), C_ALLPOLLU]));
double(FooBotTriggerArray[1, C_ALLPOLLU]));
end;
Result := True;
except
@ -201,19 +206,19 @@ begin
// Load current Foobot triggers
with HLINI do
begin
FooBotTriggerArray[Ord(at_high), C_PM] := ReadFloat(sFoobotName, 'pmTriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_PM] := ReadFloat(sFoobotName, 'pmTriggerLow', 0);
FooBotTriggerArray[Ord(at_high), C_TMP] := ReadFloat(sFoobotName, 'tmpTriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_TMP] := ReadFloat(sFoobotName, 'tmpTriggerLow', 0);
FooBotTriggerArray[Ord(at_high), C_HUM] := ReadFloat(sFoobotName, 'humTriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_HUM] := ReadFloat(sFoobotName, 'humTriggerLow', 0);
FooBotTriggerArray[Ord(at_high), C_CO2] := ReadFloat(sFoobotName, 'co2TriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_CO2] := ReadFloat(sFoobotName, 'co2TriggerLow', 0);
FooBotTriggerArray[Ord(at_high), C_VOC] := ReadFloat(sFoobotName, 'vocTriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_VOC] := ReadFloat(sFoobotName, 'vocTriggerLow', 0);
FooBotTriggerArray[Ord(at_high), C_ALLPOLLU] :=
FooBotTriggerArray[0, C_PM] := ReadFloat(sFoobotName, 'pmTriggerHigh', 0);
FooBotTriggerArray[1, C_PM] := ReadFloat(sFoobotName, 'pmTriggerLow', 0);
FooBotTriggerArray[0, C_TMP] := ReadFloat(sFoobotName, 'tmpTriggerHigh', 0);
FooBotTriggerArray[1, C_TMP] := ReadFloat(sFoobotName, 'tmpTriggerLow', 0);
FooBotTriggerArray[0, C_HUM] := ReadFloat(sFoobotName, 'humTriggerHigh', 0);
FooBotTriggerArray[1, C_HUM] := ReadFloat(sFoobotName, 'humTriggerLow', 0);
FooBotTriggerArray[0, C_CO2] := ReadFloat(sFoobotName, 'co2TriggerHigh', 0);
FooBotTriggerArray[1, C_CO2] := ReadFloat(sFoobotName, 'co2TriggerLow', 0);
FooBotTriggerArray[0, C_VOC] := ReadFloat(sFoobotName, 'vocTriggerHigh', 0);
FooBotTriggerArray[1, C_VOC] := ReadFloat(sFoobotName, 'vocTriggerLow', 0);
FooBotTriggerArray[0, C_ALLPOLLU] :=
ReadFloat(sFoobotName, 'allpolluTriggerHigh', 0);
FooBotTriggerArray[Ord(at_low), C_ALLPOLLU] :=
FooBotTriggerArray[1, C_ALLPOLLU] :=
ReadFloat(sFoobotName, 'allpolluTriggerLow', 0);
end;
Result := True;
@ -365,21 +370,22 @@ var
// ========= Internal routines start ===========
procedure SetHigh(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
// Do High/Low
if aValue > FoobotDataHighs[iMember] then
begin
FoobotDataHighs[iMember] := aValue;
FoobotDataHighTimes[iMember] := aDateTime;
SaveHighLows;
end;
if ((UseTriggers = True) and (FooBotTriggerArray[1, iMember] <> 0)) then
if ((UseTriggers = True) and (FooBotTriggerArray[0, iMember] <> 0)) then
begin
// Process High Trigger
// Do High Trigger
// Sets AlertRec record
if (aValue > FooBotTriggerArray[1, iMember]) then
if (aValue > FooBotTriggerArray[0, iMember]) then
begin
AlertRec[iMember].AlertTriggered := True;
AlertRec[iMember].AlertTime := aDateTime;
AlertRec[iMember].AlertType := at_high;
AlertRec[iMember].AlertType := 0;
AlertRec[iMember].AlertValue := aValue;
end
else
@ -389,21 +395,22 @@ var
procedure SetLow(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
// Do High/Low
if (aValue < FoobotDataLows[iMember]) or (FoobotDataLows[iMember] = 0) then
begin
FoobotDataLows[iMember] := aValue;
FoobotDataLowTimes[iMember] := aDateTime;
SaveHighLows;
end;
if ((UseTriggers = True) and (FooBotTriggerArray[0, iMember] <> 0)) then
if ((UseTriggers = True) and (FooBotTriggerArray[1, iMember] <> 0)) then
begin
// Process Low Trigger
// Do Low Trigger
// Sets AlertRec record
if (aValue < FooBotTriggerArray[1, iMember]) then
begin
AlertRec[iMember].AlertTriggered := True;
AlertRec[iMember].AlertTime := aDateTime;
AlertRec[iMember].AlertType := at_low;
AlertRec[iMember].AlertType := 1;
AlertRec[iMember].AlertValue := aValue;
end
else
@ -486,26 +493,46 @@ begin
end;
function GetHighTrigger(Const aSensor:Integer):Variant;
//TAlertType = (at_high, at_low)
begin
Result:=0;
if UseTriggers = False then Exit;
If ((aSensor < C_PM) or (aSensor > C_ALLPOLLU)) then exit;
Result:=FooBotTriggerArray[0, aSensor];
end;
function GetLowTrigger(Const aSensor:Integer):Variant;
//TAlertType = (at_high, at_low)
begin
Result:=0;
if UseTriggers = False then Exit;
If ((aSensor < C_PM) or (aSensor > C_ALLPOLLU)) then exit;
Result:=FooBotTriggerArray[1, aSensor];
end;
function SetHighTrigger(const aSensor: integer; const aValue: variant): boolean;
//TAlertType = (at_high, at_low)
begin
Result := False;
if UseTriggers = False then
Exit;
if aValue <> FooBotTriggerArray[0, aSensor] then
begin
FooBotTriggerArray[0, aSensor] := aValue;
Result := True;
end;
end;
function SetLowTrigger(const aSensor: integer; const aValue: variant): boolean;
//TAlertType = (at_high, at_low)
begin
Result := False;
if UseTriggers = False then
Exit;
if aValue <> FooBotTriggerArray[1, Ord(aSensor)] then
begin
FooBotTriggerArray[1, Ord(aSensor)] := aValue;
Result := True;
end;
end;
function SetLowTrigger(const aSensor: integer; const aValue: variant): boolean;
begin
Result := False;
if UseTriggers = False then
Exit;
if aValue <> FooBotTriggerArray[0, Ord(aSensor)] then
begin
FooBotTriggerArray[0, Ord(aSensor)] := aValue;
FooBotTriggerArray[1, aSensor] := aValue;
Result := True;
end;
end;
@ -758,12 +785,12 @@ initialization
TheCurrentFoobot := 0;
SetLength(FooBotTriggerArray, 2, Succ(C_ALLPOLLU));
SaveLoadHighLows := True; // Default
UseTriggers := False; // Defaul
UseTriggers := False; // Default
for giCount := C_PM to C_ALLPOLLU do
begin
AlertRec[giCount].AlertTriggered := False;
AlertRec[giCount].AlertTime := Now;
AlertRec[giCount].AlertType := at_low;
AlertRec[giCount].AlertType := 0;
AlertRec[giCount].AlertValue := 0;
end;
end;

View File

@ -3,14 +3,14 @@
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="10"/>
<BuildModes Active="win32"/>
<BuildModes Active="win64"/>
<Units Count="33">
<Unit0>
<Filename Value="foobotmonitor.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="12"/>
<CursorPos Y="35"/>
<UsageCount Value="108"/>
<UsageCount Value="110"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
@ -20,8 +20,8 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<CursorPos X="26" Y="19"/>
<UsageCount Value="108"/>
<CursorPos Y="307"/>
<UsageCount Value="110"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
@ -34,7 +34,7 @@
<EditorIndex Value="7"/>
<TopLine Value="33"/>
<CursorPos X="41" Y="45"/>
<UsageCount Value="98"/>
<UsageCount Value="100"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit2>
@ -44,7 +44,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="380"/>
<CursorPos X="35" Y="387"/>
<UsageCount Value="90"/>
<UsageCount Value="92"/>
</Unit3>
<Unit4>
<Filename Value="..\foobot_objects.pas"/>
@ -53,15 +53,15 @@
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="90"/>
<UsageCount Value="92"/>
</Unit4>
<Unit5>
<Filename Value="..\foobot_utility.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="9"/>
<TopLine Value="88"/>
<CursorPos X="45" Y="108"/>
<UsageCount Value="108"/>
<TopLine Value="761"/>
<CursorPos X="13" Y="770"/>
<UsageCount Value="110"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
@ -71,7 +71,7 @@
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="90"/>
<UsageCount Value="92"/>
</Unit6>
<Unit7>
<Filename Value="foobot_sensors.pas"/>
@ -79,7 +79,7 @@
<EditorIndex Value="4"/>
<TopLine Value="299"/>
<CursorPos X="14" Y="321"/>
<UsageCount Value="42"/>
<UsageCount Value="44"/>
<Loaded Value="True"/>
</Unit7>
<Unit8>
@ -90,7 +90,7 @@
<ResourceBaseClass Value="Form"/>
<EditorIndex Value="2"/>
<CursorPos X="42" Y="25"/>
<UsageCount Value="37"/>
<UsageCount Value="39"/>
<Loaded Value="True"/>
</Unit8>
<Unit9>
@ -101,7 +101,7 @@
<ResourceBaseClass Value="Form"/>
<EditorIndex Value="1"/>
<CursorPos X="57" Y="24"/>
<UsageCount Value="28"/>
<UsageCount Value="30"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit9>
@ -110,7 +110,7 @@
<EditorIndex Value="8"/>
<TopLine Value="43"/>
<CursorPos X="47" Y="13"/>
<UsageCount Value="70"/>
<UsageCount Value="71"/>
<Loaded Value="True"/>
</Unit10>
<Unit11>
@ -118,7 +118,7 @@
<EditorIndex Value="11"/>
<TopLine Value="46"/>
<CursorPos X="35" Y="59"/>
<UsageCount Value="70"/>
<UsageCount Value="71"/>
<Loaded Value="True"/>
</Unit11>
<Unit12>
@ -189,7 +189,7 @@
<EditorIndex Value="5"/>
<TopLine Value="101"/>
<CursorPos Y="154"/>
<UsageCount Value="21"/>
<UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit21>
<Unit22>
@ -218,14 +218,14 @@
<EditorIndex Value="10"/>
<TopLine Value="381"/>
<CursorPos X="13" Y="384"/>
<UsageCount Value="39"/>
<UsageCount Value="40"/>
<Loaded Value="True"/>
</Unit25>
<Unit26>
<Filename Value="..\latest_stable\udataform.pas"/>
<EditorIndex Value="6"/>
<TopLine Value="70"/>
<UsageCount Value="39"/>
<UsageCount Value="40"/>
<Loaded Value="True"/>
</Unit26>
<Unit27>
@ -269,130 +269,130 @@
<EditorIndex Value="3"/>
<TopLine Value="1811"/>
<CursorPos X="13" Y="1834"/>
<UsageCount Value="17"/>
<UsageCount Value="18"/>
<Loaded Value="True"/>
</Unit32>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="374" Column="51" TopLine="327"/>
</Position1>
<Position2>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="83" Column="46" TopLine="97"/>
</Position2>
<Position3>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="100" Column="5" TopLine="93"/>
</Position3>
<Position4>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="101" Column="28" TopLine="93"/>
</Position4>
<Position5>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="374" Column="47" TopLine="348"/>
</Position5>
<Position6>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="386" Column="46" TopLine="348"/>
</Position6>
<Position7>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="55" Column="89" TopLine="28"/>
</Position7>
<Position8>
<Filename Value="umainform.pas"/>
<Caret Line="502" Column="28" TopLine="492"/>
</Position8>
<Position9>
<Filename Value="umainform.pas"/>
<Caret Line="509" Column="28" TopLine="499"/>
</Position9>
<Position10>
<Filename Value="umainform.pas"/>
<Caret Line="491" Column="12" TopLine="489"/>
</Position10>
<Position11>
<Filename Value="utriggersform.pas"/>
<Caret Line="18" Column="57"/>
</Position11>
<Position12>
<Filename Value="utriggersform.pas"/>
<Caret Line="19" Column="57"/>
</Position12>
<Position13>
<Filename Value="utriggersform.pas"/>
<Caret Line="20" Column="57"/>
</Position13>
<Position14>
</Position1>
<Position2>
<Filename Value="utriggersform.pas"/>
<Caret Line="21" Column="57"/>
</Position14>
<Position15>
</Position2>
<Position3>
<Filename Value="utriggersform.pas"/>
<Caret Line="22" Column="57"/>
</Position15>
<Position16>
</Position3>
<Position4>
<Filename Value="utriggersform.pas"/>
<Caret Line="23" Column="57"/>
</Position16>
<Position17>
</Position4>
<Position5>
<Filename Value="utriggersform.pas"/>
<Caret Line="24" Column="57"/>
</Position17>
<Position18>
</Position5>
<Position6>
<Filename Value="utriggersform.pas"/>
<Caret Line="25" Column="57"/>
</Position18>
<Position19>
</Position6>
<Position7>
<Filename Value="utriggersform.pas"/>
<Caret Line="24" Column="57"/>
</Position19>
<Position20>
</Position7>
<Position8>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="149" Column="77" TopLine="117"/>
</Position20>
<Position21>
</Position8>
<Position9>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="139" TopLine="124"/>
</Position21>
<Position22>
</Position9>
<Position10>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="151" Column="82" TopLine="123"/>
</Position10>
<Position11>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="181" Column="81" TopLine="140"/>
</Position11>
<Position12>
<Filename Value="umainform.pas"/>
<Caret Line="12" Column="24"/>
</Position12>
<Position13>
<Filename Value="umainform.pas"/>
<Caret Line="630" Column="16" TopLine="613"/>
</Position13>
<Position14>
<Filename Value="umainform.pas"/>
<Caret Line="634" Column="46" TopLine="606"/>
</Position14>
<Position15>
<Filename Value="umainform.pas"/>
<Caret Line="2" Column="59"/>
</Position15>
<Position16>
<Filename Value="umainform.pas"/>
<Caret Line="364" Column="58" TopLine="317"/>
</Position16>
<Position17>
<Filename Value="umainform.pas"/>
<Caret Line="633" Column="48" TopLine="586"/>
</Position17>
<Position18>
<Filename Value="umainform.pas"/>
<Caret Line="824" Column="48" TopLine="777"/>
</Position18>
<Position19>
<Filename Value="umainform.pas"/>
<Caret Line="404" TopLine="383"/>
</Position19>
<Position20>
<Filename Value="umainform.pas"/>
<Caret Line="614" Column="23" TopLine="596"/>
</Position20>
<Position21>
<Filename Value="umainform.pas"/>
<Caret Line="202" Column="32" TopLine="159"/>
</Position21>
<Position22>
<Filename Value="umainform.pas"/>
<Caret Line="302" Column="26" TopLine="276"/>
</Position22>
<Position23>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="181" Column="81" TopLine="140"/>
<Caret Line="157" Column="35" TopLine="137"/>
</Position23>
<Position24>
<Filename Value="umainform.pas"/>
<Caret Line="12" Column="24"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="158" Column="43" TopLine="137"/>
</Position24>
<Position25>
<Filename Value="umainform.pas"/>
<Caret Line="630" Column="16" TopLine="613"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="203" Column="40" TopLine="181"/>
</Position25>
<Position26>
<Filename Value="umainform.pas"/>
<Caret Line="634" Column="46" TopLine="606"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="157" Column="37" TopLine="140"/>
</Position26>
<Position27>
<Filename Value="umainform.pas"/>
<Caret Line="2" Column="59"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="159" Column="36" TopLine="140"/>
</Position27>
<Position28>
<Filename Value="umainform.pas"/>
<Caret Line="364" Column="58" TopLine="317"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="157" Column="36" TopLine="140"/>
</Position28>
<Position29>
<Filename Value="umainform.pas"/>
<Caret Line="633" Column="48" TopLine="586"/>
<Caret Line="929" Column="38" TopLine="909"/>
</Position29>
<Position30>
<Filename Value="umainform.pas"/>
<Caret Line="824" Column="48" TopLine="777"/>
<Filename Value="..\foobot_utility.pas"/>
<Caret Line="58" TopLine="41"/>
</Position30>
</JumpHistory>
</ProjectSession>

View File

@ -199,6 +199,10 @@ type
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);
public
INI: TCryptINIfile;
end;
@ -285,9 +289,6 @@ begin
if SaveLoadHighLows then
LoadHighLows;
GraphHistory;
{$IFNDEF DEBUGMODE}
mnu_optionsTakeReadingNow.Click;
{$ENDIF}
// Switch off for testing
tmr_foobot.Interval := ONEHOUR;
{$IFNDEF DEBUGMODE}
@ -298,7 +299,11 @@ begin
PopulateFoobotMenu;
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
Show;
{$IFNDEF DEBUGMODE}
mnu_optionsTakeReadingNow.Click;
{$ENDIF}
grp_sensorDisplay.Refresh;
grp_highlow.Refresh;
Update;
@ -389,31 +394,71 @@ end;
procedure Tmainform.SaveConfig;
// For all Foobots
begin
INI.PlainTextMode := True;
// Colours
INI.WriteString('Config', 'pmColour', ColorToString(as_pm.ColorFore));
INI.WriteString('Config', 'tmpColour', ColorToString(as_tmp.ColorFore));
INI.WriteString('Config', 'humColour', ColorToString(as_hum.ColorFore));
INI.WriteString('Config', 'co2Colour', ColorToString(as_co2.ColorFore));
INI.WriteString('Config', 'vocColour', ColorToString(as_voc.ColorFore));
INI.WriteString('Config', 'allpolluColour', ColorToString(as_allpollu.ColorFore));
With INI do
begin
PlainTextMode := True;
// Colours
WriteString('Config', 'pmColour', ColorToString(as_pm.ColorFore));
WriteString('Config', 'tmpColour', ColorToString(as_tmp.ColorFore));
WriteString('Config', 'humColour', ColorToString(as_hum.ColorFore));
WriteString('Config', 'co2Colour', ColorToString(as_co2.ColorFore));
WriteString('Config', 'vocColour', ColorToString(as_voc.ColorFore));
WriteString('Config', 'allpolluColour', ColorToString(as_allpollu.ColorFore));
// Max and Min
WriteFloat('Config', 'pmMinValue', as_pm.ValueMin);
WriteFloat('Config', 'pmMaxValue', as_pm.ValueMax);
WriteFloat('Config', 'tmpMinValue', as_tmp.ValueMin);
WriteFloat('Config', 'tmpMaxValue', as_tmp.ValueMax);
WriteFloat('Config', 'humMinValue', as_hum.ValueMin);
WriteFloat('Config', 'humMaxValue', as_hum.ValueMax);
WriteFloat('Config', 'co2MinValue', as_co2.ValueMin);
WriteFloat('Config', 'co2MaxValue', as_co2.ValueMax);
WriteFloat('Config', 'vocMinValue', as_voc.ValueMin);
WriteFloat('Config', 'vocMaxValue', as_voc.ValueMax);
WriteFloat('Config', 'allpolluMinValue', as_allpollu.ValueMin);
WriteFloat('Config', 'allpolluMaxValue', as_allpollu.ValueMax);
WriteBool('Config', 'DisplayYellowLines', bDisplayYellowLines);
WriteBool('Config', 'DisplayRedLines', bDisplayRedLines);
// Triggers
WriteBool('Config', 'UseTriggers', UseTriggers);
PlainTextMode := False;
end;
end;
// Max and Min
INI.WriteFloat('Config', 'pmMinValue', as_pm.ValueMin);
INI.WriteFloat('Config', 'pmMaxValue', as_pm.ValueMax);
INI.WriteFloat('Config', 'tmpMinValue', as_tmp.ValueMin);
INI.WriteFloat('Config', 'tmpMaxValue', as_tmp.ValueMax);
INI.WriteFloat('Config', 'humMinValue', as_hum.ValueMin);
INI.WriteFloat('Config', 'humMaxValue', as_hum.ValueMax);
INI.WriteFloat('Config', 'co2MinValue', as_co2.ValueMin);
INI.WriteFloat('Config', 'co2MaxValue', as_co2.ValueMax);
INI.WriteFloat('Config', 'vocMinValue', as_voc.ValueMin);
INI.WriteFloat('Config', 'vocMaxValue', as_voc.ValueMax);
INI.WriteFloat('Config', 'allpolluMinValue', as_allpollu.ValueMin);
INI.WriteFloat('Config', 'allpolluMaxValue', as_allpollu.ValueMax);
INI.WriteBool('Config', 'DisplayYellowLines', bDisplayYellowLines);
INI.WriteBool('Config', 'DisplayRedLines', bDisplayRedLines);
INI.PlainTextMode := False;
procedure Tmainform.SetMinMaxTriggers;
// Ensure Triggers are in range of High & Low guage values
begin
if (UseTriggers = False) then
exit;
if as_pm.ValueMin > GetLowTrigger(C_PM) then
SetLowTrigger(C_PM, as_pm.ValueMin);
if as_pm.ValueMax < GetHighTrigger(C_PM) then
SetHighTrigger(C_PM, as_pm.ValueMax);
if as_tmp.ValueMin > GetLowTrigger(C_TMP) then
SetLowTrigger(C_TMP, as_tmp.ValueMin);
if as_tmp.ValueMax < GetHighTrigger(C_TMP) then
SetHighTrigger(C_TMP, as_tmp.ValueMax);
if as_hum.ValueMin > GetLowTrigger(C_HUM) then
SetLowTrigger(C_HUM, as_hum.ValueMin);
if as_hum.ValueMax < GetHighTrigger(C_HUM) then
SetHighTrigger(C_HUM, as_hum.ValueMax);
if as_co2.ValueMin > GetLowTrigger(C_CO2) then
SetLowTrigger(C_CO2, as_co2.ValueMin);
if as_co2.ValueMax < GetHighTrigger(C_CO2) then
SetHighTrigger(C_CO2, as_co2.ValueMax);
if as_voc.ValueMin > GetLowTrigger(C_VOC) then
SetLowTrigger(C_VOC, as_voc.ValueMin);
if as_voc.ValueMax < GetHighTrigger(C_VOC) then
SetHighTrigger(C_VOC, as_voc.ValueMax);
if as_allpollu.ValueMin > GetLowTrigger(C_ALLPOLLU) then
SetLowTrigger(C_ALLPOLLU, as_allpollu.ValueMin);
if as_allpollu.ValueMax < GetHighTrigger(C_ALLPOLLU) then
SetHighTrigger(C_ALLPOLLU, as_allpollu.ValueMax);
end;
procedure Tmainform.LoadConfig;
@ -447,6 +492,8 @@ begin
as_voc.ValueMax := INI.ReadFloat('Config', 'vocMaxValue', MAX_VOC);
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);
INI.PlainTextMode := False;
end;
@ -565,7 +612,11 @@ begin
not mnu_options_triggersActivateTriggers.Checked;
UseTriggers := mnu_options_triggersActivateTriggers.Checked;
if UseTriggers then
mnu_options_triggersActivateTriggers.Caption := 'Set Triggers Off'
begin
mnu_options_triggersActivateTriggers.Caption := 'Set Triggers Off';
LoadTriggers;
SetMinMaxTriggers
end
else
mnu_options_triggersActivateTriggers.Caption := 'Set Triggers On';
end;
@ -812,7 +863,41 @@ begin
SetYellowRecommendedLevels;
end;
end;
procedure Tmainform.DoHighTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant);
begin
Case iSensorNum of
C_PM:as_pm.Color:=clYellow;
C_TMP:as_tmp.Color:=clYellow;
C_HUM:as_hum.Color:=clYellow;
C_CO2:as_co2.Color:=clYellow;
C_VOC:as_voc.Color:=clYellow;
C_ALLPOLLU:as_allpollu.Color:=clYellow;
end;
end;
procedure Tmainform.DoLowTriggerAlert(Const iSensorNum:Integer;Const aValue:Variant);
begin
Case iSensorNum of
C_PM:as_pm.Color:=clAqua;
C_TMP:as_tmp.Color:=clAqua;
C_HUM:as_hum.Color:=clAqua;
C_CO2:as_co2.Color:=clAqua;
C_VOC:as_voc.Color:=clAqua;
C_ALLPOLLU:as_allpollu.Color:=clAqua;
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.DisplayReadings;
var
iCount: integer;
@ -841,19 +926,28 @@ begin
// Look for alerts in each sensor
for iCount := C_PM to C_ALLPOLLU do
if AlertRec[iCount].AlertTriggered then
begin
// Alert found. High or low?
if AlertRec[iCount].AlertType = at_high then
if AlertRec[iCount].AlertType = 0 then
begin
// A high alert - do something
DoHighTriggerAlert(iCount,AlertRec[iCount].AlertValue);
{
ShowMessageFmt('High alert member %d (value %f) exceeded',
[iCount, double(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)]);
}
end;
end
else RestoreNormalColour(iCount);
except
raise Exception.Create('Unable to process triggers in DisplayReadings');
end;