You've already forked lazarus-ccr
V0.1 Initial Commit
Pascal source to access Foobot data git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5569 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
BIN
applications/foobot/latest_stable/foobot.ico
Normal file
BIN
applications/foobot/latest_stable/foobot.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
338
applications/foobot/latest_stable/foobot.lpi
Normal file
338
applications/foobot/latest_stable/foobot.lpi
Normal file
@ -0,0 +1,338 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="10"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="Foobot Interrogator"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<XPManifest>
|
||||
<TextName Value="CompanyName.ProductName.AppName"/>
|
||||
<TextDesc Value="Your application description."/>
|
||||
</XPManifest>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<UseVersionInfo Value="True"/>
|
||||
<MinorVersionNr 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">
|
||||
<Item1 Name="Win32" Default="True"/>
|
||||
<Item2 Name="Win64">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\win64\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<TargetCPU Value="x86_64"/>
|
||||
<TargetOS Value="win64"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FcUTF8"/>
|
||||
<OtherDefines Count="1">
|
||||
<Define0 Value="DEBUG"/>
|
||||
</OtherDefines>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</Item2>
|
||||
<Item3 Name="Linux32">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\linux32\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="linux"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FcUTF8"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</Item3>
|
||||
<Item4 Name="Linux64">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\linux64\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<TargetCPU Value="x86_64"/>
|
||||
<TargetOS Value="linux"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FcUTF8"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</Item4>
|
||||
<Item5 Name="Win32Debug">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\win32debug\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<IncludeAssertionCode Value="True"/>
|
||||
</SyntaxOptions>
|
||||
</Parsing>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<Checks>
|
||||
<IOChecks Value="True"/>
|
||||
<RangeChecks Value="True"/>
|
||||
<OverflowChecks Value="True"/>
|
||||
<StackChecks Value="True"/>
|
||||
</Checks>
|
||||
<VerifyObjMethodCallValidity Value="True"/>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="win32"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<UseHeaptrc Value="True"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-dDEBUG
|
||||
-FcUTF8"/>
|
||||
<OtherDefines Count="1">
|
||||
<Define0 Value="DEBUG"/>
|
||||
</OtherDefines>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</Item5>
|
||||
<Item6 Name="Win32GTK">
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="gtk2"/>
|
||||
</MacroValues>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\win32GTK\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="win32"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FcUTF8"/>
|
||||
<OtherDefines Count="1">
|
||||
<Define0 Value="DEBUG"/>
|
||||
</OtherDefines>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</Item6>
|
||||
<SharedMatrixOptions Count="1">
|
||||
<Item1 ID="766380513179" Modes="Win32GTK" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/>
|
||||
</SharedMatrixOptions>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="cryptini"/>
|
||||
<MinVersion Minor="1" Release="2" Valid="True"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item2>
|
||||
</RequiredPackages>
|
||||
<Units Count="7">
|
||||
<Unit0>
|
||||
<Filename Value="foobot.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="mainform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="foobot_objects.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="foobot_httpclient.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="ulogin.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="loginform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="udataform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="dataform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit6>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\win32\foobotinterrogator"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="win32"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<LinkSmart Value="True"/>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FcUTF8"/>
|
||||
<OtherDefines Count="1">
|
||||
<Define0 Value="DEBUG"/>
|
||||
</OtherDefines>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="4">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
<Item4>
|
||||
<Name Value="EHTTPClient"/>
|
||||
</Item4>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
53
applications/foobot/latest_stable/foobot.lpr
Normal file
53
applications/foobot/latest_stable/foobot.lpr
Normal file
@ -0,0 +1,53 @@
|
||||
program foobot;
|
||||
{ Foobot Interrogator
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
}
|
||||
|
||||
{$ifdef Linux}
|
||||
{$ifdef FPC_CROSSCOMPILING}
|
||||
{$ifdef CPUARM}
|
||||
//if GUI, then uncomment
|
||||
//{$linklib GLESv2}
|
||||
{$endif}
|
||||
{$linklib libc_nonshared.a}
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, umainform, foobot_objects, foobot_httpclient, ulogin, udataform,
|
||||
foobot_utility
|
||||
{ you can add units after this };
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Title:='Foobot Interrogator';
|
||||
RequireDerivedFormResource:=True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(Tmainform, mainform);
|
||||
Application.CreateForm(Tloginform, loginform);
|
||||
Application.CreateForm(Tdataform, dataform);
|
||||
Application.Run;
|
||||
end.
|
||||
|
339
applications/foobot/latest_stable/foobot.lps
Normal file
339
applications/foobot/latest_stable/foobot.lps
Normal file
@ -0,0 +1,339 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectSession>
|
||||
<PathDelim Value="\"/>
|
||||
<Version Value="10"/>
|
||||
<BuildModes Active="Win64"/>
|
||||
<Units Count="25">
|
||||
<Unit0>
|
||||
<Filename Value="foobot.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="7"/>
|
||||
<TopLine Value="6"/>
|
||||
<CursorPos Y="44"/>
|
||||
<UsageCount Value="93"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="mainform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="174"/>
|
||||
<CursorPos X="31" Y="257"/>
|
||||
<UsageCount Value="93"/>
|
||||
<Loaded Value="True"/>
|
||||
<LoadedDesigner Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="foobot_objects.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<TopLine Value="80"/>
|
||||
<CursorPos Y="101"/>
|
||||
<UsageCount Value="53"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="foobot_httpclient.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="5"/>
|
||||
<TopLine Value="348"/>
|
||||
<CursorPos X="17" Y="369"/>
|
||||
<UsageCount Value="55"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="ulogin.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="loginform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<EditorIndex Value="6"/>
|
||||
<CursorPos Y="92"/>
|
||||
<UsageCount Value="47"/>
|
||||
<Loaded Value="True"/>
|
||||
<LoadedDesigner Value="True"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="udataform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="dataform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<EditorIndex Value="3"/>
|
||||
<TopLine Value="8"/>
|
||||
<CursorPos X="30" Y="51"/>
|
||||
<UsageCount Value="46"/>
|
||||
<Loaded Value="True"/>
|
||||
<LoadedDesigner Value="True"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<TopLine Value="27"/>
|
||||
<CursorPos X="50" Y="52"/>
|
||||
<UsageCount Value="24"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="..\..\components\cryptini\latest_stable\ucryptini.pas"/>
|
||||
<EditorIndex Value="4"/>
|
||||
<TopLine Value="262"/>
|
||||
<CursorPos X="47" Y="232"/>
|
||||
<UsageCount Value="22"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="C:\trunklatest\fpc\rtl\objpas\sysutils\sysutilh.inc"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="85"/>
|
||||
<CursorPos X="4" Y="107"/>
|
||||
<UsageCount Value="37"/>
|
||||
</Unit8>
|
||||
<Unit9>
|
||||
<Filename Value="..\json_packager\umain.pas"/>
|
||||
<ComponentName Value="frmMain"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="1358"/>
|
||||
<CursorPos Y="1369"/>
|
||||
<UsageCount Value="28"/>
|
||||
</Unit9>
|
||||
<Unit10>
|
||||
<Filename Value="..\..\components\cryptini\latest_stable\demo\umainform.pas"/>
|
||||
<ComponentName Value="mainform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="214"/>
|
||||
<CursorPos Y="235"/>
|
||||
<UsageCount Value="6"/>
|
||||
</Unit10>
|
||||
<Unit11>
|
||||
<Filename Value="D:\lazarustrunk\common_components\onlinepackagemanager\onlinepackagemanager\opkman_downloader.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="614"/>
|
||||
<CursorPos X="60" Y="565"/>
|
||||
<UsageCount Value="35"/>
|
||||
</Unit11>
|
||||
<Unit12>
|
||||
<Filename Value="D:\lazarustrunk\common_components\onlinepackagemanager\onlinepackagemanager\opkman_updates.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<CursorPos X="67" Y="8"/>
|
||||
<UsageCount Value="6"/>
|
||||
</Unit12>
|
||||
<Unit13>
|
||||
<Filename Value="C:\trunklatest\fpc\packages\fcl-json\src\fpjson.pp"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="10"/>
|
||||
<CursorPos X="12" Y="29"/>
|
||||
<UsageCount Value="38"/>
|
||||
</Unit13>
|
||||
<Unit14>
|
||||
<Filename Value="C:\trunklatest\fpc\packages\fcl-json\src\fpjsonrtti.pp"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="131"/>
|
||||
<CursorPos X="27" Y="138"/>
|
||||
<UsageCount Value="38"/>
|
||||
</Unit14>
|
||||
<Unit15>
|
||||
<Filename Value="C:\trunklatest\fpc\rtl\objpas\classes\classesh.inc"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="476"/>
|
||||
<CursorPos X="3" Y="480"/>
|
||||
<UsageCount Value="28"/>
|
||||
</Unit15>
|
||||
<Unit16>
|
||||
<Filename Value="ugenericcollection.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="6"/>
|
||||
<CursorPos X="13" Y="32"/>
|
||||
<UsageCount Value="26"/>
|
||||
</Unit16>
|
||||
<Unit17>
|
||||
<Filename Value="C:\trunklatest\fpc\rtl\objpas\classes\collect.inc"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<CursorPos X="32" Y="96"/>
|
||||
<UsageCount Value="26"/>
|
||||
</Unit17>
|
||||
<Unit18>
|
||||
<Filename Value="C:\trunklatest\lazarus\lcl\comctrls.pp"/>
|
||||
<UnitName Value="ComCtrls"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="3464"/>
|
||||
<CursorPos X="3" Y="3585"/>
|
||||
<UsageCount Value="24"/>
|
||||
</Unit18>
|
||||
<Unit19>
|
||||
<Filename Value="C:\trunklatest\lazarus\lcl\include\treeview.inc"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="1581"/>
|
||||
<CursorPos Y="1603"/>
|
||||
<UsageCount Value="22"/>
|
||||
</Unit19>
|
||||
<Unit20>
|
||||
<Filename Value="..\..\fpc\examples\fcl-json\parsedemo.pp"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="28"/>
|
||||
<UsageCount Value="9"/>
|
||||
</Unit20>
|
||||
<Unit21>
|
||||
<Filename Value="..\..\fpc\examples\fcl-json\simpledemo.pp"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="278"/>
|
||||
<CursorPos X="17" Y="311"/>
|
||||
<UsageCount Value="17"/>
|
||||
</Unit21>
|
||||
<Unit22>
|
||||
<Filename Value="..\..\fpc\packages\fcl-json\examples\demortti.pp"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<UsageCount Value="16"/>
|
||||
</Unit22>
|
||||
<Unit23>
|
||||
<Filename Value="C:\trunklatest\lazarus\lcl\grids.pas"/>
|
||||
<UnitName Value="Grids"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="9389"/>
|
||||
<CursorPos Y="9411"/>
|
||||
<UsageCount Value="12"/>
|
||||
</Unit23>
|
||||
<Unit24>
|
||||
<Filename Value="C:\trunklatest\fpc\rtl\objpas\sysutils\datih.inc"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="50"/>
|
||||
<CursorPos X="10" Y="155"/>
|
||||
<UsageCount Value="12"/>
|
||||
</Unit24>
|
||||
</Units>
|
||||
<OtherDefines Count="1">
|
||||
<Define0 Value="DEBUG"/>
|
||||
</OtherDefines>
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="290" TopLine="271"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="281" TopLine="274"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="282" TopLine="268"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="36" Column="31" TopLine="16"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="242" Column="9" TopLine="240"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="218" Column="11" TopLine="214"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="8" Column="46" TopLine="4"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="152" Column="3" TopLine="127"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="8" Column="36"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="7" Column="29" TopLine="2"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="22" Column="99"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="23" Column="21"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="74" Column="15" TopLine="72"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="88" Column="75" TopLine="65"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="279" TopLine="254"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="246" Column="42" TopLine="230"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="245" Column="32" TopLine="223"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="282" TopLine="275"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="28" TopLine="10"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="107" Column="21" TopLine="78"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="35" Column="47" TopLine="28"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="foobot.lpr"/>
|
||||
<Caret Line="44" TopLine="6"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="foobot_objects.pas"/>
|
||||
<Caret Line="101" TopLine="80"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="216" Column="26" TopLine="211"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="90" TopLine="72"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="40" Column="56" TopLine="18"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="72" Column="56" TopLine="50"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="86" Column="45" TopLine="63"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="foobot_utility.pas"/>
|
||||
<Caret Line="50" TopLine="27"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="85" TopLine="193"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
</ProjectSession>
|
||||
</CONFIG>
|
BIN
applications/foobot/latest_stable/foobot.res
Normal file
BIN
applications/foobot/latest_stable/foobot.res
Normal file
Binary file not shown.
1969
applications/foobot/latest_stable/foobot_httpclient.pas
Normal file
1969
applications/foobot/latest_stable/foobot_httpclient.pas
Normal file
File diff suppressed because it is too large
Load Diff
197
applications/foobot/latest_stable/foobot_objects.pas
Normal file
197
applications/foobot/latest_stable/foobot_objects.pas
Normal file
@ -0,0 +1,197 @@
|
||||
unit foobot_objects;
|
||||
{ Objects for Foobot Interrogator
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ugenericcollection, fpjsonrtti;
|
||||
|
||||
{TFoobotIdentities}
|
||||
type
|
||||
TFoobotIdentities = class(TCollectionItem)
|
||||
// JSON fields here as properties
|
||||
private
|
||||
Fuuid: string;
|
||||
FuserId: integer;
|
||||
FMac: string;
|
||||
FName: string;
|
||||
public
|
||||
published
|
||||
property uuid: string read Fuuid write Fuuid;
|
||||
property userId: integer read FuserId write FuserId;
|
||||
property mac: string read FMac write FMac;
|
||||
property name: string read FName write FName;
|
||||
end;
|
||||
|
||||
{TFoobotIdentityList}
|
||||
TFoobotIdentityList = specialize TGenericCollection<TFoobotIdentities>;
|
||||
|
||||
{TFoobotIdentityObject}
|
||||
// Contains a list of TFoobotIdentities as a TCollection
|
||||
type
|
||||
TFoobotIdentityObject = class(TPersistent)
|
||||
private
|
||||
FFoobotIdentityList: TFoobotIdentityList;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function SaveToFile(const AFilename: string): boolean;
|
||||
function LoadFromFile(const AFileName: string): boolean;
|
||||
published
|
||||
property FoobotIdentityList: TFoobotIdentityList
|
||||
read FFoobotIdentityList write FFoobotIdentityList;
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
TFoobotDataObject = class(TPersistent)
|
||||
private
|
||||
FDataPoints:Variant;
|
||||
FSensors:TStrings;
|
||||
FUnits:TStrings;
|
||||
Fuuid:String;
|
||||
FStart:Int64;
|
||||
FEnd:Int64;
|
||||
public
|
||||
constructor Create;
|
||||
Destructor Destroy; override;
|
||||
function SaveToFile(const AFilename: string): boolean;
|
||||
published
|
||||
property uuid:String read Fuuid write Fuuid;
|
||||
property start:Int64 read FStart write FStart;
|
||||
property &end:Int64 read FEnd write FEnd;
|
||||
property sensors:TStrings
|
||||
read FSensors write FSensors;
|
||||
property units:TStrings
|
||||
read FUnits write FUnits;
|
||||
property datapoints : Variant read FDataPoints write FDataPoints;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
constructor TFoobotDataObject.Create;
|
||||
begin
|
||||
inherited;
|
||||
FSensors:=TStringList.Create;
|
||||
FUnits:=TstringList.Create;
|
||||
end;
|
||||
|
||||
Destructor TFoobotDataObject.Destroy;
|
||||
begin
|
||||
FSensors.Free;
|
||||
FUnits.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{TFoobotIdentityObject}
|
||||
constructor TFoobotIdentityObject.Create;
|
||||
begin
|
||||
inherited;
|
||||
FFoobotIdentityList := TFoobotIdentityList.Create;
|
||||
end;
|
||||
|
||||
destructor TFoobotIdentityObject.Destroy;
|
||||
var
|
||||
c: TCollectionItem;
|
||||
begin
|
||||
for c in FFoobotIdentityList do
|
||||
c.Free;
|
||||
FFoobotIdentityList.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TFoobotIdentityObject.LoadFromFile(const AFileName: string): boolean;
|
||||
var
|
||||
DeStreamer: TJSONDeStreamer;
|
||||
s: TStringList;
|
||||
begin
|
||||
Result := True;
|
||||
s := TStringList.Create;
|
||||
try
|
||||
s.LoadFromFile(AFileName);
|
||||
DeStreamer := TJSONDeStreamer.Create(nil);
|
||||
try
|
||||
DeStreamer.JSONToObject(s.Text, Self);
|
||||
except
|
||||
// Eat the exception
|
||||
On E: Exception do
|
||||
Result := False;
|
||||
end;
|
||||
finally
|
||||
DeStreamer.Free;
|
||||
s.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TFoobotIdentityObject.SaveToFile(const AFilename: string): boolean;
|
||||
var
|
||||
Streamer: TJSONStreamer;
|
||||
s: TStringList;
|
||||
begin
|
||||
Result := True;
|
||||
s := TStringList.Create;
|
||||
try
|
||||
Streamer := TJSONStreamer.Create(nil);
|
||||
Streamer.Options := Streamer.Options + [jsoUseFormatString];
|
||||
s.AddText(Streamer.ObjectToJSONString(Self));
|
||||
try
|
||||
s.SaveToFile(AFileName);
|
||||
except
|
||||
// Eat the exception
|
||||
On E: Exception do
|
||||
Result := False;
|
||||
end;
|
||||
finally
|
||||
Streamer.Free;
|
||||
s.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TFoobotDataObject.SaveToFile(const AFilename: string): boolean;
|
||||
var
|
||||
Streamer: TJSONStreamer;
|
||||
s: TStringList;
|
||||
begin
|
||||
Result := True;
|
||||
s := TStringList.Create;
|
||||
try
|
||||
Streamer := TJSONStreamer.Create(nil);
|
||||
Streamer.Options := Streamer.Options + [jsoUseFormatString];
|
||||
s.AddText(Streamer.ObjectToJSONString(Self));
|
||||
try
|
||||
s.SaveToFile(AFileName);
|
||||
except
|
||||
// Eat the exception
|
||||
On E: Exception do
|
||||
Result := False;
|
||||
end;
|
||||
finally
|
||||
Streamer.Free;
|
||||
s.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
533
applications/foobot/latest_stable/foobot_utility.pas
Normal file
533
applications/foobot/latest_stable/foobot_utility.pas
Normal file
@ -0,0 +1,533 @@
|
||||
unit foobot_utility;
|
||||
|
||||
{ Foobot Interrogator Utilities
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
VERSION HISTORY
|
||||
===============
|
||||
* HighLow routines
|
||||
* Use GetAppGonfigFile for IniFile location
|
||||
}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Dialogs,
|
||||
foobot_httpclient, foobot_objects, fpjson, fpjsonrtti, base64, variants,
|
||||
DateUtils,INIFiles;
|
||||
|
||||
const
|
||||
FOOBOT_USER_URL = 'https://api.foobot.io/v2/user/%s/login/';
|
||||
FOOBOT_IDENTITY_URL = 'https://api.foobot.io/v2/owner/%s/device/';
|
||||
FOOBOT_DATA_LAST_URL = 'https://api.foobot.io/v2/device/%s/datapoint/%s/%s/%s/';
|
||||
FOOBOT_DATA_START_FINISH_URL =
|
||||
'https://api.foobot.io/v2/device/%s/datapoint/%s/%s/%s/';
|
||||
HIGHLOWMAX = 6;
|
||||
|
||||
type
|
||||
TDataFetchType = (dfLast, dfStartEnd);
|
||||
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;
|
||||
|
||||
// Populates FoobotIdentityObject.TFoobotIdentityList collection
|
||||
function FetchFoobotIdentity(aUsername, aSecretKey: string): boolean;
|
||||
|
||||
// Populates FoobotIdentityObject
|
||||
function FetchFoobotData(DataFetchType: TDataFetchType = dfLast;
|
||||
iCurrentFoobot: integer = 0; iLastIntervalSeconds: integer = 3600;
|
||||
iLastAverageBySeconds: integer = 0; iStartTimeSeconds: int64 = 0;
|
||||
iEndTimeSeconds: int64 = 0; aSecretKey: string = 'unknown'): boolean;
|
||||
|
||||
// Populates datapoint arrays from FoobotIdentityObject for easy access
|
||||
// - also populates HighLow arrays
|
||||
function FoobotDataObjectToArrays: boolean;
|
||||
|
||||
// Utility functions
|
||||
function ResetArrays: boolean;
|
||||
function ResetObjects: 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;
|
||||
// Easier access to datapoints
|
||||
// Call FoobotDataObjectToArrays to populate them
|
||||
FoobotData_time: array of TDateTime;
|
||||
FoobotData_pm: array of double;
|
||||
FoobotData_tmp: array of double;
|
||||
FoobotData_hum: array of double;
|
||||
FoobotData_co2: array of integer;
|
||||
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;
|
||||
|
||||
implementation
|
||||
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'));
|
||||
// Store current Foobot info
|
||||
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]));
|
||||
// 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]));
|
||||
// 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]));
|
||||
// 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]));
|
||||
// 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]));
|
||||
// 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]));
|
||||
end;
|
||||
|
||||
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'));
|
||||
// Make sure the High-Lows are for the current Foobot
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
end;
|
||||
|
||||
// ToDo: Multiple Foobots?
|
||||
function FoobotDataObjectToArrays: boolean;
|
||||
var
|
||||
J, K: integer;
|
||||
Mydatapoint: variant;
|
||||
{
|
||||
dtDate, dtStart, dtEnd: TDateTime;
|
||||
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 =============
|
||||
begin
|
||||
ResetArrays;
|
||||
Result := True;
|
||||
LoadHighLows;
|
||||
if FoobotIdentityObject.FoobotIdentityList.Count = 0 then
|
||||
Exit(False);
|
||||
if FooBotDataObject.sensors.Count = 0 then
|
||||
Exit(False);
|
||||
if FooBotDataObject.units.Count = 0 then
|
||||
Exit(False);
|
||||
// J=Column, K=Row
|
||||
for K := VarArrayLowBound(FoobotDataObject.datapoints, 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints, 1) do
|
||||
begin
|
||||
for J := VarArrayLowBound(FoobotDataObject.datapoints[K], 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints[K], 1) do
|
||||
begin
|
||||
Mydatapoint := FoobotDataObject.datapoints[K][J];
|
||||
case J of
|
||||
0: // First field is a DateTime
|
||||
begin
|
||||
iUnixSecs := int64(Mydatapoint);
|
||||
SetLength(FoobotData_time, K + 1);
|
||||
FoobotData_time[K] := UnixToDateTime(iUnixSecs);
|
||||
end;
|
||||
1: // Particulate matter
|
||||
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]);
|
||||
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]);
|
||||
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]);
|
||||
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]);
|
||||
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]);
|
||||
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]);
|
||||
end;
|
||||
end; // of Case
|
||||
end;
|
||||
end;
|
||||
SaveHighLows;
|
||||
end;
|
||||
Function ResetHighLows:Boolean;
|
||||
Var iCount:Integer;
|
||||
begin
|
||||
For iCount:=0 to HIGHLOWMAX do begin
|
||||
FoobotDataHighs[iCount]:=0;
|
||||
FoobotDataLows[iCount]:=0;
|
||||
end;
|
||||
Result:=TRUE;
|
||||
end;
|
||||
|
||||
function ResetArrays: boolean;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
SetLength(FoobotData_time, 0);
|
||||
SetLength(FoobotData_pm, 0);
|
||||
SetLength(FoobotData_tmp, 0);
|
||||
SetLength(FoobotData_hum, 0);
|
||||
SetLength(FoobotData_co2, 0);
|
||||
SetLength(FoobotData_voc, 0);
|
||||
SetLength(FoobotData_allpollu, 0);
|
||||
except
|
||||
Result := False;
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ResetObjects: boolean;
|
||||
var
|
||||
J, K: integer;
|
||||
begin
|
||||
Result := True;
|
||||
try
|
||||
for K := VarArrayLowBound(FoobotDataObject.datapoints, 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints, 1) do
|
||||
for J := VarArrayLowBound(FoobotDataObject.datapoints[K], 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints[K], 1) do
|
||||
FoobotDataObject.datapoints[K][J] := 0;
|
||||
FooBotDataObject.sensors.Clear;
|
||||
FooBotDataObject.units.Clear;
|
||||
FoobotIdentityObject.FoobotIdentityList.Clear;
|
||||
except
|
||||
Result := False;
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
function EncodeStringBase64(const s: string): string;
|
||||
|
||||
var
|
||||
outstream: TStringStream;
|
||||
encoder: TBase64EncodingStream;
|
||||
begin
|
||||
outstream := TStringStream.Create('');
|
||||
try
|
||||
encoder := TBase64EncodingStream.Create(outstream);
|
||||
try
|
||||
encoder.Write(s[1], length(s));
|
||||
finally
|
||||
encoder.Free;
|
||||
end;
|
||||
outstream.position := 0;
|
||||
Result := outstream.readstring(outstream.size);
|
||||
finally
|
||||
outstream.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FetchAuthenticationKey(aUsername, aUserPassword: string): boolean;
|
||||
var
|
||||
sRequestURL: string;
|
||||
iCount: integer;
|
||||
begin
|
||||
// FOOBOT_USER_URL = 'http://api.foobot.io/v2/user/%s/login/';
|
||||
// sAuthenticationKey
|
||||
// Looking for "x-auth-token"
|
||||
Result := False;
|
||||
try
|
||||
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);
|
||||
end;
|
||||
for iCount := 0 to ResponseHeaders.Count do
|
||||
ShowMessage(ResponseHeaders[iCount]);
|
||||
Result := True;
|
||||
end;
|
||||
finally
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function FetchFoobotIdentity(aUsername, aSecretKey: string): boolean;
|
||||
var
|
||||
sUserNameURL: string;
|
||||
JSON: TJSONStringType;
|
||||
DeStreamer: TJSONDeStreamer;
|
||||
begin
|
||||
Result := True; // Assume success: Look for failure
|
||||
sAuthenticationKey:=aSecretKey;
|
||||
try
|
||||
with httpclient do
|
||||
begin
|
||||
DeStreamer := TJSONDeStreamer.Create(nil);
|
||||
DeStreamer.Options := [jdoIgnorePropertyErrors];
|
||||
sUserNameURL := Format(FOOBOT_IDENTITY_URL, [aUsername]);
|
||||
ResponseHeaders.NameValueSeparator := ':';
|
||||
AddHeader('Accept', 'application/json;charset=UTF-8');
|
||||
AddHeader('X-API-KEY-TOKEN', aSecretKey);
|
||||
JSON := Get(sUserNameURL);
|
||||
if (ResponseStatusCode <> 200) then
|
||||
case ResponseStatusCode of
|
||||
429:
|
||||
begin
|
||||
ShowMessageFmt('Cannot retieve data - too many requests to the Foobot server%s%s',
|
||||
[LineEnding, JSON]);
|
||||
Exit(False);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
ShowMessageFmt('Cannot retieve data - Foobot server refused with code %d',
|
||||
[ResponseStatusCode]);
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
try
|
||||
// Stream it to the object list
|
||||
DeStreamer.JSONToObject(JSON, FoobotIdentityObject.FoobotIdentityList);
|
||||
except
|
||||
On E: Exception do
|
||||
showmessagefmt('Cannot retieve data - Foobot server refused with code %s', [E.Message]);
|
||||
On E: Exception do
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
DeStreamer.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function FetchFoobotData(DataFetchType: TDataFetchType;
|
||||
iCurrentFoobot, iLastIntervalSeconds, iLastAverageBySeconds: integer;
|
||||
iStartTimeSeconds, iEndTimeSeconds: int64; aSecretKey: string): boolean;
|
||||
var
|
||||
sUserNameURL: string;
|
||||
JSON: TJSONStringType;
|
||||
DeStreamer: TJSONDeStreamer;
|
||||
uuid: string;
|
||||
//FOOBOT_DATA_LAST_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
|
||||
Result := True; // Assume success: Look for failure
|
||||
TheCurrentFoobot:=iCurrentFoobot;
|
||||
// Checks for integrity
|
||||
if (FoobotIdentityObject.FoobotIdentityList.Count = 0) then
|
||||
Exit(False);
|
||||
if (DataFetchType = dfStartEnd) and ((iStartTimeSeconds = 0) or
|
||||
(iEndTimeSeconds = 0)) then
|
||||
Exit(False);
|
||||
if (aSecretKey = 'unknown') then
|
||||
Exit(False);
|
||||
|
||||
try
|
||||
with httpclient do
|
||||
begin
|
||||
DeStreamer := TJSONDeStreamer.Create(nil);
|
||||
DeStreamer.Options := [jdoIgnorePropertyErrors];
|
||||
// secretkey := INI.ReadString('Foobot', 'Secret Key', '');
|
||||
uuid := FoobotIdentityObject.FoobotIdentityList.Items[iCurrentFoobot].uuid;
|
||||
case DataFetchType of
|
||||
dfLast:
|
||||
sUserNameURL := Format(FOOBOT_DATA_LAST_URL,
|
||||
[uuid, IntToStr(iLastIntervalSeconds), 'last',
|
||||
IntToStr(iLastAverageBySeconds)]);
|
||||
dfStartEnd:
|
||||
sUserNameURL := Format(FOOBOT_DATA_START_FINISH_URL,
|
||||
[uuid, IntToStr(iStartTimeSeconds), IntToStr(iEndTimeSeconds),
|
||||
IntToStr(iLastAverageBySeconds)]);
|
||||
else
|
||||
begin
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
ResponseHeaders.NameValueSeparator := ':';
|
||||
|
||||
AddHeader('Accept', 'application/json;charset=UTF-8');
|
||||
AddHeader('X-API-KEY-TOKEN', aSecretKey);
|
||||
JSON := Get(sUserNameURL);
|
||||
if (ResponseStatusCode <> 200) then
|
||||
case ResponseStatusCode of
|
||||
429:
|
||||
begin
|
||||
ShowMessageFmt('Failed - Too many requests to the Foobot server%s%s',
|
||||
[LineEnding, JSON]);
|
||||
Exit(False);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
ShowMessageFmt('Failed - Foobot server refused with code %d',
|
||||
[ResponseStatusCode]);
|
||||
Exit(False);
|
||||
end;
|
||||
end;
|
||||
try
|
||||
// Stream it to the object list
|
||||
DeStreamer.JSONToObject(JSON, FoobotDataObject);
|
||||
except
|
||||
On E: Exception do
|
||||
showmessagefmt('Failed - Foobot server refused with code %s', [E.Message]);
|
||||
On E: Exception do
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
DeStreamer.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
begin
|
||||
HttpClient := TFPHTTPClient.Create(nil);
|
||||
FoobotIdentityObject := TFoobotIdentityObject.Create;
|
||||
FoobotDataObject := TFoobotDataObject.Create;
|
||||
SaveLoadHighLows:=TRUE;
|
||||
TheCurrentFoobot:=0;
|
||||
end;
|
||||
|
||||
finalization
|
||||
begin
|
||||
If Assigned(HLINI) then FreeAndNil(HLINI);
|
||||
FreeAndNil(HttpClient);
|
||||
FreeAndNil(FoobotIdentityObject);
|
||||
FreeAndNil(FoobotDataObject);
|
||||
SetLength(FoobotData_time, 0);
|
||||
SetLength(FoobotData_pm, 0);
|
||||
SetLength(FoobotData_tmp, 0);
|
||||
SetLength(FoobotData_hum, 0);
|
||||
SetLength(FoobotData_co2, 0);
|
||||
SetLength(FoobotData_voc, 0);
|
||||
SetLength(FoobotData_allpollu, 0);
|
||||
end;
|
||||
|
||||
end.
|
63
applications/foobot/latest_stable/udataform.lfm
Normal file
63
applications/foobot/latest_stable/udataform.lfm
Normal file
@ -0,0 +1,63 @@
|
||||
object dataform: Tdataform
|
||||
Left = 840
|
||||
Height = 425
|
||||
Top = 140
|
||||
Width = 668
|
||||
BorderStyle = bsSingle
|
||||
Caption = 'dataform'
|
||||
ClientHeight = 425
|
||||
ClientWidth = 668
|
||||
OnCreate = FormCreate
|
||||
OnShow = FormShow
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '1.7'
|
||||
object grp_data: TGroupBox
|
||||
Left = 0
|
||||
Height = 368
|
||||
Top = 0
|
||||
Width = 668
|
||||
Align = alTop
|
||||
Caption = 'grp_data'
|
||||
ClientHeight = 348
|
||||
ClientWidth = 664
|
||||
TabOrder = 0
|
||||
object datagrid: TStringGrid
|
||||
Left = 0
|
||||
Height = 348
|
||||
Top = 0
|
||||
Width = 664
|
||||
Align = alClient
|
||||
AutoEdit = False
|
||||
AutoFillColumns = True
|
||||
ColCount = 7
|
||||
ExtendedSelect = False
|
||||
FixedCols = 0
|
||||
Flat = True
|
||||
HeaderHotZones = []
|
||||
HeaderPushZones = []
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goSmoothScroll]
|
||||
RowCount = 1
|
||||
TabOrder = 0
|
||||
ColWidths = (
|
||||
94
|
||||
94
|
||||
94
|
||||
94
|
||||
94
|
||||
94
|
||||
99
|
||||
)
|
||||
end
|
||||
end
|
||||
object BitBtn1: TBitBtn
|
||||
Left = 297
|
||||
Height = 30
|
||||
Top = 382
|
||||
Width = 75
|
||||
Anchors = [akBottom]
|
||||
DefaultCaption = True
|
||||
Kind = bkClose
|
||||
ModalResult = 11
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
120
applications/foobot/latest_stable/udataform.pas
Normal file
120
applications/foobot/latest_stable/udataform.pas
Normal file
@ -0,0 +1,120 @@
|
||||
unit udataform;
|
||||
{ Foobot Interrogator data display
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids,
|
||||
StdCtrls, Buttons, Variants, dateutils;
|
||||
|
||||
type
|
||||
|
||||
{ Tdataform }
|
||||
|
||||
Tdataform = class(TForm)
|
||||
BitBtn1: TBitBtn;
|
||||
datagrid: TStringGrid;
|
||||
grp_data: TGroupBox;
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
|
||||
public
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
dataform: Tdataform;
|
||||
|
||||
implementation
|
||||
|
||||
uses umainform,foobot_utility;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ Tdataform }
|
||||
|
||||
procedure Tdataform.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Icon := Application.Icon;
|
||||
Caption := Application.Title + ' Data';
|
||||
end;
|
||||
|
||||
procedure Tdataform.FormShow(Sender: TObject);
|
||||
var
|
||||
J, K, iCount: integer;
|
||||
Mydatapoint: variant;
|
||||
dtDate, dtStart, dtEnd: TDateTime;
|
||||
sStart, sEnd: string;
|
||||
iUnixSecs: int64;
|
||||
begin
|
||||
with mainform do
|
||||
begin
|
||||
dtStart := UnixToDateTime(FoobotDataObject.Start);
|
||||
dtEnd := UnixToDateTime(FoobotDataObject.&end);
|
||||
sStart := FormatDateTime('dd/mm tt', dtStart);
|
||||
sEnd := FormatDateTime('dd/mm tt', dtEnd);
|
||||
|
||||
grp_data.Caption := 'Foobot ' +
|
||||
FoobotIdentityObject.FoobotIdentityList.Items[CurrentFoobot].Name +
|
||||
' From ' + sStart + ' to ' + sEnd;
|
||||
if mainform.FetchType = dfLast then
|
||||
grp_data.Caption := grp_data.Caption + ' Capture last = ' +
|
||||
mainform.rg_interval.Items[mainform.rg_interval.ItemIndex] + ', ';
|
||||
grp_data.Caption := grp_data.Caption + 'Average by = ' +
|
||||
mainform.rg_intervalAverageBy.Items[mainform.rg_intervalAverageBy.ItemIndex] + ')';
|
||||
|
||||
for iCount := 0 to Pred(FoobotDataObject.sensors.Count) do
|
||||
begin
|
||||
datagrid.Cells[iCount, 0] :=
|
||||
FoobotDataObject.sensors[iCount] + ' (' + FoobotDataObject.units[iCount] + ')';
|
||||
end;
|
||||
// J=Column, K=Row
|
||||
for K := VarArrayLowBound(FoobotDataObject.datapoints, 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints, 1) do
|
||||
begin
|
||||
for J := VarArrayLowBound(FoobotDataObject.datapoints[K], 1)
|
||||
to VarArrayHighBound(FoobotDataObject.datapoints[K], 1) do
|
||||
begin
|
||||
Mydatapoint := FoobotDataObject.datapoints[K][J];
|
||||
dataGrid.RowCount := K + 2;
|
||||
if J = 0 then // First field is a DateTime
|
||||
begin
|
||||
if K = VarArrayHighBound(FoobotDataObject.datapoints, 1) then
|
||||
datagrid.Cells[J, K + 1] := 'Latest' // Last entry is always latest
|
||||
else
|
||||
begin
|
||||
iUnixSecs := int64(Mydatapoint);
|
||||
dtDate := UnixToDateTime(iUnixSecs);
|
||||
datagrid.Cells[J, K + 1] := FormatDateTime('dd/mm - tt', dtDate);
|
||||
end;
|
||||
end
|
||||
else
|
||||
datagrid.Cells[J, K + 1] := VarToStr(Mydatapoint);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
50
applications/foobot/latest_stable/ugenericcollection.pas
Normal file
50
applications/foobot/latest_stable/ugenericcollection.pas
Normal file
@ -0,0 +1,50 @@
|
||||
unit ugenericcollection;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
|
||||
{ TGenericCollection }
|
||||
|
||||
generic TGenericCollection<T> = class(TCollection)
|
||||
private
|
||||
function GetItems(Index: integer): T;
|
||||
procedure SetItems(Index: integer; AValue: T);
|
||||
public
|
||||
constructor Create;
|
||||
public
|
||||
function Add: T;
|
||||
public
|
||||
property Items[Index: integer]: T read GetItems write SetItems; default;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TGenericCollection }
|
||||
|
||||
function TGenericCollection.GetItems(Index: integer): T;
|
||||
begin
|
||||
Result := T(inherited Items[Index]);
|
||||
end;
|
||||
|
||||
procedure TGenericCollection.SetItems(Index: integer; AValue: T);
|
||||
begin
|
||||
Items[Index].Assign(AValue);
|
||||
end;
|
||||
|
||||
constructor TGenericCollection.Create;
|
||||
begin
|
||||
inherited Create(T);
|
||||
end;
|
||||
|
||||
function TGenericCollection.Add: T;
|
||||
begin
|
||||
Result := T(inherited Add);
|
||||
end;
|
||||
|
||||
end.
|
84
applications/foobot/latest_stable/ulogin.lfm
Normal file
84
applications/foobot/latest_stable/ulogin.lfm
Normal file
@ -0,0 +1,84 @@
|
||||
object loginform: Tloginform
|
||||
Left = 256
|
||||
Height = 141
|
||||
Top = 472
|
||||
Width = 442
|
||||
BorderIcons = [biSystemMenu]
|
||||
BorderStyle = bsSingle
|
||||
Caption = 'Foobot Login'
|
||||
ClientHeight = 141
|
||||
ClientWidth = 442
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '1.7'
|
||||
Scaled = True
|
||||
object GroupBox1: TGroupBox
|
||||
Left = 0
|
||||
Height = 88
|
||||
Top = 0
|
||||
Width = 442
|
||||
Align = alTop
|
||||
Caption = 'Your FooBot information'
|
||||
ClientHeight = 68
|
||||
ClientWidth = 438
|
||||
TabOrder = 0
|
||||
object edt_emailaddress: TLabeledEdit
|
||||
Left = 16
|
||||
Height = 23
|
||||
Hint = 'This is your Foobot LogIn name'
|
||||
Top = 24
|
||||
Width = 192
|
||||
EditLabel.AnchorSideLeft.Control = edt_emailaddress
|
||||
EditLabel.AnchorSideRight.Control = edt_emailaddress
|
||||
EditLabel.AnchorSideRight.Side = asrBottom
|
||||
EditLabel.AnchorSideBottom.Control = edt_emailaddress
|
||||
EditLabel.Left = 16
|
||||
EditLabel.Height = 15
|
||||
EditLabel.Top = 6
|
||||
EditLabel.Width = 192
|
||||
EditLabel.Caption = 'User Name (Email address)'
|
||||
EditLabel.ParentColor = False
|
||||
ParentShowHint = False
|
||||
ShowHint = True
|
||||
TabOrder = 0
|
||||
Text = 'myname@myserver.com'
|
||||
end
|
||||
object edt_password: TLabeledEdit
|
||||
Left = 230
|
||||
Height = 23
|
||||
Hint = 'This is your Foobot LogIn password'
|
||||
Top = 24
|
||||
Width = 192
|
||||
EchoMode = emPassword
|
||||
EditLabel.AnchorSideLeft.Control = edt_password
|
||||
EditLabel.AnchorSideRight.Control = edt_password
|
||||
EditLabel.AnchorSideRight.Side = asrBottom
|
||||
EditLabel.AnchorSideBottom.Control = edt_password
|
||||
EditLabel.Left = 230
|
||||
EditLabel.Height = 15
|
||||
EditLabel.Top = 6
|
||||
EditLabel.Width = 192
|
||||
EditLabel.Caption = 'Foobot password'
|
||||
EditLabel.ParentColor = False
|
||||
ParentShowHint = False
|
||||
PasswordChar = '*'
|
||||
ShowHint = True
|
||||
TabOrder = 1
|
||||
Text = 'mypassword'
|
||||
end
|
||||
end
|
||||
object cmd_OK: TBitBtn
|
||||
Left = 184
|
||||
Height = 30
|
||||
Top = 96
|
||||
Width = 75
|
||||
Anchors = [akLeft, akRight, akBottom]
|
||||
Default = True
|
||||
DefaultCaption = True
|
||||
Kind = bkOK
|
||||
ModalResult = 1
|
||||
OnClick = cmd_OKClick
|
||||
TabOrder = 1
|
||||
end
|
||||
end
|
109
applications/foobot/latest_stable/ulogin.pas
Normal file
109
applications/foobot/latest_stable/ulogin.pas
Normal file
@ -0,0 +1,109 @@
|
||||
unit ulogin;
|
||||
|
||||
{ Foobot Interrogator
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
ExtCtrls, Buttons;
|
||||
|
||||
type
|
||||
|
||||
{ Tloginform }
|
||||
|
||||
Tloginform = class(TForm)
|
||||
cmd_OK: TBitBtn;
|
||||
edt_emailaddress: TLabeledEdit;
|
||||
edt_password: TLabeledEdit;
|
||||
GroupBox1: TGroupBox;
|
||||
procedure cmd_OKClick(Sender: TObject);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
private
|
||||
function ValidEmail(sEmail: string): boolean;
|
||||
public
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
loginform: Tloginform;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
uses umainform;
|
||||
|
||||
{ Tloginform }
|
||||
|
||||
procedure Tloginform.FormCreate(Sender: TObject);
|
||||
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');
|
||||
end;
|
||||
|
||||
procedure Tloginform.cmd_OKClick(Sender: TObject);
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure Tloginform.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
begin
|
||||
if not ValidEmail(edt_emailaddress.Text) then
|
||||
begin
|
||||
MessageDlg(Application.Title, edt_emailaddress.Text + LineEnding +
|
||||
' is not a valid email address', mtError, [mbOK], 0);
|
||||
CanClose := False;
|
||||
end
|
||||
else
|
||||
CanClose := True;
|
||||
mainform.INI.WriteString('Foobot', 'Foobot User', edt_emailaddress.Text);
|
||||
mainform.INI.WriteString('Foobot', 'Foobot Password', edt_password.Text);
|
||||
end;
|
||||
|
||||
function Tloginform.ValidEmail(sEmail: string): boolean;
|
||||
var
|
||||
at, dot, i: integer;
|
||||
bOkay: boolean;
|
||||
begin
|
||||
at := Pos('@', sEmail);
|
||||
dot := LastDelimiter('.', sEmail);
|
||||
bOkay := (at > 0) and (dot > at);
|
||||
if bOkay then
|
||||
begin
|
||||
for i := 1 to Length(sEmail) do
|
||||
begin
|
||||
if not (sEmail[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-', '_', '.', '@']) then
|
||||
begin
|
||||
bOkay := False;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result := bOkay;
|
||||
end;
|
||||
|
||||
end.
|
262
applications/foobot/latest_stable/umainform.lfm
Normal file
262
applications/foobot/latest_stable/umainform.lfm
Normal file
@ -0,0 +1,262 @@
|
||||
object mainform: Tmainform
|
||||
Left = 547
|
||||
Height = 377
|
||||
Top = 198
|
||||
Width = 510
|
||||
BorderIcons = [biSystemMenu, biMinimize]
|
||||
BorderStyle = bsSingle
|
||||
Caption = 'mainform'
|
||||
ClientHeight = 357
|
||||
ClientWidth = 510
|
||||
DefaultMonitor = dmDesktop
|
||||
Menu = MainMenu1
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '1.7'
|
||||
Scaled = True
|
||||
object GroupBox3: TGroupBox
|
||||
Left = 0
|
||||
Height = 209
|
||||
Top = 0
|
||||
Width = 510
|
||||
Align = alTop
|
||||
Caption = 'Your Foobots'
|
||||
ClientHeight = 189
|
||||
ClientWidth = 506
|
||||
TabOrder = 0
|
||||
object tv_Identity: TTreeView
|
||||
Left = 0
|
||||
Height = 136
|
||||
Top = 53
|
||||
Width = 506
|
||||
Align = alBottom
|
||||
AutoExpand = True
|
||||
DefaultItemHeight = 18
|
||||
ExpandSignType = tvestPlusMinus
|
||||
MultiSelectStyle = [msVisibleOnly]
|
||||
ReadOnly = True
|
||||
RowSelect = True
|
||||
ShowLines = False
|
||||
ShowRoot = False
|
||||
TabOrder = 0
|
||||
OnClick = tv_IdentityClick
|
||||
Options = [tvoAutoExpand, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoRowSelect, tvoShowButtons, tvoToolTips, tvoThemedDraw]
|
||||
end
|
||||
object cmd_GetIdentity: TButton
|
||||
Left = 8
|
||||
Height = 30
|
||||
Hint = 'Click to fetch your Foobot details'
|
||||
Top = 8
|
||||
Width = 128
|
||||
Caption = 'Fetch all Foobots'
|
||||
OnClick = cmd_GetIdentityClick
|
||||
ParentShowHint = False
|
||||
ShowHint = True
|
||||
TabOrder = 1
|
||||
end
|
||||
object cmd_FetchData: TButton
|
||||
Left = 144
|
||||
Height = 30
|
||||
Top = 8
|
||||
Width = 248
|
||||
Caption = 'Fetch data from selected Foobot'
|
||||
Enabled = False
|
||||
OnClick = cmd_FetchDataClick
|
||||
ParentFont = False
|
||||
TabOrder = 2
|
||||
end
|
||||
object cmd_Close: TBitBtn
|
||||
Left = 422
|
||||
Height = 30
|
||||
Top = 8
|
||||
Width = 75
|
||||
Anchors = []
|
||||
DefaultCaption = True
|
||||
Kind = bkClose
|
||||
ModalResult = 11
|
||||
OnClick = mnu_fileExitClick
|
||||
TabOrder = 3
|
||||
end
|
||||
end
|
||||
object sb: TStatusBar
|
||||
Left = 0
|
||||
Height = 23
|
||||
Top = 334
|
||||
Width = 510
|
||||
Panels = <>
|
||||
end
|
||||
object rg_interval: TRadioGroup
|
||||
Left = 264
|
||||
Height = 105
|
||||
Top = 216
|
||||
Width = 96
|
||||
AutoFill = True
|
||||
Caption = 'Previous...'
|
||||
ChildSizing.LeftRightSpacing = 6
|
||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
ClientHeight = 85
|
||||
ClientWidth = 92
|
||||
Enabled = False
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'Now'
|
||||
'Hour'
|
||||
'2 Hours'
|
||||
'4 Hours'
|
||||
'8 Hours'
|
||||
)
|
||||
OnSelectionChanged = rg_intervalSelectionChanged
|
||||
TabOrder = 2
|
||||
end
|
||||
object rg_intervalAverageBy: TRadioGroup
|
||||
Left = 360
|
||||
Height = 105
|
||||
Top = 216
|
||||
Width = 145
|
||||
AutoFill = True
|
||||
Caption = 'Average by..'
|
||||
ChildSizing.LeftRightSpacing = 6
|
||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
ClientHeight = 85
|
||||
ClientWidth = 141
|
||||
Enabled = False
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'No average'
|
||||
'Hourly average'
|
||||
'8-Hourly average'
|
||||
'24-Hourly average'
|
||||
'Total average'
|
||||
)
|
||||
OnSelectionChanged = rg_intervalAverageBySelectionChanged
|
||||
TabOrder = 3
|
||||
end
|
||||
object rg_mode: TRadioGroup
|
||||
Left = 8
|
||||
Height = 105
|
||||
Top = 216
|
||||
Width = 112
|
||||
AutoFill = True
|
||||
Caption = 'Mode'
|
||||
ChildSizing.LeftRightSpacing = 6
|
||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||
ChildSizing.ControlsPerLine = 1
|
||||
ClientHeight = 85
|
||||
ClientWidth = 108
|
||||
Enabled = False
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'Previous'
|
||||
'Date Range'
|
||||
)
|
||||
OnSelectionChanged = rg_modeSelectionChanged
|
||||
TabOrder = 4
|
||||
end
|
||||
object grp_daterange: TGroupBox
|
||||
Left = 128
|
||||
Height = 105
|
||||
Top = 216
|
||||
Width = 129
|
||||
Caption = 'Date Range'
|
||||
ClientHeight = 85
|
||||
ClientWidth = 125
|
||||
Enabled = False
|
||||
TabOrder = 5
|
||||
object lbl_fromdate: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 12
|
||||
Width = 55
|
||||
Caption = 'From Date'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_to: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 36
|
||||
Width = 11
|
||||
Caption = 'to'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_toDate: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 60
|
||||
Width = 39
|
||||
Caption = 'To date'
|
||||
ParentColor = False
|
||||
end
|
||||
object spd_fromdate: TSpeedButton
|
||||
Left = 88
|
||||
Height = 22
|
||||
Top = 8
|
||||
Width = 23
|
||||
Caption = '...'
|
||||
OnClick = spd_fromdateClick
|
||||
end
|
||||
object spd_todate: TSpeedButton
|
||||
Left = 88
|
||||
Height = 22
|
||||
Top = 56
|
||||
Width = 23
|
||||
Caption = '...'
|
||||
OnClick = spd_todateClick
|
||||
end
|
||||
end
|
||||
object Button1: TButton
|
||||
Left = 0
|
||||
Height = 25
|
||||
Top = 312
|
||||
Width = 75
|
||||
Caption = 'Button1'
|
||||
OnClick = Button1Click
|
||||
TabOrder = 6
|
||||
end
|
||||
object MainMenu1: TMainMenu
|
||||
Left = 304
|
||||
Top = 24
|
||||
object mnu_file: TMenuItem
|
||||
Caption = '&File'
|
||||
object mnu_fileExit: TMenuItem
|
||||
Caption = 'E&xit'
|
||||
OnClick = mnu_fileExitClick
|
||||
end
|
||||
end
|
||||
object mnu_help: TMenuItem
|
||||
Caption = '&Help'
|
||||
object mnu_helpAbout: TMenuItem
|
||||
Caption = '&About...'
|
||||
OnClick = mnu_helpAboutClick
|
||||
end
|
||||
end
|
||||
end
|
||||
object ApplicationProperties1: TApplicationProperties
|
||||
ExceptionDialog = aedOkMessageBox
|
||||
OnHint = ApplicationProperties1Hint
|
||||
Left = 264
|
||||
Top = 16
|
||||
end
|
||||
object CalendarDialog1: TCalendarDialog
|
||||
Date = 42730
|
||||
OKCaption = '&OK'
|
||||
CancelCaption = 'Cancel'
|
||||
Left = 373
|
||||
Top = 25
|
||||
end
|
||||
end
|
346
applications/foobot/latest_stable/umainform.pas
Normal file
346
applications/foobot/latest_stable/umainform.pas
Normal file
@ -0,0 +1,346 @@
|
||||
unit umainform;
|
||||
|
||||
{ Foobot Interrogator
|
||||
|
||||
Copyright (C)2016 Gordon Bamber minsadorada@charcodelvalle.com
|
||||
|
||||
This source is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
A copy of the GNU General Public License is available on the World Wide Web
|
||||
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
||||
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
}
|
||||
|
||||
{
|
||||
== VERSION HISTORY ==
|
||||
V0.1.0.0: Intial version by minesadorada
|
||||
V0.1.1.0: ??
|
||||
}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
Buttons, Menus, ExtCtrls, ComCtrls, ExtDlgs,
|
||||
ucryptini, dateutils, ulogin, udataform, foobot_utility;
|
||||
|
||||
type
|
||||
{ Tmainform }
|
||||
|
||||
Tmainform = class(TForm)
|
||||
ApplicationProperties1: TApplicationProperties;
|
||||
Button1: TButton;
|
||||
CalendarDialog1: TCalendarDialog;
|
||||
cmd_Close: TBitBtn;
|
||||
cmd_FetchData: TButton;
|
||||
cmd_GetIdentity: TButton;
|
||||
grp_daterange: TGroupBox;
|
||||
GroupBox3: TGroupBox;
|
||||
lbl_fromdate: TLabel;
|
||||
lbl_to: TLabel;
|
||||
lbl_toDate: TLabel;
|
||||
MainMenu1: TMainMenu;
|
||||
mnu_helpAbout: TMenuItem;
|
||||
mnu_help: TMenuItem;
|
||||
mnu_fileExit: TMenuItem;
|
||||
mnu_file: TMenuItem;
|
||||
rg_intervalAverageBy: TRadioGroup;
|
||||
rg_interval: TRadioGroup;
|
||||
rg_mode: TRadioGroup;
|
||||
sb: TStatusBar;
|
||||
spd_fromdate: TSpeedButton;
|
||||
spd_todate: TSpeedButton;
|
||||
tv_Identity: TTreeView;
|
||||
procedure ApplicationProperties1Hint(Sender: TObject);
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure cmd_FetchDataClick(Sender: TObject);
|
||||
procedure cmd_GetIdentityClick(Sender: TObject);
|
||||
procedure cmd_testClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure mnu_fileExitClick(Sender: TObject);
|
||||
procedure mnu_helpAboutClick(Sender: TObject);
|
||||
procedure rg_intervalAverageBySelectionChanged(Sender: TObject);
|
||||
procedure rg_intervalSelectionChanged(Sender: TObject);
|
||||
procedure rg_modeSelectionChanged(Sender: TObject);
|
||||
procedure spd_fromdateClick(Sender: TObject);
|
||||
procedure spd_todateClick(Sender: TObject);
|
||||
procedure tv_IdentityClick(Sender: TObject);
|
||||
private
|
||||
sFoobotUserName: string;
|
||||
sFoobotPassword: string;
|
||||
iLastIntervalSeconds: integer;
|
||||
iLastAverageBySeconds: integer;
|
||||
iStartTimeSeconds, iEndTimeSeconds: int64;
|
||||
function PopulateIdentityTreeView: boolean;
|
||||
public
|
||||
INI: TCryptIniFile;
|
||||
CurrentFoobot: integer;
|
||||
FetchType: TDataFetchType;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
mainform: Tmainform;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ Tmainform }
|
||||
|
||||
procedure Tmainform.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Icon := Application.Icon;
|
||||
Caption := Application.Title;
|
||||
INI := TCryptINIFile.Create(GetAppConfigFile(False));
|
||||
if INI.IsVirgin then
|
||||
begin
|
||||
INI.WriteIdent('Gordon Bamber', '(c)2016', 'GPLV2',
|
||||
'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
|
||||
ShowMessage(Application.Title +
|
||||
' has been tampered wth. Please re-install from a trusted source.');
|
||||
Application.Terminate;
|
||||
end;
|
||||
CurrentFoobot := 0;
|
||||
Hint := 'Welcome to ' + Application.Title;
|
||||
sb.SimpleText := Hint;
|
||||
FetchType := dfLast;
|
||||
end;
|
||||
|
||||
procedure Tmainform.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FreeAndNil(INI);
|
||||
end;
|
||||
|
||||
procedure Tmainform.FormShow(Sender: TObject);
|
||||
begin
|
||||
loginform.showmodal;
|
||||
sFoobotUserName := INI.ReadString('Foobot', 'Foobot User', 'myname@myserver.com');
|
||||
sFoobotPassword := INI.ReadString('Foobot', 'Foobot Password', 'password');
|
||||
end;
|
||||
|
||||
procedure Tmainform.cmd_testClick(Sender: TObject);
|
||||
begin
|
||||
end;
|
||||
|
||||
function Tmainform.PopulateIdentityTreeView: boolean;
|
||||
var
|
||||
iCount: integer;
|
||||
mainnode, node: TTreeNode;
|
||||
begin
|
||||
Result := False;
|
||||
if FoobotIdentityObject.FoobotIdentityList.Count > 0 then
|
||||
begin
|
||||
// TTreeView
|
||||
TV_Identity.Items.Add(nil, 'All Foobots'); // Root
|
||||
try
|
||||
// Loop through all the detected Foobot instances
|
||||
for iCount := 0 to Pred(FoobotIdentityObject.FoobotIdentityList.Count) do
|
||||
begin
|
||||
mainnode := TV_Identity.Items[iCount];
|
||||
node := TV_Identity.Items.AddChild(mainnode,
|
||||
Format('Foobot #%d', [Succ(iCount)]));
|
||||
TV_Identity.Items.AddChild(node, 'Name: ' +
|
||||
FoobotIdentityObject.FoobotIdentityList.Items[iCount].Name);
|
||||
TV_Identity.Items.AddChild(node, 'UserID: ' +
|
||||
Format('%d', [FoobotIdentityObject.FoobotIdentityList.Items[
|
||||
iCount].userID]));
|
||||
TV_Identity.Items.AddChild(node, 'Mac: ' +
|
||||
FoobotIdentityObject.FoobotIdentityList.Items[iCount].mac);
|
||||
TV_Identity.Items.AddChild(node, 'uuID: ' +
|
||||
FoobotIdentityObject.FoobotIdentityList.Items[iCount].uuid);
|
||||
node.Expanded := False;
|
||||
Result := True;
|
||||
end;
|
||||
except
|
||||
On E: Exception do
|
||||
showmessagefmt('PopulateIdentityTreeView: Failed because %s', [E.Message]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.cmd_GetIdentityClick(Sender: TObject);
|
||||
var
|
||||
sSecretKey: string;
|
||||
begin
|
||||
sSecretKey := INI.ReadString('Foobot', 'Secret Key', '');
|
||||
if FetchFoobotIdentity(sFoobotUserName, sSecretKey) then
|
||||
if PopulateIdentityTreeView then
|
||||
begin
|
||||
cmd_GetIdentity.Enabled := False;
|
||||
tv_Identity.Hint := 'Click on a Foobot instance in the panel to interrogate it';
|
||||
tv_Identity.ShowHint := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.ApplicationProperties1Hint(Sender: TObject);
|
||||
begin
|
||||
if Application.Hint <> '' then
|
||||
sb.SimpleText := Application.Hint
|
||||
else
|
||||
sb.SimpleText := mainform.hint;
|
||||
end;
|
||||
|
||||
procedure Tmainform.Button1Click(Sender: TObject);
|
||||
begin
|
||||
FetchAuthenticationKey(sFoobotUserName, sFoobotPassword);
|
||||
end;
|
||||
|
||||
procedure Tmainform.cmd_FetchDataClick(Sender: TObject);
|
||||
var
|
||||
sSecretKey: string;
|
||||
begin
|
||||
sSecretKey := INI.ReadString('Foobot', 'Secret Key', '');
|
||||
|
||||
if FetchFoobotData(FetchType, CurrentFoobot, iLastIntervalSeconds,
|
||||
iLastAverageBySeconds, iStartTimeSeconds, iEndTimeSeconds, sSecretKey) then
|
||||
begin
|
||||
//DEBUG FoobotDataObject.SaveToFile('FoobotDataObject.json');
|
||||
dataform.ShowModal;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_fileExitClick(Sender: TObject);
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_helpAboutClick(Sender: TObject);
|
||||
var
|
||||
s: string;
|
||||
begin
|
||||
s := Application.Title + LineEnding;
|
||||
s += 'Version: ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_APPVERSION, '') +
|
||||
LineEnding + LineEnding;
|
||||
s += INI.ReadUnencryptedString('ProgramInfo', IDENT_COPYRIGHT, '');
|
||||
s += ' by ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_AUTHOR, '') + LineEnding;
|
||||
s += 'Licence: ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_LICENSE, '') +
|
||||
LineEnding;
|
||||
s += 'Made with LCL v ' + INI.ReadUnencryptedString('ProgramInfo',
|
||||
IDENT_LCLVERSION, '');
|
||||
s += ' FPC v ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_FPCVERSION, '') +
|
||||
LineEnding;
|
||||
s += 'Compiled ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_LASTCOMPILED, '') +
|
||||
LineEnding;
|
||||
s += ' for ' + INI.ReadUnencryptedString('ProgramInfo', IDENT_TARGET, '');
|
||||
MessageDlg('About ' + Application.Title, s,
|
||||
mtInformation, [mbOK], 0);
|
||||
end;
|
||||
|
||||
procedure Tmainform.rg_intervalAverageBySelectionChanged(Sender: TObject);
|
||||
begin
|
||||
case rg_intervalAverageBy.ItemIndex of
|
||||
0:
|
||||
begin
|
||||
if FetchType = dfStartEnd then
|
||||
begin
|
||||
MessageDlg(Application.Title, 'Setting minimum average = Hourly',
|
||||
mtError, [mbOK], 0);
|
||||
iLastAverageBySeconds := 3600;
|
||||
end
|
||||
else
|
||||
iLastAverageBySeconds := 0;
|
||||
end;
|
||||
1: iLastAverageBySeconds := 3600;
|
||||
2: iLastAverageBySeconds := 8 * 3600;
|
||||
3: iLastAverageBySeconds := 24 * 3600;
|
||||
4: iLastAverageBySeconds := iLastIntervalSeconds;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.rg_intervalSelectionChanged(Sender: TObject);
|
||||
begin
|
||||
case rg_interval.ItemIndex of
|
||||
0: iLastIntervalSeconds := 0;
|
||||
1: iLastIntervalSeconds := 3600;
|
||||
2: iLastIntervalSeconds := 2 * 3600;
|
||||
3: iLastIntervalSeconds := 4 * 3600;
|
||||
4: iLastIntervalSeconds := 8 * 3600;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.rg_modeSelectionChanged(Sender: TObject);
|
||||
begin
|
||||
case rg_mode.ItemIndex of
|
||||
0:
|
||||
begin
|
||||
FetchType := dfLast;
|
||||
rg_interval.Enabled := True;
|
||||
grp_daterange.Enabled := False;
|
||||
end;
|
||||
1:
|
||||
begin
|
||||
FetchType := dfStartEnd;
|
||||
rg_interval.Enabled := False;
|
||||
grp_daterange.Enabled := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.spd_fromdateClick(Sender: TObject);
|
||||
begin
|
||||
if CalendarDialog1.Execute then
|
||||
begin
|
||||
iStartTimeSeconds := DateTimeToUnix(CalendarDialog1.Date);
|
||||
lbl_fromdate.Caption := FormatDateTime('dd/mm/yyyy', CalendarDialog1.Date);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.spd_todateClick(Sender: TObject);
|
||||
begin
|
||||
if CalendarDialog1.Execute then
|
||||
begin
|
||||
iEndTimeSeconds := DateTimeToUnix(CalendarDialog1.Date);
|
||||
lbl_todate.Caption := FormatDateTime('dd/mm/yyyy', CalendarDialog1.Date);
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.tv_IdentityClick(Sender: TObject);
|
||||
var
|
||||
node: TTreeNode;
|
||||
begin
|
||||
if tv_Identity.Items.Count > 0 then
|
||||
begin
|
||||
node := tv_Identity.Selected;
|
||||
if not Assigned(Node) then
|
||||
Exit;
|
||||
if node.Level = 1 then
|
||||
begin
|
||||
CurrentFoobot := node.Index; // Zero-based
|
||||
cmd_FetchData.Enabled := True;
|
||||
cmd_FetchData.Font.Style := [fsBold];
|
||||
rg_mode.Enabled := True;
|
||||
rg_interval.Enabled := True;
|
||||
rg_intervalAverageBy.Enabled := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cmd_FetchData.Enabled := False;
|
||||
cmd_FetchData.Font.Style := [];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
BIN
applications/foobot/monitor/foobotmonitor.ico
Normal file
BIN
applications/foobot/monitor/foobotmonitor.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
278
applications/foobot/monitor/foobotmonitor.lpi
Normal file
278
applications/foobot/monitor/foobotmonitor.lpi
Normal file
@ -0,0 +1,278 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="10"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="Foobot monitor"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<XPManifest>
|
||||
<DpiAware Value="True"/>
|
||||
<TextName Value="CompanyName.ProductName.AppName"/>
|
||||
<TextDesc Value="Your application description."/>
|
||||
</XPManifest>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<UseVersionInfo Value="True"/>
|
||||
<RevisionNr Value="1"/>
|
||||
</VersionInfo>
|
||||
<BuildModes Count="6">
|
||||
<Item1 Name="Debug" Default="True"/>
|
||||
<Item2 Name="win32">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="win32"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
</Item2>
|
||||
<Item3 Name="win64">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="x86_64"/>
|
||||
<TargetOS Value="win64"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
</Item3>
|
||||
<Item4 Name="linux32">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="linux"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
</Item4>
|
||||
<Item5 Name="linux64">
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="x86_64"/>
|
||||
<TargetOS Value="linux"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
</Item5>
|
||||
<Item6 Name="win32GTK2">
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="gtk2"/>
|
||||
</MacroValues>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<TargetCPU Value="i386"/>
|
||||
<TargetOS Value="win32"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<GenerateDebugInfo Value="False"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
</Item6>
|
||||
<SharedMatrixOptions Count="1">
|
||||
<Item1 ID="571324092942" Modes="win32GTK2" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk2"/>
|
||||
</SharedMatrixOptions>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="3">
|
||||
<Item1>
|
||||
<PackageName Value="industrial"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="cryptini"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item3>
|
||||
</RequiredPackages>
|
||||
<Units Count="7">
|
||||
<Unit0>
|
||||
<Filename Value="foobotmonitor.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="mainform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="uconfigform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="configform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="..\foobot_httpclient.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="..\foobot_objects.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="..\foobot_utility.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="..\ugenericcollection.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit6>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="compiled\$(BuildMode)\foobotmonitor"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<OtherUnitFiles Value=".."/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<IncludeAssertionCode Value="True"/>
|
||||
</SyntaxOptions>
|
||||
</Parsing>
|
||||
<CodeGeneration>
|
||||
<Checks>
|
||||
<IOChecks Value="True"/>
|
||||
<RangeChecks Value="True"/>
|
||||
<OverflowChecks Value="True"/>
|
||||
<StackChecks Value="True"/>
|
||||
</Checks>
|
||||
<VerifyObjMethodCallValidity Value="True"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<UseHeaptrc Value="True"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
31
applications/foobot/monitor/foobotmonitor.lpr
Normal file
31
applications/foobot/monitor/foobotmonitor.lpr
Normal file
@ -0,0 +1,31 @@
|
||||
program foobotmonitor;
|
||||
{$ifdef Linux}
|
||||
{$ifdef FPC_CROSSCOMPILING}
|
||||
{$ifdef CPUARM}
|
||||
//if GUI, then uncomment
|
||||
//{$linklib GLESv2}
|
||||
{$endif}
|
||||
{$linklib libc_nonshared.a}
|
||||
{$endif}
|
||||
{$endif}
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, umainform, uconfigform
|
||||
{ you can add units after this };
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Title:='Foobot monitor';
|
||||
RequireDerivedFormResource:=True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(Tmainform, mainform);
|
||||
Application.CreateForm(Tconfigform, configform);
|
||||
Application.Run;
|
||||
end.
|
||||
|
237
applications/foobot/monitor/foobotmonitor.lps
Normal file
237
applications/foobot/monitor/foobotmonitor.lps
Normal file
@ -0,0 +1,237 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectSession>
|
||||
<PathDelim Value="\"/>
|
||||
<Version Value="10"/>
|
||||
<BuildModes Active="win64"/>
|
||||
<Units Count="19">
|
||||
<Unit0>
|
||||
<Filename Value="foobotmonitor.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="7"/>
|
||||
<CursorPos X="33" Y="25"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="mainform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<TopLine Value="80"/>
|
||||
<CursorPos X="54" Y="105"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Loaded Value="True"/>
|
||||
<LoadedDesigner Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="uconfigform.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="configform"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<TopLine Value="80"/>
|
||||
<CursorPos X="23" Y="92"/>
|
||||
<UsageCount Value="28"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="..\foobot_httpclient.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<WindowIndex Value="-1"/>
|
||||
<TopLine Value="-1"/>
|
||||
<CursorPos X="-1" Y="-1"/>
|
||||
<UsageCount Value="20"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="..\foobot_objects.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<WindowIndex Value="-1"/>
|
||||
<TopLine Value="-1"/>
|
||||
<CursorPos X="-1" Y="-1"/>
|
||||
<UsageCount Value="20"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="..\foobot_utility.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="74"/>
|
||||
<CursorPos X="21" Y="138"/>
|
||||
<UsageCount Value="20"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="..\ugenericcollection.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<WindowIndex Value="-1"/>
|
||||
<TopLine Value="-1"/>
|
||||
<CursorPos X="-1" Y="-1"/>
|
||||
<UsageCount Value="20"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="..\latest_stable\foobot_httpclient.pas"/>
|
||||
<EditorIndex Value="3"/>
|
||||
<TopLine Value="260"/>
|
||||
<CursorPos X="8" Y="1048"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="..\latest_stable\foobot_objects.pas"/>
|
||||
<EditorIndex Value="6"/>
|
||||
<CursorPos X="32" Y="61"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit8>
|
||||
<Unit9>
|
||||
<Filename Value="..\foobot_utility.pas"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<EditorIndex Value="5"/>
|
||||
<TopLine Value="85"/>
|
||||
<CursorPos X="72" Y="104"/>
|
||||
<UsageCount Value="38"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit9>
|
||||
<Unit10>
|
||||
<Filename Value="..\latest_stable\ugenericcollection.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<WindowIndex Value="-1"/>
|
||||
<TopLine Value="-1"/>
|
||||
<CursorPos X="-1" Y="-1"/>
|
||||
<UsageCount Value="38"/>
|
||||
</Unit10>
|
||||
<Unit11>
|
||||
<Filename Value="..\latest_stable\umainform.lfm"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<UsageCount Value="10"/>
|
||||
<DefaultSyntaxHighlighter Value="LFM"/>
|
||||
</Unit11>
|
||||
<Unit12>
|
||||
<Filename Value="..\latest_stable\umainform.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="10"/>
|
||||
<CursorPos X="57" Y="36"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit12>
|
||||
<Unit13>
|
||||
<Filename Value="..\udataform.pas"/>
|
||||
<EditorIndex Value="8"/>
|
||||
<TopLine Value="74"/>
|
||||
<CursorPos Y="96"/>
|
||||
<UsageCount Value="18"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit13>
|
||||
<Unit14>
|
||||
<Filename Value="..\umainform.pas"/>
|
||||
<EditorIndex Value="4"/>
|
||||
<TopLine Value="134"/>
|
||||
<CursorPos X="25" Y="154"/>
|
||||
<UsageCount Value="18"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit14>
|
||||
<Unit15>
|
||||
<Filename Value="C:\trunklatest\lazarus\lcl\lclmessageglue.pas"/>
|
||||
<UnitName Value="LCLMessageGlue"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="93"/>
|
||||
<CursorPos Y="114"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit15>
|
||||
<Unit16>
|
||||
<Filename Value="..\ulogin.pas"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<TopLine Value="65"/>
|
||||
<CursorPos Y="108"/>
|
||||
<UsageCount Value="13"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit16>
|
||||
<Unit17>
|
||||
<Filename Value="..\..\..\components\cryptini\latest_stable\ucryptini.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="906"/>
|
||||
<CursorPos X="8" Y="939"/>
|
||||
<UsageCount Value="11"/>
|
||||
</Unit17>
|
||||
<Unit18>
|
||||
<Filename Value="..\backup\foobot_utility.pas"/>
|
||||
<EditorIndex Value="-1"/>
|
||||
<TopLine Value="7"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit18>
|
||||
</Units>
|
||||
<JumpHistory Count="17" HistoryIndex="16">
|
||||
<Position1>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="7" Column="9"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="188" Column="3" TopLine="186"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="189" Column="3" TopLine="187"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="190" Column="3" TopLine="188"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="191" Column="3" TopLine="189"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="192" Column="3" TopLine="190"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="193" Column="3" TopLine="191"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="15" Column="3" TopLine="4"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="13" Column="15"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="14" Column="6"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="208" TopLine="204"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="216" TopLine="212"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="223" Column="28" TopLine="220"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="236" Column="29" TopLine="233"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="163" Column="48" TopLine="143"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="165" Column="48" TopLine="145"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="umainform.pas"/>
|
||||
<Caret Line="153" Column="47" TopLine="132"/>
|
||||
</Position17>
|
||||
</JumpHistory>
|
||||
</ProjectSession>
|
||||
</CONFIG>
|
BIN
applications/foobot/monitor/foobotmonitor.res
Normal file
BIN
applications/foobot/monitor/foobotmonitor.res
Normal file
Binary file not shown.
89
applications/foobot/monitor/uconfigform.lfm
Normal file
89
applications/foobot/monitor/uconfigform.lfm
Normal file
@ -0,0 +1,89 @@
|
||||
object configform: Tconfigform
|
||||
Left = 654
|
||||
Height = 197
|
||||
Top = 285
|
||||
Width = 592
|
||||
BorderIcons = []
|
||||
BorderStyle = bsToolWindow
|
||||
Caption = 'configform'
|
||||
ClientHeight = 197
|
||||
ClientWidth = 592
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
Position = poMainFormCenter
|
||||
LCLVersion = '1.7'
|
||||
object grp_main: TGroupBox
|
||||
Left = 0
|
||||
Height = 145
|
||||
Top = 0
|
||||
Width = 592
|
||||
Align = alTop
|
||||
Caption = 'Your Foobot'
|
||||
ClientHeight = 125
|
||||
ClientWidth = 588
|
||||
TabOrder = 0
|
||||
object edt_username: TLabeledEdit
|
||||
Left = 104
|
||||
Height = 23
|
||||
Top = 8
|
||||
Width = 472
|
||||
EditLabel.AnchorSideTop.Control = edt_username
|
||||
EditLabel.AnchorSideTop.Side = asrCenter
|
||||
EditLabel.AnchorSideRight.Control = edt_username
|
||||
EditLabel.AnchorSideBottom.Control = edt_username
|
||||
EditLabel.AnchorSideBottom.Side = asrBottom
|
||||
EditLabel.Left = 7
|
||||
EditLabel.Height = 15
|
||||
EditLabel.Top = 12
|
||||
EditLabel.Width = 94
|
||||
EditLabel.Caption = 'Foobot Username'
|
||||
EditLabel.ParentColor = False
|
||||
LabelPosition = lpLeft
|
||||
TabOrder = 0
|
||||
Text = '(email address)'
|
||||
OnEditingDone = edt_usernameEditingDone
|
||||
end
|
||||
object Memo1: TMemo
|
||||
Left = 0
|
||||
Height = 69
|
||||
Top = 56
|
||||
Width = 588
|
||||
Align = alBottom
|
||||
Lines.Strings = (
|
||||
'Copy + Paste here'
|
||||
)
|
||||
OnEditingDone = Memo1EditingDone
|
||||
TabOrder = 1
|
||||
end
|
||||
object Label1: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 32
|
||||
Width = 75
|
||||
Caption = 'API Secret Key'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object BitBtn1: TBitBtn
|
||||
Left = 259
|
||||
Height = 30
|
||||
Top = 160
|
||||
Width = 75
|
||||
Default = True
|
||||
DefaultCaption = True
|
||||
Kind = bkOK
|
||||
ModalResult = 1
|
||||
TabOrder = 1
|
||||
end
|
||||
object BitBtn2: TBitBtn
|
||||
Left = 512
|
||||
Height = 30
|
||||
Top = 160
|
||||
Width = 75
|
||||
Cancel = True
|
||||
DefaultCaption = True
|
||||
Kind = bkCancel
|
||||
ModalResult = 11
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
124
applications/foobot/monitor/uconfigform.pas
Normal file
124
applications/foobot/monitor/uconfigform.pas
Normal file
@ -0,0 +1,124 @@
|
||||
unit uconfigform;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||
ExtCtrls, Buttons;
|
||||
|
||||
type
|
||||
|
||||
{ Tconfigform }
|
||||
|
||||
Tconfigform = class(TForm)
|
||||
BitBtn1: TBitBtn;
|
||||
BitBtn2: TBitBtn;
|
||||
grp_main: TGroupBox;
|
||||
edt_username: TLabeledEdit;
|
||||
Label1: TLabel;
|
||||
Memo1: TMemo;
|
||||
procedure edt_usernameEditingDone(Sender: TObject);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure Memo1EditingDone(Sender: TObject);
|
||||
private
|
||||
bDoneUsername,bDoneSecretKey:Boolean;
|
||||
function ValidEmail(sEmail: string): boolean;
|
||||
public
|
||||
FoobotUsername,FoobotSecretKey:String;
|
||||
bValid:Boolean;
|
||||
end;
|
||||
|
||||
var
|
||||
configform: Tconfigform;
|
||||
|
||||
implementation
|
||||
Uses umainform;
|
||||
{$R *.lfm}
|
||||
|
||||
{ Tconfigform }
|
||||
function Tconfigform.ValidEmail(sEmail: string): boolean;
|
||||
var
|
||||
at, dot, i: integer;
|
||||
bOkay: boolean;
|
||||
begin
|
||||
at := Pos('@', sEmail);
|
||||
dot := LastDelimiter('.', sEmail);
|
||||
bOkay := (at > 0) and (dot > at);
|
||||
if bOkay then
|
||||
begin
|
||||
for i := 1 to Length(sEmail) do
|
||||
begin
|
||||
if not (sEmail[i] in ['a'..'z', 'A'..'Z', '0'..'9', '-', '_', '.', '@']) then
|
||||
begin
|
||||
bOkay := False;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result := bOkay;
|
||||
end;
|
||||
|
||||
procedure Tconfigform.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Caption:='Configure ' + Application.Title;
|
||||
Icon:=Application.Icon;
|
||||
bDoneUsername:=FALSE;
|
||||
bDoneSecretKey:=FALSE;
|
||||
bValid:=False;
|
||||
FoobotUsername:= mainform.INI.ReadString('Foobot', 'Foobot User', 'unknown');
|
||||
FoobotSecretKey:= mainform.INI.ReadString('Foobot', 'Secret Key', 'unknown');
|
||||
|
||||
|
||||
end;
|
||||
|
||||
procedure Tconfigform.Memo1EditingDone(Sender: TObject);
|
||||
begin
|
||||
If (Memo1.Text='Copy + Paste here') then
|
||||
begin
|
||||
MessageDlg(Application.Title,
|
||||
edt_username.Text + ' is not a valid API key. Try again',
|
||||
mtWarning,[MBOK],0);
|
||||
Exit;
|
||||
end
|
||||
else
|
||||
FoobotSecretKey:=Memo1.Text;
|
||||
bDoneSecretKey:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tconfigform.edt_usernameEditingDone(Sender: TObject);
|
||||
begin
|
||||
If NOT ValidEmail(edt_username.Text) then
|
||||
begin
|
||||
MessageDlg(Application.Title,
|
||||
edt_username.Text + ' is not a valid email address. Try again',
|
||||
mtWarning,[MBOK],0);
|
||||
Exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FoobotUsername:=edt_username.Text;
|
||||
bDoneUsername:=TRUE;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tconfigform.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
begin
|
||||
If ( bDoneUsername=FALSE) OR (bDoneSecretKey=FALSE) then
|
||||
begin
|
||||
CanClose:=FALSE;
|
||||
If MessageDlg('You haven''t completed all the fields. Are you sure you want to quit?',
|
||||
mtConfirmation,[MBYES,MBNO],0,MBNO) = mrYes then CanClose:=TRUE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
bValid:=TRUE;
|
||||
CanClose:=TRUE;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
383
applications/foobot/monitor/umainform.lfm
Normal file
383
applications/foobot/monitor/umainform.lfm
Normal file
@ -0,0 +1,383 @@
|
||||
object mainform: Tmainform
|
||||
Left = 615
|
||||
Height = 262
|
||||
Top = 154
|
||||
Width = 782
|
||||
BorderIcons = [biSystemMenu]
|
||||
BorderStyle = bsToolWindow
|
||||
Caption = 'mainform'
|
||||
ClientHeight = 242
|
||||
ClientWidth = 782
|
||||
DefaultMonitor = dmDesktop
|
||||
Menu = MainMenu1
|
||||
OnActivate = FormActivate
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
Position = poWorkAreaCenter
|
||||
LCLVersion = '1.7'
|
||||
Scaled = True
|
||||
object grp_sensorDisplay: TGroupBox
|
||||
Left = 0
|
||||
Height = 120
|
||||
Top = 0
|
||||
Width = 782
|
||||
Align = alTop
|
||||
Caption = 'Current Values'
|
||||
ChildSizing.ControlsPerLine = 6
|
||||
ClientHeight = 100
|
||||
ClientWidth = 778
|
||||
TabOrder = 0
|
||||
object as_pm: TAnalogSensor
|
||||
Left = 0
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 0
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 300
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
object as_tmp: TAnalogSensor
|
||||
Left = 130
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 1
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 40
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
object as_hum: TAnalogSensor
|
||||
Left = 260
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 2
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 100
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
object as_co2: TAnalogSensor
|
||||
Left = 390
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 3
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 3000
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
object as_voc: TAnalogSensor
|
||||
Left = 520
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 4
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 1000
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
object as_allpollu: TAnalogSensor
|
||||
Left = 650
|
||||
Height = 100
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
ClientHeight = 100
|
||||
ClientWidth = 130
|
||||
TabOrder = 5
|
||||
ShowText = True
|
||||
ShowLevel = True
|
||||
Value = 0
|
||||
ValueMin = 0
|
||||
ValueMax = 300
|
||||
ValueRed = 0
|
||||
ValueYellow = 0
|
||||
AnalogKind = akAnalog
|
||||
end
|
||||
end
|
||||
object grp_highlow: TGroupBox
|
||||
Left = 0
|
||||
Height = 119
|
||||
Top = 120
|
||||
Width = 782
|
||||
Align = alTop
|
||||
Caption = 'Highs and Lows'
|
||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||
ChildSizing.EnlargeVertical = crsScaleChilds
|
||||
ChildSizing.ControlsPerLine = 6
|
||||
ClientHeight = 99
|
||||
ClientWidth = 778
|
||||
TabOrder = 1
|
||||
object grp_pm: TGroupBox
|
||||
Left = 0
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'Particulates'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 0
|
||||
object lbl_pmhigh: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 60
|
||||
Caption = 'lbl_pmhigh'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_pmlow: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 55
|
||||
Caption = 'lbl_pmlow'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object grp_tmp: TGroupBox
|
||||
Left = 130
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'Temperature'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 1
|
||||
object lbl_tmphigh: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 64
|
||||
Caption = 'lbl_tmphigh'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_tmplow: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 59
|
||||
Caption = 'lbl_tmplow'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object grp_hum: TGroupBox
|
||||
Left = 260
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'Humidity'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 2
|
||||
object lbl_humhigh: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 67
|
||||
Caption = 'lbl_humhigh'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_humlow: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 62
|
||||
Caption = 'lbl_humlow'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object grp_co2: TGroupBox
|
||||
Left = 390
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'CO2'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 3
|
||||
object lbl_co2high: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 61
|
||||
Caption = 'lbl_co2high'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_co2low: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 56
|
||||
Caption = 'lbl_co2low'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object grp_voc: TGroupBox
|
||||
Left = 520
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'Volatile VOC'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 4
|
||||
object lbl_vochigh: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 61
|
||||
Caption = 'lbl_vochigh'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_voclow: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 56
|
||||
Caption = 'lbl_voclow'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object grp_allpollu: TGroupBox
|
||||
Left = 650
|
||||
Height = 99
|
||||
Top = 0
|
||||
Width = 130
|
||||
Align = alLeft
|
||||
Caption = 'All Pollution'
|
||||
ClientHeight = 79
|
||||
ClientWidth = 126
|
||||
TabOrder = 5
|
||||
object lbl_allpolluhigh: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 81
|
||||
Caption = 'lbl_allpolluhigh'
|
||||
ParentColor = False
|
||||
end
|
||||
object lbl_allpollulow: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 40
|
||||
Width = 76
|
||||
Caption = 'lbl_allpollulow'
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
end
|
||||
object tmr_foobot: TTimer
|
||||
Enabled = False
|
||||
Interval = 3600
|
||||
OnTimer = tmr_foobotTimer
|
||||
Left = 16
|
||||
end
|
||||
object MainMenu1: TMainMenu
|
||||
Left = 56
|
||||
Top = 8
|
||||
object mnu_file: TMenuItem
|
||||
Caption = '&File'
|
||||
object mnu_fileExit: TMenuItem
|
||||
Caption = 'E&xit'
|
||||
OnClick = mnu_fileExitClick
|
||||
end
|
||||
end
|
||||
object mnu_options: TMenuItem
|
||||
Caption = '&Options'
|
||||
object mnu_optionsShowHighsAndLows: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = 'Show Highs and Lows'
|
||||
Checked = True
|
||||
OnClick = mnu_optionsShowHighsAndLowsClick
|
||||
end
|
||||
object mnu_optionsTakeReadingNow: TMenuItem
|
||||
Caption = 'Take reading now'
|
||||
OnClick = mnu_optionsTakeReadingNowClick
|
||||
end
|
||||
object mnu_optionsSampleEvery: TMenuItem
|
||||
Caption = 'Sample every...'
|
||||
object mnu_SampleEvery1Hour: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = 'Hour (default)'
|
||||
Checked = True
|
||||
GroupIndex = 1
|
||||
OnClick = mnu_SampleEvery1HourClick
|
||||
end
|
||||
object mnu_SampleEvery2Hours: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = '2 Hours'
|
||||
OnClick = mnu_SampleEvery2HoursClick
|
||||
end
|
||||
object mnu_SampleEvery4Hours: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = '4 Hours'
|
||||
OnClick = mnu_SampleEvery4HoursClick
|
||||
end
|
||||
object mnu_SampleEvery8Hours: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = '8 Hours'
|
||||
OnClick = mnu_SampleEvery8HoursClick
|
||||
end
|
||||
object mnu_SampleEvery24Hours: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = '24 Hours'
|
||||
GroupIndex = 1
|
||||
OnClick = mnu_SampleEvery24HoursClick
|
||||
end
|
||||
end
|
||||
object mnu_optionsSaveHighLows: TMenuItem
|
||||
AutoCheck = True
|
||||
Caption = 'Save/Load High-Lows to disk'
|
||||
Checked = True
|
||||
OnClick = mnu_optionsSaveHighLowsClick
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
406
applications/foobot/monitor/umainform.pas
Normal file
406
applications/foobot/monitor/umainform.pas
Normal file
@ -0,0 +1,406 @@
|
||||
unit umainform;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Sensors, Forms, Controls, Graphics, Dialogs,
|
||||
ExtCtrls, StdCtrls, Menus, foobot_utility, uCryptIni, Variants, dateutils,
|
||||
uconfigform;
|
||||
|
||||
CONST
|
||||
ONEMINUTE = 60000;
|
||||
ONEHOUR = ONEMINUTE * 60;
|
||||
TWOHOURS = ONEHOUR * 2;
|
||||
FOURHOURS = ONEHOUR * 4;
|
||||
EIGHTHOURS = ONEHOUR * 8;
|
||||
TWENTYFOURHOURS = ONEHOUR * 24;
|
||||
|
||||
|
||||
type
|
||||
|
||||
{ Tmainform }
|
||||
|
||||
Tmainform = class(TForm)
|
||||
as_allpollu: TAnalogSensor;
|
||||
as_co2: TAnalogSensor;
|
||||
as_hum: TAnalogSensor;
|
||||
as_pm: TAnalogSensor;
|
||||
as_tmp: TAnalogSensor;
|
||||
as_voc: TAnalogSensor;
|
||||
grp_pm: TGroupBox;
|
||||
grp_tmp: TGroupBox;
|
||||
grp_hum: TGroupBox;
|
||||
grp_co2: TGroupBox;
|
||||
grp_voc: TGroupBox;
|
||||
grp_allpollu: TGroupBox;
|
||||
grp_highlow: TGroupBox;
|
||||
grp_sensorDisplay: TGroupBox;
|
||||
lbl_pmhigh: TLabel;
|
||||
lbl_tmphigh: TLabel;
|
||||
lbl_humhigh: TLabel;
|
||||
lbl_co2high: TLabel;
|
||||
lbl_vochigh: TLabel;
|
||||
lbl_allpolluhigh: TLabel;
|
||||
lbl_pmlow: TLabel;
|
||||
lbl_tmplow: TLabel;
|
||||
lbl_humlow: TLabel;
|
||||
lbl_co2low: TLabel;
|
||||
lbl_voclow: TLabel;
|
||||
lbl_allpollulow: TLabel;
|
||||
MainMenu1: TMainMenu;
|
||||
mnu_optionsSaveHighLows: TMenuItem;
|
||||
mnu_SampleEvery24Hours: TMenuItem;
|
||||
mnu_SampleEvery8Hours: TMenuItem;
|
||||
mnu_SampleEvery4Hours: TMenuItem;
|
||||
mnu_SampleEvery2Hours: TMenuItem;
|
||||
mnu_SampleEvery1Hour: TMenuItem;
|
||||
mnu_optionsSampleEvery: TMenuItem;
|
||||
mnu_optionsTakeReadingNow: TMenuItem;
|
||||
mnu_optionsShowHighsAndLows: TMenuItem;
|
||||
mnu_options: TMenuItem;
|
||||
mnu_fileExit: TMenuItem;
|
||||
mnu_file: TMenuItem;
|
||||
tmr_foobot: TTimer;
|
||||
procedure FormActivate(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure mnu_fileExitClick(Sender: TObject);
|
||||
procedure mnu_optionsSaveHighLowsClick(Sender: TObject);
|
||||
procedure mnu_optionsShowHighsAndLowsClick(Sender: TObject);
|
||||
procedure mnu_optionsTakeReadingNowClick(Sender: TObject);
|
||||
procedure mnu_SampleEvery1HourClick(Sender: TObject);
|
||||
procedure mnu_SampleEvery24HoursClick(Sender: TObject);
|
||||
procedure mnu_SampleEvery2HoursClick(Sender: TObject);
|
||||
procedure mnu_SampleEvery4HoursClick(Sender: TObject);
|
||||
procedure mnu_SampleEvery8HoursClick(Sender: TObject);
|
||||
procedure tmr_foobotTimer(Sender: TObject);
|
||||
private
|
||||
sSecretKey, sFoobotUserName, sUUID: string;
|
||||
bShowHighsAndLows: boolean;
|
||||
iFudgeFactor: integer;
|
||||
iSampleInterval:Integer;
|
||||
procedure DisplayReadings;
|
||||
procedure UpdateGuage(Sender: TAnalogSensor; SensorNumber: integer);
|
||||
procedure UpdateHighLow(SensorNumber: integer);
|
||||
public
|
||||
INI: TCryptINIfile;
|
||||
end;
|
||||
|
||||
var
|
||||
mainform: Tmainform;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
{ Tmainform }
|
||||
|
||||
procedure Tmainform.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Caption := Application.Title;
|
||||
Icon := Application.Icon;
|
||||
INI := TCryptINIfile.Create(GetAppConfigFile(False));
|
||||
if INI.IsVirgin then
|
||||
begin
|
||||
INI.WriteIdent('Gordon Bamber', '(c)2016', 'GPLV2',
|
||||
'minesadorada@charcodelvalle.com', True);
|
||||
end;
|
||||
if not INI.VerifyIdent('41d10218d247980fc5e871b6b7844483') then
|
||||
begin
|
||||
ShowMessage(Application.Title +
|
||||
' has been tampered wth. Please re-install from a trusted source.');
|
||||
FreeAndNil(INI);
|
||||
Application.Terminate;
|
||||
end;
|
||||
INI.SectionHashing:=FALSE;
|
||||
ResetHighLows;
|
||||
iFudgeFactor := 20;
|
||||
ClientHeight := grp_sensorDisplay.Height + grp_highlow.Height + iFudgeFactor;
|
||||
bShowHighsAndLows := True;
|
||||
end;
|
||||
|
||||
procedure Tmainform.FormActivate(Sender: TObject);
|
||||
Var sTempFoobotUserName,sTempSecretKey:String;
|
||||
|
||||
begin
|
||||
// Allow user to enter values in INIFile
|
||||
sTempFoobotUserName:=INI.ReadUnencryptedString('Config','Foobot User','unknown');
|
||||
sTempSecretKey:=INI.ReadUnencryptedString('Config', 'Secret Key', 'unknown');
|
||||
if ((sTempFoobotUserName <> 'unknown') and (sTempSecretKey <> 'unknown')) then
|
||||
begin
|
||||
INI.WriteString('Foobot', 'Foobot User', sTempFoobotUserName);
|
||||
INI.DeleteKey('Config','Foobot User');
|
||||
INI.WriteString('Foobot', 'Secret Key', sTempSecretKey);
|
||||
INI.DeleteKey('Config','Secret Key');
|
||||
end;
|
||||
// Fetch Username and API_KEY
|
||||
sFoobotUserName := INI.ReadString('Foobot', 'Foobot User', 'unknown');
|
||||
sSecretKey := INI.ReadString('Foobot', 'Secret Key', 'unknown');
|
||||
if ((sFoobotUserName <> 'unknown') and (sSecretKey <> 'unknown')) then
|
||||
begin
|
||||
Hide;
|
||||
if FetchFoobotIdentity(sFoobotUserName, sSecretKey) then
|
||||
begin
|
||||
if FoobotIdentityObject.FoobotIdentityList.Count > 0 then
|
||||
begin
|
||||
sUUID := FoobotIdentityObject.FoobotIdentityList.Items[0].uuid;
|
||||
SaveLoadHighLows:=INI.ReadBool('Foobot','SaveLoadHighLows',TRUE);
|
||||
mnu_optionsSaveHighLows.Checked:=SaveLoadHighLows;
|
||||
If SaveLoadHighLows then LoadHighLows;
|
||||
mnu_optionsTakeReadingNow.Click;
|
||||
// Switch off for testing
|
||||
tmr_foobot.Interval:=ONEHOUR;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
Show;
|
||||
end;
|
||||
end
|
||||
else Close;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// No valid cfg. Show config form
|
||||
Hide;
|
||||
Application.ProcessMessages;
|
||||
configform.ShowModal;
|
||||
// If user quit without data, then bail out
|
||||
If NOT configform.bValid then
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
// Store encrypted Username and API_KEY
|
||||
INI.WriteString('Foobot', 'Foobot User', configform.FoobotUsername);
|
||||
INI.WriteString('Foobot', 'Secret Key', configform.FoobotSecretKey);
|
||||
//sFoobotUserName := INI.ReadString('Foobot', 'Foobot User', 'unknown');
|
||||
//sSecretKey := INI.ReadString('Foobot', 'Secret Key', 'unknown');
|
||||
ShowMessage('Click OK to store settings and close the app.' + LineEnding + 'New settings are applied on resart.');
|
||||
Close;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FreeAndNil(INI);
|
||||
end;
|
||||
|
||||
procedure Tmainform.FormShow(Sender: TObject);
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_fileExitClick(Sender: TObject);
|
||||
begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_optionsSaveHighLowsClick(Sender: TObject);
|
||||
begin
|
||||
SaveLoadHighLows:=mnu_optionsSaveHighLows.Checked;
|
||||
INI.WriteBool('Foobot','SaveLoadHighLows',SaveLoadHighLows);
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_optionsShowHighsAndLowsClick(Sender: TObject);
|
||||
begin
|
||||
if mnu_optionsShowHighsAndLows.Checked then
|
||||
mainform.ClientHeight := grp_sensorDisplay.Height + grp_highlow.Height + iFudgeFactor
|
||||
else
|
||||
mainform.ClientHeight := grp_sensorDisplay.Height + iFudgeFactor;
|
||||
bShowHighsAndLows := mnu_optionsShowHighsAndLows.Checked;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_optionsTakeReadingNowClick(Sender: TObject);
|
||||
begin
|
||||
mainform.Cursor := crHourGlass;
|
||||
// Only Foobot #0
|
||||
if FetchFoobotData(dfLast, 0, 0, 0, 0, 0, sSecretKey) then
|
||||
DisplayReadings
|
||||
else
|
||||
ShowMessage('Sorry - no readings available');
|
||||
mainform.Cursor := crDefault;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_SampleEvery1HourClick(Sender: TObject);
|
||||
begin
|
||||
tmr_foobot.Enabled:=FALSE;
|
||||
tmr_foobot.Interval:=ONEHOUR;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_SampleEvery24HoursClick(Sender: TObject);
|
||||
begin
|
||||
tmr_foobot.Enabled:=FALSE;
|
||||
tmr_foobot.Interval:=TWENTYFOURHOURS;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_SampleEvery2HoursClick(Sender: TObject);
|
||||
begin
|
||||
tmr_foobot.Enabled:=FALSE;
|
||||
tmr_foobot.Interval:=TWOHOURS;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_SampleEvery4HoursClick(Sender: TObject);
|
||||
begin
|
||||
tmr_foobot.Enabled:=FALSE;
|
||||
tmr_foobot.Interval:=FOURHOURS;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tmainform.mnu_SampleEvery8HoursClick(Sender: TObject);
|
||||
begin
|
||||
tmr_foobot.Enabled:=FALSE;
|
||||
tmr_foobot.Interval:=EIGHTHOURS;
|
||||
tmr_foobot.Enabled:=TRUE;
|
||||
end;
|
||||
|
||||
procedure Tmainform.tmr_foobotTimer(Sender: TObject);
|
||||
begin
|
||||
if FetchFoobotData(dfLast, 0, 0, 0, 0, 0, sSecretKey) then
|
||||
DisplayReadings;
|
||||
end;
|
||||
|
||||
procedure Tmainform.UpdateHighLow(SensorNumber: integer);
|
||||
begin
|
||||
case SensorNumber of
|
||||
1:
|
||||
begin
|
||||
lbl_pmhigh.Caption := Format(
|
||||
'High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_pmLow.Caption := Format(
|
||||
'Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) +
|
||||
LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(
|
||||
FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
2:
|
||||
begin
|
||||
lbl_tmphigh.Caption := Format(
|
||||
'High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_tmpLow.Caption := Format(
|
||||
'Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) +
|
||||
LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(
|
||||
FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
3:
|
||||
begin
|
||||
lbl_humhigh.Caption := Format(
|
||||
'High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_humLow.Caption := Format(
|
||||
'Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) +
|
||||
LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(
|
||||
FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
4:
|
||||
begin
|
||||
lbl_co2high.Caption := Format(
|
||||
'High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_co2Low.Caption := Format(
|
||||
'Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) +
|
||||
LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(
|
||||
FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
5:
|
||||
begin
|
||||
lbl_vochigh.Caption := Format(
|
||||
'High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_vocLow.Caption := Format(
|
||||
'Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) +
|
||||
LineEnding + 'on ' + FormatDateTime('dd/mm tt', TDateTime(
|
||||
FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
6:
|
||||
begin
|
||||
lbl_allpolluhigh.Caption :=
|
||||
Format('High: %f %s', [double(FoobotDataHighs[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataHighTimes[SensorNumber]));
|
||||
lbl_allpollulow.Caption :=
|
||||
Format('Low: %f %s', [double(FoobotDataLows[SensorNumber]),
|
||||
FoobotDataObject.Units[SensorNumber]]) + LineEnding + 'on ' +
|
||||
FormatDateTime('dd/mm tt', TDateTime(FoobotDataLowTimes[SensorNumber]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.UpdateGuage(Sender: TAnalogSensor; SensorNumber: integer);
|
||||
begin
|
||||
with Sender do
|
||||
begin
|
||||
case SensorNumber of
|
||||
1:
|
||||
begin
|
||||
Value := FoobotData_pm[0];
|
||||
Caption := Format('PM (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
2:
|
||||
begin
|
||||
Value := FoobotData_tmp[0];
|
||||
Caption := Format('Temp (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
3:
|
||||
begin
|
||||
Value := FoobotData_hum[0];
|
||||
Caption := Format('Hum. (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
4:
|
||||
begin
|
||||
Value := FoobotData_co2[0];
|
||||
Caption := Format('CO2 (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
5:
|
||||
begin
|
||||
Value := FoobotData_voc[0];
|
||||
Caption := Format('VOC (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
6:
|
||||
begin
|
||||
Value := FoobotData_allpollu[0];
|
||||
Caption := Format('All (%s): ', [FoobotDataObject.Units[SensorNumber]]);
|
||||
end;
|
||||
end;
|
||||
if Value > ValueMax then
|
||||
ValueMax := Value;
|
||||
ValueYellow := ValueMax;
|
||||
if Value > ValueRed then
|
||||
ValueRed := Value;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Tmainform.DisplayReadings;
|
||||
var
|
||||
iCount: integer;
|
||||
begin
|
||||
if FoobotDataObjectToArrays = True then
|
||||
begin
|
||||
mainform.Caption := Format('Foobot "%s" - ',
|
||||
[FoobotIdentityObject.FoobotIdentityList[0].Name]) +
|
||||
FormatDateTime('dd/mm/yyyy - tt', FoobotData_time[0]);
|
||||
UpdateGuage(as_pm, 1);
|
||||
UpdateGuage(as_tmp, 2);
|
||||
UpdateGuage(as_hum, 3);
|
||||
UpdateGuage(as_co2, 4);
|
||||
UpdateGuage(as_voc, 5);
|
||||
UpdateGuage(as_allpollu, 6);
|
||||
if bShowHighsAndLows then
|
||||
for iCount := 1 to 6 do
|
||||
UpdateHighLow(iCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
Reference in New Issue
Block a user