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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,6 +37,8 @@ type
edt_emailaddress: TLabeledEdit; edt_emailaddress: TLabeledEdit;
edt_password: TLabeledEdit; edt_password: TLabeledEdit;
GroupBox1: TGroupBox; GroupBox1: TGroupBox;
Label1: TLabel;
Memo1: TMemo;
procedure cmd_OKClick(Sender: TObject); procedure cmd_OKClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
@ -57,12 +59,17 @@ uses umainform;
{ Tloginform } { Tloginform }
procedure Tloginform.FormCreate(Sender: TObject); procedure Tloginform.FormCreate(Sender: TObject);
Var s:String;
begin begin
Icon := Application.Icon; Icon := Application.Icon;
Caption := Application.Title + ' Login'; Caption := Application.Title + ' Login';
edt_emailaddress.Text := mainform.INI.ReadString('Foobot', 'Foobot User', edt_emailaddress.Text := mainform.INI.ReadString('Foobot', 'Foobot User',
'myname@myserver.com'); 'myname@myserver.com');
edt_password.Text := mainform.INI.ReadString('Foobot', 'Foobot Password', 'password'); 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; end;
procedure Tloginform.cmd_OKClick(Sender: TObject); procedure Tloginform.cmd_OKClick(Sender: TObject);
@ -82,6 +89,7 @@ begin
CanClose := True; CanClose := True;
mainform.INI.WriteString('Foobot', 'Foobot User', edt_emailaddress.Text); mainform.INI.WriteString('Foobot', 'Foobot User', edt_emailaddress.Text);
mainform.INI.WriteString('Foobot', 'Foobot Password', edt_password.Text); mainform.INI.WriteString('Foobot', 'Foobot Password', edt_password.Text);
mainform.INI.WriteString('Foobot', 'Secret Key',memo1.text);
end; end;
function Tloginform.ValidEmail(sEmail: string): boolean; function Tloginform.ValidEmail(sEmail: string): boolean;

View File

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

View File

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