Updated Foobot Interregator to V0.1.1.0

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5575 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
gbamber
2016-12-30 09:34:07 +00:00
parent 0dcb581438
commit 29084dcf3d
9 changed files with 403 additions and 337 deletions

View File

@ -32,7 +32,7 @@ interface
uses
Classes, SysUtils, Dialogs,
foobot_httpclient, foobot_objects, fpjson, fpjsonrtti, base64, variants,
DateUtils,INIFiles;
DateUtils, INIFiles;
const
FOOBOT_USER_URL = 'https://api.foobot.io/v2/user/%s/login/';
@ -44,7 +44,7 @@ const
type
TDataFetchType = (dfLast, dfStartEnd);
TSensorType = (st_time,st_pm,st_tmp,st_hum,st_co2,st_voc,st_allpollu);
TSensorType = (st_time, st_pm, st_tmp, st_hum, st_co2, st_voc, st_allpollu);
function EncodeStringBase64(const s: string): string;
function FetchAuthenticationKey(aUsername, aUserPassword: string): boolean;
@ -65,19 +65,19 @@ function FoobotDataObjectToArrays: boolean;
// Utility functions
function ResetArrays: boolean;
function ResetObjects: boolean;
Function ResetHighLows:Boolean;
function SaveHighLows:Boolean;
Function LoadHighLows:Boolean;
function ResetHighLows: boolean;
function SaveHighLows: boolean;
function LoadHighLows: boolean;
var
HttpClient: TFPHTTPClient;
FoobotIdentityObject: TFoobotIdentityObject;
FoobotDataObject: TFoobotDataObject;
sAuthenticationKey: string;
SensorType:TSensorType;
SaveLoadHighLows:Boolean;
TheCurrentFoobot:Integer;
HLINI:TIniFile;
SensorType: TSensorType;
SaveLoadHighLows: boolean;
TheCurrentFoobot: integer;
HLINI: TIniFile;
// Easier access to datapoints
// Call FoobotDataObjectToArrays to populate them
FoobotData_time: array of TDateTime;
@ -88,96 +88,101 @@ var
FoobotData_voc: array of integer;
FoobotData_allpollu: array of double;
// Set in FoobotDataObjectToArrays
FoobotDataHighs:Array[0..HIGHLOWMAX]of Variant;
FoobotDataLows:Array[0..HIGHLOWMAX]of Variant;
FoobotDataHighTimes:Array[0..HIGHLOWMAX]of Variant;
FoobotDataLowTimes:Array[0..HIGHLOWMAX]of Variant;
FoobotDataHighs: array[0..HIGHLOWMAX] of variant;
FoobotDataLows: array[0..HIGHLOWMAX] of variant;
FoobotDataHighTimes: array[0..HIGHLOWMAX] of variant;
FoobotDataLowTimes: array[0..HIGHLOWMAX] of variant;
implementation
function SaveHighLows:Boolean;
Var sFoobotName:String;
function SaveHighLows: boolean;
var
sFoobotName: string;
begin
If SaveLoadHighLows=FALSE then Exit(FALSE);
sFoobotName:=FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].name;
If Not Assigned(HLINI) then
HLINI:=TIniFile.Create(ChangeFileExt(GetAppConfigFile(False),'.ini'));
if SaveLoadHighLows = False then
Exit(False);
sFoobotName := FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].Name;
if not Assigned(HLINI) then
HLINI := TIniFile.Create(ChangeFileExt(GetAppConfigFile(False), '.ini'));
// Store current Foobot info
HLINI.WriteInteger('Foobot','CurrentFoobot',TheCurrentFoobot);
HLINI.WriteString('Foobot','CurrentFoobotName',sFoobotName);
HLINI.WriteInteger('Foobot', 'CurrentFoobot', TheCurrentFoobot);
HLINI.WriteString('Foobot', 'CurrentFoobotName', sFoobotName);
// Particulates
HLINI.WriteFloat(sFoobotName,'pmHigh',Double(FoobotDataHighs[1]));
HLINI.WriteDateTime(sFoobotName,'pmHighTime',TDateTime(FoobotDataHighTimes[1]));
HLINI.WriteFloat(sFoobotName,'pmLow',Double(FoobotDataLows[1]));
HLINI.WriteDateTime(sFoobotName,'pmLowTime',TDateTime(FoobotDataLowTimes[1]));
HLINI.WriteFloat(sFoobotName, 'pmHigh', double(FoobotDataHighs[1]));
HLINI.WriteDateTime(sFoobotName, 'pmHighTime', TDateTime(FoobotDataHighTimes[1]));
HLINI.WriteFloat(sFoobotName, 'pmLow', double(FoobotDataLows[1]));
HLINI.WriteDateTime(sFoobotName, 'pmLowTime', TDateTime(FoobotDataLowTimes[1]));
// Temp
HLINI.WriteFloat(sFoobotName,'tmpHigh',Double(FoobotDataHighs[2]));
HLINI.WriteDateTime(sFoobotName,'tmpHighTime',TDateTime(FoobotDataHighTimes[2]));
HLINI.WriteFloat(sFoobotName,'tmpLow',Double(FoobotDataLows[2]));
HLINI.WriteDateTime(sFoobotName,'tmpLowTime',TDateTime(FoobotDataLowTimes[2]));
HLINI.WriteFloat(sFoobotName, 'tmpHigh', double(FoobotDataHighs[2]));
HLINI.WriteDateTime(sFoobotName, 'tmpHighTime', TDateTime(FoobotDataHighTimes[2]));
HLINI.WriteFloat(sFoobotName, 'tmpLow', double(FoobotDataLows[2]));
HLINI.WriteDateTime(sFoobotName, 'tmpLowTime', TDateTime(FoobotDataLowTimes[2]));
// Humidity
HLINI.WriteFloat(sFoobotName,'humHigh',Double(FoobotDataHighs[3]));
HLINI.WriteDateTime(sFoobotName,'humHighTime',TDateTime(FoobotDataHighTimes[3]));
HLINI.WriteFloat(sFoobotName,'humLow',Double(FoobotDataLows[3]));
HLINI.WriteDateTime(sFoobotName,'humLowTime',TDateTime(FoobotDataLowTimes[3]));
HLINI.WriteFloat(sFoobotName, 'humHigh', double(FoobotDataHighs[3]));
HLINI.WriteDateTime(sFoobotName, 'humHighTime', TDateTime(FoobotDataHighTimes[3]));
HLINI.WriteFloat(sFoobotName, 'humLow', double(FoobotDataLows[3]));
HLINI.WriteDateTime(sFoobotName, 'humLowTime', TDateTime(FoobotDataLowTimes[3]));
// CO2
HLINI.WriteInteger(sFoobotName,'co2High',Integer(FoobotDataHighs[4]));
HLINI.WriteDateTime(sFoobotName,'co2HighTime',TDateTime(FoobotDataHighTimes[4]));
HLINI.WriteInteger(sFoobotName,'co2Low',Integer(FoobotDataLows[4]));
HLINI.WriteDateTime(sFoobotName,'co2LowTime',TDateTime(FoobotDataLowTimes[4]));
HLINI.WriteInteger(sFoobotName, 'co2High', integer(FoobotDataHighs[4]));
HLINI.WriteDateTime(sFoobotName, 'co2HighTime', TDateTime(FoobotDataHighTimes[4]));
HLINI.WriteInteger(sFoobotName, 'co2Low', integer(FoobotDataLows[4]));
HLINI.WriteDateTime(sFoobotName, 'co2LowTime', TDateTime(FoobotDataLowTimes[4]));
// Volatile Compounds
HLINI.WriteInteger(sFoobotName,'vocHigh',Integer(FoobotDataHighs[5]));
HLINI.WriteDateTime(sFoobotName,'vocHighTime',TDateTime(FoobotDataHighTimes[5]));
HLINI.WriteInteger(sFoobotName,'vocLow',Integer(FoobotDataLows[5]));
HLINI.WriteDateTime(sFoobotName,'vocLowTime',TDateTime(FoobotDataLowTimes[5]));
HLINI.WriteInteger(sFoobotName, 'vocHigh', integer(FoobotDataHighs[5]));
HLINI.WriteDateTime(sFoobotName, 'vocHighTime', TDateTime(FoobotDataHighTimes[5]));
HLINI.WriteInteger(sFoobotName, 'vocLow', integer(FoobotDataLows[5]));
HLINI.WriteDateTime(sFoobotName, 'vocLowTime', TDateTime(FoobotDataLowTimes[5]));
// All Pollution
HLINI.WriteFloat(sFoobotName,'allpolluHigh',Double(FoobotDataHighs[6]));
HLINI.WriteDateTime(sFoobotName,'allpolluHighTime',TDateTime(FoobotDataHighTimes[6]));
HLINI.WriteFloat(sFoobotName,'allpolluLow',Double(FoobotDataLows[6]));
HLINI.WriteDateTime(sFoobotName,'allpolluLowTime',TDateTime(FoobotDataLowTimes[6]));
HLINI.WriteFloat(sFoobotName, 'allpolluHigh', double(FoobotDataHighs[6]));
HLINI.WriteDateTime(sFoobotName, 'allpolluHighTime', TDateTime(FoobotDataHighTimes[6]));
HLINI.WriteFloat(sFoobotName, 'allpolluLow', double(FoobotDataLows[6]));
HLINI.WriteDateTime(sFoobotName, 'allpolluLowTime', TDateTime(FoobotDataLowTimes[6]));
end;
Function LoadHighLows:Boolean;
Var sFoobotName:String;
function LoadHighLows: boolean;
var
sFoobotName: string;
begin
If SaveLoadHighLows=FALSE then Exit(FALSE);
sFoobotName:=FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].name;
If Not Assigned(HLINI) then
HLINI:=TIniFile.Create(ChangeFileExt(GetAppConfigFile(False),'.ini'));
if SaveLoadHighLows = False then
Exit(False);
sFoobotName := FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].Name;
if not Assigned(HLINI) then
HLINI := TIniFile.Create(ChangeFileExt(GetAppConfigFile(False), '.ini'));
// Make sure the High-Lows are for the current Foobot
if (HLINI.ReadString('Foobot','CurrentFoobotName','unknown') <> sFoobotName)
then Exit(FALSE);
if (HLINI.ReadString('Foobot', 'CurrentFoobotName', 'unknown') <> sFoobotName) then
Exit(False);
// Particulates
FoobotDataHighs[1]:=HLINI.ReadFloat(sFoobotName,'pmHigh',0);
FoobotDataHighTimes[1]:=HLINI.ReadDateTime(sFoobotName,'pmHighTime',Now);
FoobotDataLows[1]:=HLINI.ReadFloat(sFoobotName,'pmLow',0);
FoobotDataLowTimes[1]:=HLINI.ReadDateTime(sFoobotName,'pmLowTime',Now);
FoobotDataHighs[1] := HLINI.ReadFloat(sFoobotName, 'pmHigh', 0);
FoobotDataHighTimes[1] := HLINI.ReadDateTime(sFoobotName, 'pmHighTime', Now);
FoobotDataLows[1] := HLINI.ReadFloat(sFoobotName, 'pmLow', 0);
FoobotDataLowTimes[1] := HLINI.ReadDateTime(sFoobotName, 'pmLowTime', Now);
// Temp
FoobotDataHighs[2]:=HLINI.ReadFloat(sFoobotName,'tmpHigh',0);
FoobotDataHighTimes[2]:=HLINI.ReadDateTime(sFoobotName,'tmpHighTime',Now);
FoobotDataLows[2]:=HLINI.ReadFloat(sFoobotName,'tmpLow',0);
FoobotDataLowTimes[2]:=HLINI.ReadDateTime(sFoobotName,'tmpLowTime',Now);
FoobotDataHighs[2] := HLINI.ReadFloat(sFoobotName, 'tmpHigh', 0);
FoobotDataHighTimes[2] := HLINI.ReadDateTime(sFoobotName, 'tmpHighTime', Now);
FoobotDataLows[2] := HLINI.ReadFloat(sFoobotName, 'tmpLow', 0);
FoobotDataLowTimes[2] := HLINI.ReadDateTime(sFoobotName, 'tmpLowTime', Now);
// Humidity
FoobotDataHighs[3]:=HLINI.ReadFloat(sFoobotName,'humHigh',0);
FoobotDataHighTimes[3]:=HLINI.ReadDateTime(sFoobotName,'humHighTime',Now);
FoobotDataLows[3]:=HLINI.ReadFloat(sFoobotName,'humLow',0);
FoobotDataLowTimes[3]:=HLINI.ReadDateTime(sFoobotName,'humLowTime',Now);
FoobotDataHighs[3] := HLINI.ReadFloat(sFoobotName, 'humHigh', 0);
FoobotDataHighTimes[3] := HLINI.ReadDateTime(sFoobotName, 'humHighTime', Now);
FoobotDataLows[3] := HLINI.ReadFloat(sFoobotName, 'humLow', 0);
FoobotDataLowTimes[3] := HLINI.ReadDateTime(sFoobotName, 'humLowTime', Now);
// CO2
FoobotDataHighs[4]:=HLINI.ReadInteger(sFoobotName,'co2High',0);
FoobotDataHighTimes[4]:=HLINI.ReadDateTime(sFoobotName,'co2HighTime',Now);
FoobotDataLows[4]:=HLINI.ReadInteger(sFoobotName,'co2Low',0);
FoobotDataLowTimes[4]:=HLINI.ReadDateTime(sFoobotName,'co2LowTime',Now);
FoobotDataHighs[4] := HLINI.ReadInteger(sFoobotName, 'co2High', 0);
FoobotDataHighTimes[4] := HLINI.ReadDateTime(sFoobotName, 'co2HighTime', Now);
FoobotDataLows[4] := HLINI.ReadInteger(sFoobotName, 'co2Low', 0);
FoobotDataLowTimes[4] := HLINI.ReadDateTime(sFoobotName, 'co2LowTime', Now);
// Volatile Compounds
FoobotDataHighs[5]:=HLINI.ReadInteger(sFoobotName,'vocHigh',0);
FoobotDataHighTimes[5]:=HLINI.ReadDateTime(sFoobotName,'vocHighTime',Now);
FoobotDataLows[5]:=HLINI.ReadInteger(sFoobotName,'vocLow',0);
FoobotDataLowTimes[5]:=HLINI.ReadDateTime(sFoobotName,'vocLowTime',Now);
FoobotDataHighs[5] := HLINI.ReadInteger(sFoobotName, 'vocHigh', 0);
FoobotDataHighTimes[5] := HLINI.ReadDateTime(sFoobotName, 'vocHighTime', Now);
FoobotDataLows[5] := HLINI.ReadInteger(sFoobotName, 'vocLow', 0);
FoobotDataLowTimes[5] := HLINI.ReadDateTime(sFoobotName, 'vocLowTime', Now);
// All Pollution
FoobotDataHighs[6]:=HLINI.ReadFloat(sFoobotName,'allpolluHigh',0);
FoobotDataHighTimes[6]:=HLINI.ReadDateTime(sFoobotName,'allpolluHighTime',Now);
FoobotDataLows[6]:=HLINI.ReadFloat(sFoobotName,'allpolluLow',0);
FoobotDataLowTimes[6]:=HLINI.ReadDateTime(sFoobotName,'allpolluLowTime',Now);
FoobotDataHighs[6] := HLINI.ReadFloat(sFoobotName, 'allpolluHigh', 0);
FoobotDataHighTimes[6] := HLINI.ReadDateTime(sFoobotName, 'allpolluHighTime', Now);
FoobotDataLows[6] := HLINI.ReadFloat(sFoobotName, 'allpolluLow', 0);
FoobotDataLowTimes[6] := HLINI.ReadDateTime(sFoobotName, 'allpolluLowTime', Now);
end;
// ToDo: Multiple Foobots?
@ -190,24 +195,25 @@ var
sStart, sEnd: string;
}
iUnixSecs: int64;
// ========= Internal routines start ===========
procedure SetHigh(iMember:Integer;aValue:Variant;aDateTime:TDateTime);
begin
If aValue > FoobotDataHighs[iMember] then
begin
FoobotDataHighs[iMember]:=aValue;
FoobotDataHighTimes[iMember]:=aDateTime;
end;
end;
procedure SetLow(iMember:Integer;aValue:Variant;aDateTime:TDateTime);
begin
If (aValue < FoobotDataLows[iMember]) OR (FoobotDataLows[iMember] = 0) then
begin
FoobotDataLows[iMember]:=aValue;
FoobotDataLowTimes[iMember]:=aDateTime;
end;
end;
// ========== Internal routines end =============
// ========= Internal routines start ===========
procedure SetHigh(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
if aValue > FoobotDataHighs[iMember] then
begin
FoobotDataHighs[iMember] := aValue;
FoobotDataHighTimes[iMember] := aDateTime;
end;
end;
procedure SetLow(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
if (aValue < FoobotDataLows[iMember]) or (FoobotDataLows[iMember] = 0) then
begin
FoobotDataLows[iMember] := aValue;
FoobotDataLowTimes[iMember] := aDateTime;
end;
end;
// ========== Internal routines end =============
begin
ResetArrays;
Result := True;
@ -237,57 +243,60 @@ begin
begin
SetLength(FoobotData_pm, K + 1);
FoobotData_pm[K] := double(MyDataPoint);
SetHigh(J,FoobotData_pm[K],FoobotData_time[K]);
SetLow(J,FoobotData_pm[K],FoobotData_time[K]);
SetHigh(J, FoobotData_pm[K], FoobotData_time[K]);
SetLow(J, FoobotData_pm[K], FoobotData_time[K]);
end;
2: // Temperature
begin
SetLength(FoobotData_tmp, K + 1);
FoobotData_tmp[K] := double(MyDataPoint);
SetHigh(J,FoobotData_tmp[K],FoobotData_time[K]);
SetLow(J,FoobotData_tmp[K],FoobotData_time[K]);
SetHigh(J, FoobotData_tmp[K], FoobotData_time[K]);
SetLow(J, FoobotData_tmp[K], FoobotData_time[K]);
end;
3: // Humidity
begin
SetLength(FoobotData_hum, K + 1);
FoobotData_hum[K] := double(MyDataPoint);
SetHigh(J,FoobotData_hum[K],FoobotData_time[K]);
SetLow(J,FoobotData_hum[K],FoobotData_time[K]);
SetHigh(J, FoobotData_hum[K], FoobotData_time[K]);
SetLow(J, FoobotData_hum[K], FoobotData_time[K]);
end;
4: // CO2
begin
SetLength(FoobotData_co2, K + 1);
FoobotData_co2[K] := integer(MyDataPoint);
SetHigh(J,FoobotData_co2[K],FoobotData_time[K]);
SetLow(J,FoobotData_co2[K],FoobotData_time[K]);
SetHigh(J, FoobotData_co2[K], FoobotData_time[K]);
SetLow(J, FoobotData_co2[K], FoobotData_time[K]);
end;
5: // Volatile compounds
begin
SetLength(FoobotData_voc, K + 1);
FoobotData_voc[K] := integer(MyDataPoint);
SetHigh(J,FoobotData_voc[K],FoobotData_time[K]);
SetLow(J,FoobotData_voc[K],FoobotData_time[K]);
SetHigh(J, FoobotData_voc[K], FoobotData_time[K]);
SetLow(J, FoobotData_voc[K], FoobotData_time[K]);
end;
6: // All Pollution
begin
SetLength(FoobotData_allpollu, K + 1);
FoobotData_allpollu[K] := double(MyDataPoint);
SetHigh(J,FoobotData_allpollu[K],FoobotData_time[K]);
SetLow(J,FoobotData_allpollu[K],FoobotData_time[K]);
SetHigh(J, FoobotData_allpollu[K], FoobotData_time[K]);
SetLow(J, FoobotData_allpollu[K], FoobotData_time[K]);
end;
end; // of Case
end;
end;
SaveHighLows;
end;
Function ResetHighLows:Boolean;
Var iCount:Integer;
function ResetHighLows: boolean;
var
iCount: integer;
begin
For iCount:=0 to HIGHLOWMAX do begin
FoobotDataHighs[iCount]:=0;
FoobotDataLows[iCount]:=0;
for iCount := 0 to HIGHLOWMAX do
begin
FoobotDataHighs[iCount] := 0;
FoobotDataLows[iCount] := 0;
end;
Result:=TRUE;
Result := True;
end;
function ResetArrays: boolean;
@ -352,6 +361,7 @@ function FetchAuthenticationKey(aUsername, aUserPassword: string): boolean;
var
sRequestURL: string;
iCount: integer;
JSON: TJSONStringType;
begin
// FOOBOT_USER_URL = 'http://api.foobot.io/v2/user/%s/login/';
// sAuthenticationKey
@ -361,17 +371,22 @@ begin
with httpclient do
begin
ResponseHeaders.NameValueSeparator := ':';
AddHeader('Authorization', EncodeStringBase64(aUsername + ':' + aUserPassword));
sRequestURL := Format(FOOBOT_USER_URL, [aUsername]);
Get(sRequestURL);
if ResponseStatusCode <> 200 then
begin
ShowMessageFmt('Failed - Foobot server refused with code %d',
[ResponseStatusCode]);
Exit(False);
AddHeader('password', aUserPassword);
// ShowMessage(EncodeURLElement(aUsername));
sRequestURL := Format(FOOBOT_USER_URL, [EncodeURLElement(aUsername)]);
try
JSON := Get(sRequestURL);
if ResponseStatusCode <> 200 then
begin
ShowMessageFmt('Failed - Foobot server refused with code %d',
[ResponseStatusCode]);
Exit(False);
end;
finally
ShowMessage(JSON);
for iCount := 0 to Pred(ResponseHeaders.Count) do
ShowMessage(ResponseHeaders[iCount]);
end;
for iCount := 0 to ResponseHeaders.Count do
ShowMessage(ResponseHeaders[iCount]);
Result := True;
end;
finally
@ -386,7 +401,7 @@ var
DeStreamer: TJSONDeStreamer;
begin
Result := True; // Assume success: Look for failure
sAuthenticationKey:=aSecretKey;
sAuthenticationKey := aSecretKey;
try
with httpclient do
begin
@ -417,7 +432,8 @@ begin
DeStreamer.JSONToObject(JSON, FoobotIdentityObject.FoobotIdentityList);
except
On E: Exception do
showmessagefmt('Cannot retieve data - Foobot server refused with code %s', [E.Message]);
showmessagefmt('Cannot retieve data - Foobot server refused with code %s',
[E.Message]);
On E: Exception do
Result := False;
end;
@ -439,7 +455,7 @@ var
//FOOBOT_DATA_START_FINISH_URL = 'http://api.foobot.io/v2/device/%s/datapoint/%s/%s/%s/';
begin
Result := True; // Assume success: Look for failure
TheCurrentFoobot:=iCurrentFoobot;
TheCurrentFoobot := iCurrentFoobot;
// Checks for integrity
if (FoobotIdentityObject.FoobotIdentityList.Count = 0) then
Exit(False);
@ -511,13 +527,14 @@ initialization
HttpClient := TFPHTTPClient.Create(nil);
FoobotIdentityObject := TFoobotIdentityObject.Create;
FoobotDataObject := TFoobotDataObject.Create;
SaveLoadHighLows:=TRUE;
TheCurrentFoobot:=0;
SaveLoadHighLows := True;
TheCurrentFoobot := 0;
end;
finalization
begin
If Assigned(HLINI) then FreeAndNil(HLINI);
if Assigned(HLINI) then
FreeAndNil(HLINI);
FreeAndNil(HttpClient);
FreeAndNil(FoobotIdentityObject);
FreeAndNil(FoobotDataObject);

View File

@ -18,6 +18,7 @@
<VersionInfo>
<UseVersionInfo Value="True"/>
<MinorVersionNr Value="1"/>
<RevisionNr Value="1"/>
<StringTable Comments="Uses foobot public API" LegalCopyright="(c)2016 minesadorada@charcodelvalle.com" ProductName="fpc/Lazarus" ProductVersion="3.1.1.0"/>
</VersionInfo>
<BuildModes Count="6">
@ -127,6 +128,9 @@
</Linking>
<Other>
<CustomOptions Value="-FcUTF8"/>
<OtherDefines Count="1">
<Define0 Value="DEBUG"/>
</OtherDefines>
</Other>
</CompilerOptions>
</Item4>

View File

@ -3,7 +3,7 @@
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="10"/>
<BuildModes Active="Win64"/>
<BuildModes Active="Linux64"/>
<Units Count="25">
<Unit0>
<Filename Value="foobot.lpr"/>
@ -11,7 +11,7 @@
<EditorIndex Value="7"/>
<TopLine Value="6"/>
<CursorPos Y="44"/>
<UsageCount Value="93"/>
<UsageCount Value="95"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
@ -20,10 +20,9 @@
<ComponentName Value="mainform"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<TopLine Value="174"/>
<CursorPos X="31" Y="257"/>
<UsageCount Value="93"/>
<TopLine Value="91"/>
<CursorPos X="47" Y="115"/>
<UsageCount Value="95"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
@ -33,7 +32,7 @@
<EditorIndex Value="2"/>
<TopLine Value="80"/>
<CursorPos Y="101"/>
<UsageCount Value="53"/>
<UsageCount Value="55"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
@ -41,8 +40,8 @@
<IsPartOfProject Value="True"/>
<EditorIndex Value="5"/>
<TopLine Value="348"/>
<CursorPos X="17" Y="369"/>
<UsageCount Value="55"/>
<CursorPos X="26" Y="356"/>
<UsageCount Value="57"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
@ -51,9 +50,11 @@
<ComponentName Value="loginform"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="6"/>
<CursorPos Y="92"/>
<UsageCount Value="47"/>
<TopLine Value="19"/>
<CursorPos X="20" Y="29"/>
<UsageCount Value="49"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit4>
@ -66,7 +67,7 @@
<EditorIndex Value="3"/>
<TopLine Value="8"/>
<CursorPos X="30" Y="51"/>
<UsageCount Value="46"/>
<UsageCount Value="48"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit5>
@ -74,9 +75,9 @@
<Filename Value="foobot_utility.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="1"/>
<TopLine Value="27"/>
<CursorPos X="50" Y="52"/>
<UsageCount Value="24"/>
<TopLine Value="362"/>
<CursorPos X="44" Y="374"/>
<UsageCount Value="26"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
@ -84,7 +85,7 @@
<EditorIndex Value="4"/>
<TopLine Value="262"/>
<CursorPos X="47" Y="232"/>
<UsageCount Value="22"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
</Unit7>
<Unit8>
@ -215,124 +216,124 @@
</OtherDefines>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="umainform.pas"/>
<Caret Line="290" TopLine="271"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="8" Column="46" TopLine="4"/>
</Position1>
<Position2>
<Filename Value="umainform.pas"/>
<Caret Line="281" TopLine="274"/>
<Caret Line="152" Column="3" TopLine="127"/>
</Position2>
<Position3>
<Filename Value="umainform.pas"/>
<Caret Line="282" TopLine="268"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="8" Column="36"/>
</Position3>
<Position4>
<Filename Value="umainform.pas"/>
<Caret Line="36" Column="31" TopLine="16"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="7" Column="29" TopLine="2"/>
</Position4>
<Position5>
<Filename Value="umainform.pas"/>
<Caret Line="242" Column="9" TopLine="240"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="22" Column="99"/>
</Position5>
<Position6>
<Filename Value="umainform.pas"/>
<Caret Line="218" Column="11" TopLine="214"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="23" Column="21"/>
</Position6>
<Position7>
<Filename Value="foobot_utility.pas"/>
<Caret Line="8" Column="46" TopLine="4"/>
<Caret Line="74" Column="15" TopLine="72"/>
</Position7>
<Position8>
<Filename Value="umainform.pas"/>
<Caret Line="152" Column="3" TopLine="127"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="88" Column="75" TopLine="65"/>
</Position8>
<Position9>
<Filename Value="foobot_utility.pas"/>
<Caret Line="8" Column="36"/>
<Filename Value="umainform.pas"/>
<Caret Line="279" TopLine="254"/>
</Position9>
<Position10>
<Filename Value="foobot_utility.pas"/>
<Caret Line="7" Column="29" TopLine="2"/>
<Filename Value="umainform.pas"/>
<Caret Line="246" Column="42" TopLine="230"/>
</Position10>
<Position11>
<Filename Value="foobot_utility.pas"/>
<Caret Line="22" Column="99"/>
<Filename Value="umainform.pas"/>
<Caret Line="245" Column="32" TopLine="223"/>
</Position11>
<Position12>
<Filename Value="foobot_utility.pas"/>
<Caret Line="23" Column="21"/>
<Filename Value="umainform.pas"/>
<Caret Line="282" TopLine="275"/>
</Position12>
<Position13>
<Filename Value="foobot_utility.pas"/>
<Caret Line="74" Column="15" TopLine="72"/>
<Caret Line="28" TopLine="10"/>
</Position13>
<Position14>
<Filename Value="foobot_utility.pas"/>
<Caret Line="88" Column="75" TopLine="65"/>
<Filename Value="umainform.pas"/>
<Caret Line="107" Column="21" TopLine="78"/>
</Position14>
<Position15>
<Filename Value="umainform.pas"/>
<Caret Line="279" TopLine="254"/>
<Caret Line="35" Column="47" TopLine="28"/>
</Position15>
<Position16>
<Filename Value="umainform.pas"/>
<Caret Line="246" Column="42" TopLine="230"/>
<Filename Value="foobot.lpr"/>
<Caret Line="44" TopLine="6"/>
</Position16>
<Position17>
<Filename Value="umainform.pas"/>
<Caret Line="245" Column="32" TopLine="223"/>
<Filename Value="foobot_objects.pas"/>
<Caret Line="101" TopLine="80"/>
</Position17>
<Position18>
<Filename Value="umainform.pas"/>
<Caret Line="282" TopLine="275"/>
<Caret Line="216" Column="26" TopLine="211"/>
</Position18>
<Position19>
<Filename Value="foobot_utility.pas"/>
<Caret Line="28" TopLine="10"/>
<Filename Value="umainform.pas"/>
<Caret Line="90" TopLine="72"/>
</Position19>
<Position20>
<Filename Value="umainform.pas"/>
<Caret Line="107" Column="21" TopLine="78"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="40" Column="56" TopLine="18"/>
</Position20>
<Position21>
<Filename Value="umainform.pas"/>
<Caret Line="35" Column="47" TopLine="28"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="72" Column="56" TopLine="50"/>
</Position21>
<Position22>
<Filename Value="foobot.lpr"/>
<Caret Line="44" TopLine="6"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="86" Column="45" TopLine="63"/>
</Position22>
<Position23>
<Filename Value="foobot_objects.pas"/>
<Caret Line="101" TopLine="80"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="50" TopLine="27"/>
</Position23>
<Position24>
<Filename Value="umainform.pas"/>
<Caret Line="216" Column="26" TopLine="211"/>
<Caret Line="257" Column="31" TopLine="174"/>
</Position24>
<Position25>
<Filename Value="umainform.pas"/>
<Caret Line="90" TopLine="72"/>
<Filename Value="foobot_utility.pas"/>
<Caret Line="364" Column="43" TopLine="351"/>
</Position25>
<Position26>
<Filename Value="foobot_utility.pas"/>
<Caret Line="40" Column="56" TopLine="18"/>
<Caret Line="365" Column="74" TopLine="343"/>
</Position26>
<Position27>
<Filename Value="foobot_utility.pas"/>
<Caret Line="72" Column="56" TopLine="50"/>
<Caret Line="375" TopLine="342"/>
</Position27>
<Position28>
<Filename Value="foobot_utility.pas"/>
<Caret Line="86" Column="45" TopLine="63"/>
<Filename Value="ulogin.pas"/>
<Caret Line="92"/>
</Position28>
<Position29>
<Filename Value="foobot_utility.pas"/>
<Caret Line="50" TopLine="27"/>
<Filename Value="ulogin.pas"/>
<Caret Line="71" Column="19" TopLine="46"/>
</Position29>
<Position30>
<Filename Value="umainform.pas"/>
<Caret Line="85" TopLine="193"/>
<Filename Value="ulogin.pas"/>
<Caret Line="29" Column="20" TopLine="19"/>
</Position30>
</JumpHistory>
</ProjectSession>

View File

@ -1,6 +1,6 @@
unit foobot_utility;
{ Foobot Interrogator Utilities
{ Foobot Utilities
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
@ -32,7 +32,7 @@ interface
uses
Classes, SysUtils, Dialogs,
foobot_httpclient, foobot_objects, fpjson, fpjsonrtti, base64, variants,
DateUtils,INIFiles;
DateUtils, INIFiles;
const
FOOBOT_USER_URL = 'https://api.foobot.io/v2/user/%s/login/';
@ -44,7 +44,7 @@ const
type
TDataFetchType = (dfLast, dfStartEnd);
TSensorType = (st_time,st_pm,st_tmp,st_hum,st_co2,st_voc,st_allpollu);
TSensorType = (st_time, st_pm, st_tmp, st_hum, st_co2, st_voc, st_allpollu);
function EncodeStringBase64(const s: string): string;
function FetchAuthenticationKey(aUsername, aUserPassword: string): boolean;
@ -65,19 +65,19 @@ function FoobotDataObjectToArrays: boolean;
// Utility functions
function ResetArrays: boolean;
function ResetObjects: boolean;
Function ResetHighLows:Boolean;
function SaveHighLows:Boolean;
Function LoadHighLows:Boolean;
function ResetHighLows: boolean;
function SaveHighLows: boolean;
function LoadHighLows: boolean;
var
HttpClient: TFPHTTPClient;
FoobotIdentityObject: TFoobotIdentityObject;
FoobotDataObject: TFoobotDataObject;
sAuthenticationKey: string;
SensorType:TSensorType;
SaveLoadHighLows:Boolean;
TheCurrentFoobot:Integer;
HLINI:TIniFile;
SensorType: TSensorType;
SaveLoadHighLows: boolean;
TheCurrentFoobot: integer;
HLINI: TIniFile;
// Easier access to datapoints
// Call FoobotDataObjectToArrays to populate them
FoobotData_time: array of TDateTime;
@ -88,96 +88,101 @@ var
FoobotData_voc: array of integer;
FoobotData_allpollu: array of double;
// Set in FoobotDataObjectToArrays
FoobotDataHighs:Array[0..HIGHLOWMAX]of Variant;
FoobotDataLows:Array[0..HIGHLOWMAX]of Variant;
FoobotDataHighTimes:Array[0..HIGHLOWMAX]of Variant;
FoobotDataLowTimes:Array[0..HIGHLOWMAX]of Variant;
FoobotDataHighs: array[0..HIGHLOWMAX] of variant;
FoobotDataLows: array[0..HIGHLOWMAX] of variant;
FoobotDataHighTimes: array[0..HIGHLOWMAX] of variant;
FoobotDataLowTimes: array[0..HIGHLOWMAX] of variant;
implementation
function SaveHighLows:Boolean;
Var sFoobotName:String;
function SaveHighLows: boolean;
var
sFoobotName: string;
begin
If SaveLoadHighLows=FALSE then Exit(FALSE);
sFoobotName:=FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].name;
If Not Assigned(HLINI) then
HLINI:=TIniFile.Create(ChangeFileExt(GetAppConfigFile(False),'.ini'));
if SaveLoadHighLows = False then
Exit(False);
sFoobotName := FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].Name;
if not Assigned(HLINI) then
HLINI := TIniFile.Create(ChangeFileExt(GetAppConfigFile(False), '.ini'));
// Store current Foobot info
HLINI.WriteInteger('Foobot','CurrentFoobot',TheCurrentFoobot);
HLINI.WriteString('Foobot','CurrentFoobotName',sFoobotName);
HLINI.WriteInteger('Foobot', 'CurrentFoobot', TheCurrentFoobot);
HLINI.WriteString('Foobot', 'CurrentFoobotName', sFoobotName);
// Particulates
HLINI.WriteFloat(sFoobotName,'pmHigh',Double(FoobotDataHighs[1]));
HLINI.WriteDateTime(sFoobotName,'pmHighTime',TDateTime(FoobotDataHighTimes[1]));
HLINI.WriteFloat(sFoobotName,'pmLow',Double(FoobotDataLows[1]));
HLINI.WriteDateTime(sFoobotName,'pmLowTime',TDateTime(FoobotDataLowTimes[1]));
HLINI.WriteFloat(sFoobotName, 'pmHigh', double(FoobotDataHighs[1]));
HLINI.WriteDateTime(sFoobotName, 'pmHighTime', TDateTime(FoobotDataHighTimes[1]));
HLINI.WriteFloat(sFoobotName, 'pmLow', double(FoobotDataLows[1]));
HLINI.WriteDateTime(sFoobotName, 'pmLowTime', TDateTime(FoobotDataLowTimes[1]));
// Temp
HLINI.WriteFloat(sFoobotName,'tmpHigh',Double(FoobotDataHighs[2]));
HLINI.WriteDateTime(sFoobotName,'tmpHighTime',TDateTime(FoobotDataHighTimes[2]));
HLINI.WriteFloat(sFoobotName,'tmpLow',Double(FoobotDataLows[2]));
HLINI.WriteDateTime(sFoobotName,'tmpLowTime',TDateTime(FoobotDataLowTimes[2]));
HLINI.WriteFloat(sFoobotName, 'tmpHigh', double(FoobotDataHighs[2]));
HLINI.WriteDateTime(sFoobotName, 'tmpHighTime', TDateTime(FoobotDataHighTimes[2]));
HLINI.WriteFloat(sFoobotName, 'tmpLow', double(FoobotDataLows[2]));
HLINI.WriteDateTime(sFoobotName, 'tmpLowTime', TDateTime(FoobotDataLowTimes[2]));
// Humidity
HLINI.WriteFloat(sFoobotName,'humHigh',Double(FoobotDataHighs[3]));
HLINI.WriteDateTime(sFoobotName,'humHighTime',TDateTime(FoobotDataHighTimes[3]));
HLINI.WriteFloat(sFoobotName,'humLow',Double(FoobotDataLows[3]));
HLINI.WriteDateTime(sFoobotName,'humLowTime',TDateTime(FoobotDataLowTimes[3]));
HLINI.WriteFloat(sFoobotName, 'humHigh', double(FoobotDataHighs[3]));
HLINI.WriteDateTime(sFoobotName, 'humHighTime', TDateTime(FoobotDataHighTimes[3]));
HLINI.WriteFloat(sFoobotName, 'humLow', double(FoobotDataLows[3]));
HLINI.WriteDateTime(sFoobotName, 'humLowTime', TDateTime(FoobotDataLowTimes[3]));
// CO2
HLINI.WriteInteger(sFoobotName,'co2High',Integer(FoobotDataHighs[4]));
HLINI.WriteDateTime(sFoobotName,'co2HighTime',TDateTime(FoobotDataHighTimes[4]));
HLINI.WriteInteger(sFoobotName,'co2Low',Integer(FoobotDataLows[4]));
HLINI.WriteDateTime(sFoobotName,'co2LowTime',TDateTime(FoobotDataLowTimes[4]));
HLINI.WriteInteger(sFoobotName, 'co2High', integer(FoobotDataHighs[4]));
HLINI.WriteDateTime(sFoobotName, 'co2HighTime', TDateTime(FoobotDataHighTimes[4]));
HLINI.WriteInteger(sFoobotName, 'co2Low', integer(FoobotDataLows[4]));
HLINI.WriteDateTime(sFoobotName, 'co2LowTime', TDateTime(FoobotDataLowTimes[4]));
// Volatile Compounds
HLINI.WriteInteger(sFoobotName,'vocHigh',Integer(FoobotDataHighs[5]));
HLINI.WriteDateTime(sFoobotName,'vocHighTime',TDateTime(FoobotDataHighTimes[5]));
HLINI.WriteInteger(sFoobotName,'vocLow',Integer(FoobotDataLows[5]));
HLINI.WriteDateTime(sFoobotName,'vocLowTime',TDateTime(FoobotDataLowTimes[5]));
HLINI.WriteInteger(sFoobotName, 'vocHigh', integer(FoobotDataHighs[5]));
HLINI.WriteDateTime(sFoobotName, 'vocHighTime', TDateTime(FoobotDataHighTimes[5]));
HLINI.WriteInteger(sFoobotName, 'vocLow', integer(FoobotDataLows[5]));
HLINI.WriteDateTime(sFoobotName, 'vocLowTime', TDateTime(FoobotDataLowTimes[5]));
// All Pollution
HLINI.WriteFloat(sFoobotName,'allpolluHigh',Double(FoobotDataHighs[6]));
HLINI.WriteDateTime(sFoobotName,'allpolluHighTime',TDateTime(FoobotDataHighTimes[6]));
HLINI.WriteFloat(sFoobotName,'allpolluLow',Double(FoobotDataLows[6]));
HLINI.WriteDateTime(sFoobotName,'allpolluLowTime',TDateTime(FoobotDataLowTimes[6]));
HLINI.WriteFloat(sFoobotName, 'allpolluHigh', double(FoobotDataHighs[6]));
HLINI.WriteDateTime(sFoobotName, 'allpolluHighTime', TDateTime(FoobotDataHighTimes[6]));
HLINI.WriteFloat(sFoobotName, 'allpolluLow', double(FoobotDataLows[6]));
HLINI.WriteDateTime(sFoobotName, 'allpolluLowTime', TDateTime(FoobotDataLowTimes[6]));
end;
Function LoadHighLows:Boolean;
Var sFoobotName:String;
function LoadHighLows: boolean;
var
sFoobotName: string;
begin
If SaveLoadHighLows=FALSE then Exit(FALSE);
sFoobotName:=FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].name;
If Not Assigned(HLINI) then
HLINI:=TIniFile.Create(ChangeFileExt(GetAppConfigFile(False),'.ini'));
if SaveLoadHighLows = False then
Exit(False);
sFoobotName := FoobotIdentityObject.FoobotIdentityList[TheCurrentFoobot].Name;
if not Assigned(HLINI) then
HLINI := TIniFile.Create(ChangeFileExt(GetAppConfigFile(False), '.ini'));
// Make sure the High-Lows are for the current Foobot
if (HLINI.ReadString('Foobot','CurrentFoobotName','unknown') <> sFoobotName)
then Exit(FALSE);
if (HLINI.ReadString('Foobot', 'CurrentFoobotName', 'unknown') <> sFoobotName) then
Exit(False);
// Particulates
FoobotDataHighs[1]:=HLINI.ReadFloat(sFoobotName,'pmHigh',0);
FoobotDataHighTimes[1]:=HLINI.ReadDateTime(sFoobotName,'pmHighTime',Now);
FoobotDataLows[1]:=HLINI.ReadFloat(sFoobotName,'pmLow',0);
FoobotDataLowTimes[1]:=HLINI.ReadDateTime(sFoobotName,'pmLowTime',Now);
FoobotDataHighs[1] := HLINI.ReadFloat(sFoobotName, 'pmHigh', 0);
FoobotDataHighTimes[1] := HLINI.ReadDateTime(sFoobotName, 'pmHighTime', Now);
FoobotDataLows[1] := HLINI.ReadFloat(sFoobotName, 'pmLow', 0);
FoobotDataLowTimes[1] := HLINI.ReadDateTime(sFoobotName, 'pmLowTime', Now);
// Temp
FoobotDataHighs[2]:=HLINI.ReadFloat(sFoobotName,'tmpHigh',0);
FoobotDataHighTimes[2]:=HLINI.ReadDateTime(sFoobotName,'tmpHighTime',Now);
FoobotDataLows[2]:=HLINI.ReadFloat(sFoobotName,'tmpLow',0);
FoobotDataLowTimes[2]:=HLINI.ReadDateTime(sFoobotName,'tmpLowTime',Now);
FoobotDataHighs[2] := HLINI.ReadFloat(sFoobotName, 'tmpHigh', 0);
FoobotDataHighTimes[2] := HLINI.ReadDateTime(sFoobotName, 'tmpHighTime', Now);
FoobotDataLows[2] := HLINI.ReadFloat(sFoobotName, 'tmpLow', 0);
FoobotDataLowTimes[2] := HLINI.ReadDateTime(sFoobotName, 'tmpLowTime', Now);
// Humidity
FoobotDataHighs[3]:=HLINI.ReadFloat(sFoobotName,'humHigh',0);
FoobotDataHighTimes[3]:=HLINI.ReadDateTime(sFoobotName,'humHighTime',Now);
FoobotDataLows[3]:=HLINI.ReadFloat(sFoobotName,'humLow',0);
FoobotDataLowTimes[3]:=HLINI.ReadDateTime(sFoobotName,'humLowTime',Now);
FoobotDataHighs[3] := HLINI.ReadFloat(sFoobotName, 'humHigh', 0);
FoobotDataHighTimes[3] := HLINI.ReadDateTime(sFoobotName, 'humHighTime', Now);
FoobotDataLows[3] := HLINI.ReadFloat(sFoobotName, 'humLow', 0);
FoobotDataLowTimes[3] := HLINI.ReadDateTime(sFoobotName, 'humLowTime', Now);
// CO2
FoobotDataHighs[4]:=HLINI.ReadInteger(sFoobotName,'co2High',0);
FoobotDataHighTimes[4]:=HLINI.ReadDateTime(sFoobotName,'co2HighTime',Now);
FoobotDataLows[4]:=HLINI.ReadInteger(sFoobotName,'co2Low',0);
FoobotDataLowTimes[4]:=HLINI.ReadDateTime(sFoobotName,'co2LowTime',Now);
FoobotDataHighs[4] := HLINI.ReadInteger(sFoobotName, 'co2High', 0);
FoobotDataHighTimes[4] := HLINI.ReadDateTime(sFoobotName, 'co2HighTime', Now);
FoobotDataLows[4] := HLINI.ReadInteger(sFoobotName, 'co2Low', 0);
FoobotDataLowTimes[4] := HLINI.ReadDateTime(sFoobotName, 'co2LowTime', Now);
// Volatile Compounds
FoobotDataHighs[5]:=HLINI.ReadInteger(sFoobotName,'vocHigh',0);
FoobotDataHighTimes[5]:=HLINI.ReadDateTime(sFoobotName,'vocHighTime',Now);
FoobotDataLows[5]:=HLINI.ReadInteger(sFoobotName,'vocLow',0);
FoobotDataLowTimes[5]:=HLINI.ReadDateTime(sFoobotName,'vocLowTime',Now);
FoobotDataHighs[5] := HLINI.ReadInteger(sFoobotName, 'vocHigh', 0);
FoobotDataHighTimes[5] := HLINI.ReadDateTime(sFoobotName, 'vocHighTime', Now);
FoobotDataLows[5] := HLINI.ReadInteger(sFoobotName, 'vocLow', 0);
FoobotDataLowTimes[5] := HLINI.ReadDateTime(sFoobotName, 'vocLowTime', Now);
// All Pollution
FoobotDataHighs[6]:=HLINI.ReadFloat(sFoobotName,'allpolluHigh',0);
FoobotDataHighTimes[6]:=HLINI.ReadDateTime(sFoobotName,'allpolluHighTime',Now);
FoobotDataLows[6]:=HLINI.ReadFloat(sFoobotName,'allpolluLow',0);
FoobotDataLowTimes[6]:=HLINI.ReadDateTime(sFoobotName,'allpolluLowTime',Now);
FoobotDataHighs[6] := HLINI.ReadFloat(sFoobotName, 'allpolluHigh', 0);
FoobotDataHighTimes[6] := HLINI.ReadDateTime(sFoobotName, 'allpolluHighTime', Now);
FoobotDataLows[6] := HLINI.ReadFloat(sFoobotName, 'allpolluLow', 0);
FoobotDataLowTimes[6] := HLINI.ReadDateTime(sFoobotName, 'allpolluLowTime', Now);
end;
// ToDo: Multiple Foobots?
@ -190,24 +195,25 @@ var
sStart, sEnd: string;
}
iUnixSecs: int64;
// ========= Internal routines start ===========
procedure SetHigh(iMember:Integer;aValue:Variant;aDateTime:TDateTime);
begin
If aValue > FoobotDataHighs[iMember] then
begin
FoobotDataHighs[iMember]:=aValue;
FoobotDataHighTimes[iMember]:=aDateTime;
end;
end;
procedure SetLow(iMember:Integer;aValue:Variant;aDateTime:TDateTime);
begin
If (aValue < FoobotDataLows[iMember]) OR (FoobotDataLows[iMember] = 0) then
begin
FoobotDataLows[iMember]:=aValue;
FoobotDataLowTimes[iMember]:=aDateTime;
end;
end;
// ========== Internal routines end =============
// ========= Internal routines start ===========
procedure SetHigh(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
if aValue > FoobotDataHighs[iMember] then
begin
FoobotDataHighs[iMember] := aValue;
FoobotDataHighTimes[iMember] := aDateTime;
end;
end;
procedure SetLow(iMember: integer; aValue: variant; aDateTime: TDateTime);
begin
if (aValue < FoobotDataLows[iMember]) or (FoobotDataLows[iMember] = 0) then
begin
FoobotDataLows[iMember] := aValue;
FoobotDataLowTimes[iMember] := aDateTime;
end;
end;
// ========== Internal routines end =============
begin
ResetArrays;
Result := True;
@ -237,57 +243,60 @@ begin
begin
SetLength(FoobotData_pm, K + 1);
FoobotData_pm[K] := double(MyDataPoint);
SetHigh(J,FoobotData_pm[K],FoobotData_time[K]);
SetLow(J,FoobotData_pm[K],FoobotData_time[K]);
SetHigh(J, FoobotData_pm[K], FoobotData_time[K]);
SetLow(J, FoobotData_pm[K], FoobotData_time[K]);
end;
2: // Temperature
begin
SetLength(FoobotData_tmp, K + 1);
FoobotData_tmp[K] := double(MyDataPoint);
SetHigh(J,FoobotData_tmp[K],FoobotData_time[K]);
SetLow(J,FoobotData_tmp[K],FoobotData_time[K]);
SetHigh(J, FoobotData_tmp[K], FoobotData_time[K]);
SetLow(J, FoobotData_tmp[K], FoobotData_time[K]);
end;
3: // Humidity
begin
SetLength(FoobotData_hum, K + 1);
FoobotData_hum[K] := double(MyDataPoint);
SetHigh(J,FoobotData_hum[K],FoobotData_time[K]);
SetLow(J,FoobotData_hum[K],FoobotData_time[K]);
SetHigh(J, FoobotData_hum[K], FoobotData_time[K]);
SetLow(J, FoobotData_hum[K], FoobotData_time[K]);
end;
4: // CO2
begin
SetLength(FoobotData_co2, K + 1);
FoobotData_co2[K] := integer(MyDataPoint);
SetHigh(J,FoobotData_co2[K],FoobotData_time[K]);
SetLow(J,FoobotData_co2[K],FoobotData_time[K]);
SetHigh(J, FoobotData_co2[K], FoobotData_time[K]);
SetLow(J, FoobotData_co2[K], FoobotData_time[K]);
end;
5: // Volatile compounds
begin
SetLength(FoobotData_voc, K + 1);
FoobotData_voc[K] := integer(MyDataPoint);
SetHigh(J,FoobotData_voc[K],FoobotData_time[K]);
SetLow(J,FoobotData_voc[K],FoobotData_time[K]);
SetHigh(J, FoobotData_voc[K], FoobotData_time[K]);
SetLow(J, FoobotData_voc[K], FoobotData_time[K]);
end;
6: // All Pollution
begin
SetLength(FoobotData_allpollu, K + 1);
FoobotData_allpollu[K] := double(MyDataPoint);
SetHigh(J,FoobotData_allpollu[K],FoobotData_time[K]);
SetLow(J,FoobotData_allpollu[K],FoobotData_time[K]);
SetHigh(J, FoobotData_allpollu[K], FoobotData_time[K]);
SetLow(J, FoobotData_allpollu[K], FoobotData_time[K]);
end;
end; // of Case
end;
end;
SaveHighLows;
end;
Function ResetHighLows:Boolean;
Var iCount:Integer;
function ResetHighLows: boolean;
var
iCount: integer;
begin
For iCount:=0 to HIGHLOWMAX do begin
FoobotDataHighs[iCount]:=0;
FoobotDataLows[iCount]:=0;
for iCount := 0 to HIGHLOWMAX do
begin
FoobotDataHighs[iCount] := 0;
FoobotDataLows[iCount] := 0;
end;
Result:=TRUE;
Result := True;
end;
function ResetArrays: boolean;
@ -352,6 +361,7 @@ function FetchAuthenticationKey(aUsername, aUserPassword: string): boolean;
var
sRequestURL: string;
iCount: integer;
JSON: TJSONStringType;
begin
// FOOBOT_USER_URL = 'http://api.foobot.io/v2/user/%s/login/';
// sAuthenticationKey
@ -361,17 +371,22 @@ begin
with httpclient do
begin
ResponseHeaders.NameValueSeparator := ':';
AddHeader('Authorization', EncodeStringBase64(aUsername + ':' + aUserPassword));
sRequestURL := Format(FOOBOT_USER_URL, [aUsername]);
Get(sRequestURL);
if ResponseStatusCode <> 200 then
begin
ShowMessageFmt('Failed - Foobot server refused with code %d',
[ResponseStatusCode]);
Exit(False);
AddHeader('password', aUserPassword);
// ShowMessage(EncodeURLElement(aUsername));
sRequestURL := Format(FOOBOT_USER_URL, [EncodeURLElement(aUsername)]);
try
JSON := Get(sRequestURL);
if ResponseStatusCode <> 200 then
begin
ShowMessageFmt('Failed - Foobot server refused with code %d',
[ResponseStatusCode]);
Exit(False);
end;
finally
ShowMessage(JSON);
for iCount := 0 to Pred(ResponseHeaders.Count) do
ShowMessage(ResponseHeaders[iCount]);
end;
for iCount := 0 to ResponseHeaders.Count do
ShowMessage(ResponseHeaders[iCount]);
Result := True;
end;
finally
@ -386,7 +401,7 @@ var
DeStreamer: TJSONDeStreamer;
begin
Result := True; // Assume success: Look for failure
sAuthenticationKey:=aSecretKey;
sAuthenticationKey := aSecretKey;
try
with httpclient do
begin
@ -417,7 +432,8 @@ begin
DeStreamer.JSONToObject(JSON, FoobotIdentityObject.FoobotIdentityList);
except
On E: Exception do
showmessagefmt('Cannot retieve data - Foobot server refused with code %s', [E.Message]);
showmessagefmt('Cannot retieve data - Foobot server refused with code %s',
[E.Message]);
On E: Exception do
Result := False;
end;
@ -439,7 +455,7 @@ var
//FOOBOT_DATA_START_FINISH_URL = 'http://api.foobot.io/v2/device/%s/datapoint/%s/%s/%s/';
begin
Result := True; // Assume success: Look for failure
TheCurrentFoobot:=iCurrentFoobot;
TheCurrentFoobot := iCurrentFoobot;
// Checks for integrity
if (FoobotIdentityObject.FoobotIdentityList.Count = 0) then
Exit(False);
@ -511,13 +527,14 @@ initialization
HttpClient := TFPHTTPClient.Create(nil);
FoobotIdentityObject := TFoobotIdentityObject.Create;
FoobotDataObject := TFoobotDataObject.Create;
SaveLoadHighLows:=TRUE;
TheCurrentFoobot:=0;
SaveLoadHighLows := True;
TheCurrentFoobot := 0;
end;
finalization
begin
If Assigned(HLINI) then FreeAndNil(HLINI);
if Assigned(HLINI) then
FreeAndNil(HLINI);
FreeAndNil(HttpClient);
FreeAndNil(FoobotIdentityObject);
FreeAndNil(FoobotDataObject);

View File

@ -1,12 +1,12 @@
object loginform: Tloginform
Left = 256
Height = 141
Top = 472
Left = 648
Height = 243
Top = 288
Width = 442
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Caption = 'Foobot Login'
ClientHeight = 141
ClientHeight = 243
ClientWidth = 442
OnCloseQuery = FormCloseQuery
OnCreate = FormCreate
@ -15,12 +15,12 @@ object loginform: Tloginform
Scaled = True
object GroupBox1: TGroupBox
Left = 0
Height = 88
Height = 96
Top = 0
Width = 442
Align = alTop
Caption = 'Your FooBot information'
ClientHeight = 68
ClientHeight = 76
ClientWidth = 438
TabOrder = 0
object edt_emailaddress: TLabeledEdit
@ -67,11 +67,21 @@ object loginform: Tloginform
TabOrder = 1
Text = 'mypassword'
end
object Label1: TLabel
Left = 16
Height = 15
Top = 56
Width = 408
Alignment = taCenter
AutoSize = False
Caption = 'API Secret Key'
ParentColor = False
end
end
object cmd_OK: TBitBtn
Left = 184
Height = 30
Top = 96
Top = 198
Width = 75
Anchors = [akLeft, akRight, akBottom]
Default = True
@ -81,4 +91,12 @@ object loginform: Tloginform
OnClick = cmd_OKClick
TabOrder = 1
end
object Memo1: TMemo
Left = 0
Height = 90
Top = 96
Width = 442
Align = alTop
TabOrder = 2
end
end

View File

@ -37,6 +37,8 @@ type
edt_emailaddress: TLabeledEdit;
edt_password: TLabeledEdit;
GroupBox1: TGroupBox;
Label1: TLabel;
Memo1: TMemo;
procedure cmd_OKClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormCreate(Sender: TObject);
@ -57,12 +59,17 @@ uses umainform;
{ Tloginform }
procedure Tloginform.FormCreate(Sender: TObject);
Var s:String;
begin
Icon := Application.Icon;
Caption := Application.Title + ' Login';
edt_emailaddress.Text := mainform.INI.ReadString('Foobot', 'Foobot User',
'myname@myserver.com');
edt_password.Text := mainform.INI.ReadString('Foobot', 'Foobot Password', 'password');
s:='Copy + Paste your API key here & click OK' + LineEnding;
s+='Get one by visiting the Foobot website:' + LineEnding;
s+='https://api.foobot.io/apidoc/index.html';
memo1.text:=mainform.INI.ReadString('Foobot', 'Secret Key',s);
end;
procedure Tloginform.cmd_OKClick(Sender: TObject);
@ -82,6 +89,7 @@ begin
CanClose := True;
mainform.INI.WriteString('Foobot', 'Foobot User', edt_emailaddress.Text);
mainform.INI.WriteString('Foobot', 'Foobot Password', edt_password.Text);
mainform.INI.WriteString('Foobot', 'Secret Key',memo1.text);
end;
function Tloginform.ValidEmail(sEmail: string): boolean;

View File

@ -1,7 +1,7 @@
object mainform: Tmainform
Left = 547
Left = 918
Height = 377
Top = 198
Top = 191
Width = 510
BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
@ -227,6 +227,7 @@ object mainform: Tmainform
Caption = 'Button1'
OnClick = Button1Click
TabOrder = 6
Visible = False
end
object MainMenu1: TMainMenu
Left = 304

View File

@ -113,7 +113,7 @@ begin
'minesadorada@charcodelvalle.com', True);
// PUT YOUR SECRET API KEY HERE IF YOU LIKE
// INI.WriteString('Foobot', 'Secret Key',
'');
// '');
end;
if not INI.VerifyIdent('41d10218d247980fc5e871b6b7844483') then
begin