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

View File

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

View File

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