SmartFactory_NEOL/SOURCE/Agent,Kiosk/NILM_Manager_D104/uMain.~pas
2026-09-04 14:08:41 +09:00

653 lines
19 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uMQTTComps, StdCtrls, Grids, BaseGrid, AdvGrid, uMQTT ,uSysLog,
ExtCtrls, DateUtils, ComCtrls, Menus, ScktComp, inifiles, FarmSMem,
JsonConvertor, Buttons, IntNum, NumEdit, ZConnection, MQTT,
ZAbstractDataset, ZDataset, DB, ZAbstractRODataset;
type
TfrmMain = class(TForm)
MQTTClient1: TMQTTClient;
initTimer: TTimer;
StatusBar1: TStatusBar;
MainMenu1: TMainMenu;
File1: TMenuItem;
Config1: TMenuItem;
N2: TMenuItem;
Connect1: TMenuItem;
Disconnect1: TMenuItem;
JsonConvertor1: TJsonConvertor;
insertTimer: TTimer;
ListBox1: TListBox;
File2: TMenuItem;
DebugMode1: TMenuItem;
N8: TMenuItem;
ProgramExit1: TMenuItem;
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ZConnection1: TZConnection;
ZReadOnlyQuery1: TZReadOnlyQuery;
ZQuery1: TZQuery;
NILM1: TMenuItem;
Edit1: TMenuItem;
N1: TMenuItem;
procedure MQTTClient1ClientID(Sender: TObject;
var aClientID: UTF8String);
procedure MQTTClient1EnableChange(Sender: TObject);
procedure MQTTClient1Failure(Sender: TObject; aReason: Integer;
var CloseClient: Boolean);
procedure MQTTClient1Mon(Sender: TObject; aStr: String);
procedure MQTTClient1Msg(Sender: TObject; aTopic: UTF8String;
aMessage: String; aQos: TMQTTQOSType; aRetained: Boolean);
procedure MQTTClient1Offline(Sender: TObject; Graceful: Boolean);
procedure MQTTClient1Online(Sender: TObject);
procedure initTimerTimer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Connect1Click(Sender: TObject);
procedure Disconnect1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure insertTimerTimer(Sender: TObject);
procedure ListBox1DblClick(Sender: TObject);
procedure ProgramExit1Click(Sender: TObject);
procedure DebugMode1Click(Sender: TObject);
procedure Config1Click(Sender: TObject);
procedure Edit1Click(Sender: TObject);
procedure N1Click(Sender: TObject);
private
{ Private declarations }
debug_mode : Boolean;
msg_flaw_stop : boolean;
dumyTopic : string;
debug_mode_count, hubPort : integer;
procedure InsertData(topic, msg : string);
public
//read_gwid : integer;
fIOTGW : array [1..max_gw] of TIOTGW;
fNILM : array [1..max_gw] of TNILM;
appPath : string;
dbIP, dbPW, dbUser, dbSchema : string;
dbPort, brokerPort : integer;
mqtt_topic, brokerIP, ClientID, mqtt_user, mqtt_pw : string;
aRetain: Boolean;
old_NilmID : integer;
aQos: TMQTTQOSType;
procedure PrintLog(msg, msgType : String);
procedure MQTTParsing(data, aTopic : String);
procedure ClearIOTGW();
procedure SendMQTT_CtrlCommand(sTopic, sMsg : string);
procedure insertSQL(sql : string);
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
uses global, uConfigMQTT, uConfigNILM, uDevConfig;
procedure TfrmMain.ClearIOTGW();
var
p, i : integer;
begin
for p:=1 to max_gw do
begin
fIOTGW[p]._TOPIC := '';
for i:=0 to 15 do fIOTGW[p]._DI[i] := false;
for i:=0 to 7 do fIOTGW[p]._DO[i] := false;
for i:=0 to 3 do fIOTGW[p]._AI[i] := 0;
for i:=0 to 9 do fIOTGW[p]._TEMP[i] := 0.0;
for i:=0 to 9 do fIOTGW[p]._HUMID[i] := 0.0;
fIOTGW[p].run_dd := 0;
fIOTGW[p].run_hh := 0;
fIOTGW[p].run_mm := 0;
fIOTGW[p].run_ss := 0;
fNILM[p].idxNo := 0;
fNILM[p]._TOPIC := '';
fNILM[p]._NAME := '';
for i:=1 to 3 do
begin
fNILM[p]._VALUE.PF[i] := 0.0;
fNILM[p]._VALUE.Vrms[i] := 0.0;
fNILM[p]._VALUE.Irms[i] := 0.0;
fNILM[p]._VALUE._Var[i] := 0.0;
fNILM[p]._VALUE.Va[i] := 0.0;
fNILM[p]._VALUE.Pwr[i] := 0.0;
fNILM[p]._VALUE.Gyro[i] := 0.0;
fNILM[p]._VALUE.Accel[i] := 0.0;
end;
fNILM[p]._VALUE.TempC := 0;
fNILM[p].rcvCount := 0;
fNILM[p].oldRcvCount := 0;
end;
end;
procedure TfrmMain.InsertData(topic, msg : string);
begin
end;
//MQTT <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ľ<EFBFBD>
procedure TfrmMain.MQTTParsing(data, aTopic : String);
var
tempTopic_list : TStringList;
aVal, pf, Vrms, Irms, Var_, Va, Pwr, gX, gY, gZ, aX, aY, aZ, TempC : Single;
sVal : String;
nilmID, ch : integer;
sql : string;
begin
try
if Trim(data) <> '' then
begin
InsertData(aTopic, data);
try
tempTopic_list := TStringList.Create;
Strsplit('/',aTopic, tempTopic_list);
if tempTopic_list.Count>3 then
begin
nilmID := StrToIntDef(tempTopic_list.Strings[ tempTopic_list.Count-1 ], 0);
Label1.Caption := format('NILM ID = %d',[nilmID]);
if (nilmID > 0) and (nilmID <= max_gw) and (fNILM[nilmID].idxNo>0) then
begin
JsonConvertor1.srcJson_Colon := data;
ch := StrToIntDef(JsonConvertor1.GetItemValue('CH'), 0);
case ch of
01, 02 :
begin
pf := StrToFloatDef(JsonConvertor1.GetItemValue('PF'), 0.0);
Vrms := StrToFloatDef(JsonConvertor1.GetItemValue('Vrms'), 0.0);
Irms := StrToFloatDef(JsonConvertor1.GetItemValue('Irms'), 0.0);
Var_ := StrToFloatDef(JsonConvertor1.GetItemValue('Var'), 0.0);
Va := StrToFloatDef(JsonConvertor1.GetItemValue('Va'), 0.0);
Pwr := StrToFloatDef(JsonConvertor1.GetItemValue('Pwr'), 0.0);
fNILM[nilmID]._VALUE.PF[ch] := pf;
fNILM[nilmID]._VALUE.Vrms[ch] := Vrms;
fNILM[nilmID]._VALUE.Irms[ch] := Irms;
fNILM[nilmID]._VALUE._Var[ch] := Var_;
fNILM[nilmID]._VALUE.Va[ch] := Va;
fNILM[nilmID]._VALUE.Pwr[ch] := Pwr;
if ch = 01 then Label2.Caption := format('PF : %.3f, Vrms : %.3f, Irms : %.3f, Var : %.3f, Va : %.3f, Pwr : %.3f',[pf, Vrms, Irms, Var_, Va, Pwr]);
if ch = 02 then Label3.Caption := format('PF : %.3f, Vrms : %.3f, Irms : %.3f, Var : %.3f, Va : %.3f, Pwr : %.3f',[pf, Vrms, Irms, Var_, Va, Pwr]);
end;
03 :
begin
gX := StrToFloatDef(JsonConvertor1.GetItemValue('gX'), 0.0);
gY := StrToFloatDef(JsonConvertor1.GetItemValue('gY'), 0.0);
gZ := StrToFloatDef(JsonConvertor1.GetItemValue('gZ'), 0.0);
aX := StrToFloatDef(JsonConvertor1.GetItemValue('aX'), 0.0);
aY := StrToFloatDef(JsonConvertor1.GetItemValue('aY'), 0.0);
aZ := StrToFloatDef(JsonConvertor1.GetItemValue('aZ'), 0.0);
TempC := StrToFloatDef(JsonConvertor1.GetItemValue('TempC'), 0.0);
Label4.Caption := format('gX : %.3f, gY : %.3f, gZ : %.3f, aX : %.3f, aY : %.3f, aZ : %.3f, Temp : %.2f',[gX, gY, gZ, aX, aY, aZ, TempC]);
fNILM[nilmID]._VALUE.Gyro[1] := gX;
fNILM[nilmID]._VALUE.Gyro[2] := gY;
fNILM[nilmID]._VALUE.Gyro[3] := gZ;
fNILM[nilmID]._VALUE.Accel[1] := aX;
fNILM[nilmID]._VALUE.Accel[2] := aY;
fNILM[nilmID]._VALUE.Accel[3] := aZ;
fNILM[nilmID]._VALUE.TempC := TempC;
fNILM[nilmID].rcvCount := fNILM[nilmID].rcvCount + 1;
if fNILM[nilmID].rcvCount > 65535 then fNILM[nilmID].rcvCount := 1;
end;
end;
end;
end;
finally
tempTopic_list.Free;
end;
end;
except
end;
end;
procedure TfrmMain.PrintLog(msg, msgType : string);
var
f : TextFile;
log: TStringList;
i : integer;
logfile, buf : string;
begin
if ListBox1.Items.Count >= 300 then ListBox1.Items.Clear;
if msgType = 'DEBUG' then
begin
if debug_mode then
begin
if not msg_flaw_stop then ListBox1.Items.Insert(0, FormatDateTime('hh:nn:ss :: ',now)+msg);
end;
end else if msgType = 'SYS' then
begin
ListBox1.Items.Insert(0, FormatDateTime('hh:nn:ss :: ',now)+msg);
logfile := '';
logfile := appPath+'log\'+formatdatetime('yyyymmddhh',now())+'.log';
if FileExists(logfile) then
begin
log := TStringList.Create;
AssignFile(f, logfile);
reset(f);
while not eof(f) do
begin
ReadLn(f, buf);
log.Add(buf);
end;
log.add(msg);
CloseFile(F);
AssignFile(f, logfile);
rewrite(f);
for i := 0 to log.Count - 1 do
begin
WriteLn(f, log.strings[i]);
end;
CloseFile(F);
log.Free;
end else
begin
log := TStringList.Create;
log.add(msg);
AssignFile(f, logfile);
rewrite(f);
for i := 0 to log.Count - 1 do
begin
WriteLn(f, log.strings[i]);
end;
CloseFile(F);
log.Free;
end;
end;
end;
procedure TfrmMain.MQTTClient1ClientID(Sender: TObject; var aClientID: UTF8String);
begin
PrintLog('ClientID :: ' + aClientID, 'SYS');
end;
procedure TfrmMain.MQTTClient1EnableChange(Sender: TObject);
begin
if TMQTTClient(Sender).Enabled then
printlog('Client is enabled.', 'SYS')
else
printlog('Client is disabled.', 'SYS');
end;
procedure TfrmMain.MQTTClient1Failure(Sender: TObject; aReason: Integer; var CloseClient: Boolean);
begin
printlog('---- Failure Reported ' + FailureNames(aReason), 'SYS');
end;
procedure TfrmMain.MQTTClient1Mon(Sender: TObject; aStr: string);
begin
printlog(aStr, 'SYS');
end;
procedure TfrmMain.MQTTClient1Offline(Sender: TObject; Graceful: Boolean);
begin
if Graceful then
begin
printlog('Client Gracefully Disconnected.', 'SYS');
end
else
begin
printlog('Client Terminated Unexpectedly.', 'SYS');
end;
end;
procedure TfrmMain.MQTTClient1Online(Sender: TObject);
var
s: TStringList;
begin
printlog('Client is online.', 'SYS');
s := TStringList.Create;
s.AddObject(mqtt_topic, TObject(aQos));
MQTTClient1.Subscribe(s);
s.Free;
end;
procedure TfrmMain.MQTTClient1Msg(Sender: TObject; aTopic: UTF8String; aMessage: string; aQos: TMQTTQOSType; aRetained: Boolean);
var
str : string;
a : integer;
begin
str := aMessage;
//PrintLog('Message : '+str);
if (Pos('{',str)<=0) or (Pos('}',str)<=0) then
begin
PrintLog('[Not Entry]Topic : '+Utf8ToAnsi(aTopic), 'DEBUG');
end else
begin
PrintLog('Topic : '+Utf8ToAnsi(aTopic)+', Msg='+str, 'DEBUG');
MQTTParsing(str,Utf8ToAnsi(aTopic));
end;
//FRecvTime := now;//IncSecond(Now + (FTimeout -1));
//NotifySessionReadOk(FPtrSession);
end;
procedure TfrmMain.initTimerTimer(Sender: TObject);
var
ini : TInifile;
pwd : string;
begin
old_NilmID := 0;
debug_mode := false;
debug_mode_count := 0;
msg_flaw_stop := false;
ListBox1.Clear;
mqtt_topic := '';
mqtt_topic := 'QST/NILM/LVDT/#';
pwd := '';
pwd := appPath+'NILM_Manager.ini';
if FileExists(pwd) then
begin
ini := TInifile.Create(pwd);
with ini do
begin
mqtt_topic := ReadString('MQTT','TOPIC',mqtt_topic);
brokerIP := ReadString('MQTT','BrokerIP','183.111.125.203');
brokerPort := ReadInteger('MQTT','BrokerPort',1883);
ClientID := ReadString('MQTT','ClientID','NILM_1st');
mqtt_user := ReadString('MQTT','User','qsentech');
mqtt_pw := ReadString('MQTT','Password','qsentech!1233');
dbIP := ReadString('DATABASE','IP','192.168.200.199');
dbUser := ReadString('DATABASE','User','root');
dbPW := ReadString('DATABASE','PW','1233');
dbSchema := ReadString('DATABASE','Schema','nilm');
dbPort := ReadInteger('DATABASE','Port',3306);
hubPort := ReadInteger('MQTT_HUB','Port',6969);
end;
ini.Free;
end;
Statusbar1.Panels.Items[2].Text := format('%d',[MQTTClient1.Port]);
Statusbar1.Panels.Items[3].Text := mqtt_topic;
MQTTClient1.Activate(false);
Sleep(300);
MQTTClient1.ClientID := ClientID;
MQTTClient1.Host := brokerIP;
MQTTClient1.Port := brokerPort;
MQTTClient1.Username := mqtt_user;
MQTTClient1.Password := mqtt_pw;
MQTTClient1.Activate(true);
if ZConnection1.Connected then ZConnection1.disConnect();
Sleep(300);
ZConnection1.HostName := dbIP;
ZConnection1.Port := dbPort;
ZConnection1.User := dbUser;
ZConnection1.Password := dbPW;
ZConnection1.Database := dbSchema;
try
if not ZConnection1.Connected then ZConnection1.Connect();
except
on e : exception do
begin
printlog('Database Connect Error :: '+e.Message, 'DB');
end;
end;
frmNILM.ShowNILM();
frmDevConfig.ShowDev();
insertTimer.Enabled := True;
initTimer.Enabled := false;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MQTTClient1.Activate(false);
end;
procedure TfrmMain.Connect1Click(Sender: TObject);
begin
MQTTClient1.Activate(false);
sleep(300);
MQTTClient1.Activate(true);
end;
procedure TfrmMain.Disconnect1Click(Sender: TObject);
begin
MQTTClient1.Activate(false);
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
appPath := '';
appPath := ExtractFilePath(Application.ExeName);
if not DirectoryExists(appPath + 'log') then
if not CreateDir(appPath + 'log') then
raise Exception.Create('Cannot create ' + appPath + 'log');
ClearIOTGW();
end;
procedure TfrmMain.SendMQTT_CtrlCommand(sTopic, sMsg : string);
var
pTopic : UTF8String;
begin
pTopic := '';
pTopic := sTopic;
MQTTClient1.Publish(pTopic, sMsg, aQos, false);
end;
procedure TfrmMain.insertSQL(sql : string);
begin
try
try
if not ZConnection1.Connected then ZConnection1.Connect();
if ZConnection1.Connected then
begin
ZQuery1.Active := false;
ZQuery1.SQL.Clear;
ZQuery1.SQL.Add(sql);
ZQuery1.ExecSQL;
end;
finally
if ZConnection1.Connected then ZConnection1.Disconnect;
end;
except
on e : exception do
begin
printlog('[insertSQL()]Database Connect Error :: '+e.Message, 'DB');
end;
end;
end;
procedure TfrmMain.insertTimerTimer(Sender: TObject);
var
pMsg, S, sql : string;
pTopic : UTF8String;
p : integer;
begin
if debug_mode then
begin
Statusbar1.Panels.Items[0].Text := 'DEBUG';
Inc(debug_mode_count, 1);
if debug_mode_count > 1800 then // Debug Mode<64><65> 30<33>и<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 24<32>ð<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
begin
debug_mode_count := 0;
debug_mode := false;
DebugMode1.Checked := debug_mode;
end;
end else
begin
Statusbar1.Panels.Items[0].Text := 'RUN';
end;
if (MQTTClient1.Online) then
begin
Statusbar1.Panels.Items[1].Text := 'CONN';
// dumyTopic := '';
// dumyTopic := 'SMART-FARM/QST/MQTT_HUB/PUB/0000';
// pTopic := '';
// pTopic := dumyTopic;
// pMsg := '';
// S := '';
// S := formatdatetime('yyyymmddhhnnss',now());
// pMsg := format('{DATE_TIME=%s}', [S]);;
// MQTTClient1.Publish(pTopic, pMsg, aQos, false);
end else
begin
Statusbar1.Panels.Items[1].Text := 'DisCON';
end;
for p:=1 to max_gw do
begin
if (fNILM[p].rcvCount>0) and (fNILM[p].rcvCount <> fNILM[p].oldRcvCount) then
begin
fNILM[p].oldRcvCount := fNILM[p].RcvCount;
sql := '';
sql := 'UPDATE nilm_value SET '+
'pf_1='+floattostr(fNILM[p]._VALUE.PF[1] )+', '+
'pf_2='+floattostr(fNILM[p]._VALUE.PF[2] )+', '+
'pf_3='+floattostr(fNILM[p]._VALUE.PF[3] )+', '+
'Vrms_1='+floattostr(fNILM[p]._VALUE.Vrms[1] )+', '+
'Vrms_2='+floattostr(fNILM[p]._VALUE.Vrms[2] )+', '+
'Vrms_3='+floattostr(fNILM[p]._VALUE.Vrms[3] )+', '+
'Irms_1='+floattostr(fNILM[p]._VALUE.Irms[1] )+', '+
'Irms_2='+floattostr(fNILM[p]._VALUE.Irms[2] )+', '+
'Irms_3='+floattostr(fNILM[p]._VALUE.Irms[3] )+', '+
'Var_1='+floattostr(fNILM[p]._VALUE._Var[1] )+', '+
'Var_2='+floattostr(fNILM[p]._VALUE._Var[2] )+', '+
'Var_3='+floattostr(fNILM[p]._VALUE._Var[3] )+', '+
'Va_1='+floattostr(fNILM[p]._VALUE.Va[1] )+', '+
'Va_2='+floattostr(fNILM[p]._VALUE.Va[2] )+', '+
'Va_3='+floattostr(fNILM[p]._VALUE.Va[3] )+', '+
'Pwr_1='+floattostr(fNILM[p]._VALUE.Pwr[1] )+', '+
'Pwr_2='+floattostr(fNILM[p]._VALUE.Pwr[2] )+', '+
'Pwr_3='+floattostr(fNILM[p]._VALUE.Pwr[3] )+', '+
'gX='+floattostr(fNILM[p]._VALUE.Gyro[1])+', '+
'gY='+floattostr(fNILM[p]._VALUE.Gyro[2])+', '+
'gZ='+floattostr(fNILM[p]._VALUE.Gyro[3])+', '+
'aX='+floattostr(fNILM[p]._VALUE.Accel[1])+', '+
'aY='+floattostr(fNILM[p]._VALUE.Accel[2])+', '+
'aZ='+floattostr(fNILM[p]._VALUE.Accel[3])+', '+
'TempC='+floattostr(fNILM[p]._VALUE.TempC)+', '+
'lastUpdate=now()'+
' WHERE NilmID='+inttostr(p);
if fNILM[p].idxNo > 0 then insertSQL(sql);
sql := '';
sql := 'INSERT INTO '+format('nilm_%.5d',[fNILM[p].idxNo])+' VALUES(null, '+
''+inttostr(p)+', '+ // Nilm ID
''+floattostr(fNILM[p]._VALUE.PF[1] )+', 0, '+
''+floattostr(fNILM[p]._VALUE.Vrms[1] )+', '+
''+floattostr(fNILM[p]._VALUE.Irms[1] )+', '+
''+floattostr(fNILM[p]._VALUE._Var[1] )+', '+
''+floattostr(fNILM[p]._VALUE.Va[1] )+', '+
''+floattostr(fNILM[p]._VALUE.Pwr[1] )+', '+
''+floattostr(fNILM[p]._VALUE.PF[2] )+', 0, '+
''+floattostr(fNILM[p]._VALUE.Vrms[2] )+', '+
''+floattostr(fNILM[p]._VALUE.Irms[2] )+', '+
''+floattostr(fNILM[p]._VALUE._Var[2] )+', '+
''+floattostr(fNILM[p]._VALUE.Va[2] )+', '+
''+floattostr(fNILM[p]._VALUE.Pwr[2] )+', '+
''+floattostr(fNILM[p]._VALUE.PF[3] )+', 0, '+
''+floattostr(fNILM[p]._VALUE.Vrms[3] )+', '+
''+floattostr(fNILM[p]._VALUE.Irms[3] )+', '+
''+floattostr(fNILM[p]._VALUE._Var[3] )+', '+
''+floattostr(fNILM[p]._VALUE.Va[3] )+', '+
''+floattostr(fNILM[p]._VALUE.Pwr[3] )+', '+
''+floattostr(fNILM[p]._VALUE.Gyro[1])+', '+
''+floattostr(fNILM[p]._VALUE.Gyro[2])+', '+
''+floattostr(fNILM[p]._VALUE.Gyro[3])+', '+
''+floattostr(fNILM[p]._VALUE.Accel[1])+', '+
''+floattostr(fNILM[p]._VALUE.Accel[2])+', '+
''+floattostr(fNILM[p]._VALUE.Accel[3])+', '+
''+floattostr(fNILM[p]._VALUE.TempC)+', '+
'now())';
if fNILM[p].idxNo > 0 then insertSQL(sql);
end;
end;
end;
procedure TfrmMain.ListBox1DblClick(Sender: TObject);
begin
msg_flaw_stop := not msg_flaw_stop;
end;
procedure TfrmMain.ProgramExit1Click(Sender: TObject);
begin
frmMain.Close;
end;
procedure TfrmMain.DebugMode1Click(Sender: TObject);
begin
DebugMode1.Checked := not DebugMode1.Checked;
debug_mode := DebugMode1.Checked;
debug_mode_count := 0;
end;
procedure TfrmMain.Config1Click(Sender: TObject);
begin
frmConfigMQTT.Show;
end;
procedure TfrmMain.Edit1Click(Sender: TObject);
begin
frmNILM.Show;
end;
procedure TfrmMain.N1Click(Sender: TObject);
begin
frmDevConfig.Show;
end;
end.