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

453 lines
12 KiB
ObjectPascal

unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uMQTTComps, StdCtrls, Grids, BaseGrid, AdvGrid, uMQTT,
ExtCtrls, DateUtils, ComCtrls, Menus, ScktComp, inifiles,
Buttons, ZConnection, MQTT,
ZAbstractDataset, ZDataset, DB, ZAbstractRODataset, VclTee.TeeGDIPlus,
VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart,
ZAbstractConnection;
type
TfrmMain = class(TForm)
initTimer: TTimer;
StatusBar1: TStatusBar;
MainMenu1: TMainMenu;
ListBox1: TListBox;
File2: TMenuItem;
ProgramExit1: TMenuItem;
ZConnection1: TZConnection;
ZReadOnlyQuery1: TZReadOnlyQuery;
ZQuery1: TZQuery;
N3: TMenuItem;
CONFIG1: TMenuItem;
NILM2: TMenuItem;
Device1: TMenuItem;
N1: TMenuItem;
Panel1: TPanel;
TreeView1: TTreeView;
Splitter1: TSplitter;
Panel2: TPanel;
Timer1: TTimer;
MQTTClient1: TMQTTClient;
Chart_main: TChart;
procedure initTimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ProgramExit1Click(Sender: TObject);
procedure CONFIG1Click(Sender: TObject);
procedure NILM2Click(Sender: TObject);
procedure Device1Click(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
Series1: TLineSeries; // 전력량 데이터를 저장할 라인 시리즈
Series2: TLineSeries; // 전력량 데이터를 저장할 라인 시리즈
Series3: TLineSeries; // 전력량 데이터를 저장할 라인 시리즈
Series4: TLineSeries; // 전력량 데이터를 저장할 라인 시리즈
Series5: TLineSeries; // 전력량 데이터를 저장할 라인 시리즈
select_nilmID, select_nilm_idxNo : integer;
FMaxPoints: Integer; // 차트에 표시할 최대 데이터 포인트 수
procedure InitializeChart;
public
//read_gwid : integer;
fNILM : array [1..max_gw] of TNILM;
appPath : string;
hubPort : integer;
dbIP, dbPW, dbUser, dbSchema, mqtt_topic, ClientID : string;
dbPort, brokerPort : integer;
brokerIP, mqtt_user, mqtt_pw : string;
old_NilmID : integer;
procedure PrintLog(msg : String);
procedure ClearIOTGW();
procedure insertSQL(sql : string);
procedure ShowNilmTreeView();
end;
var
frmMain: TfrmMain;
no : Double;
implementation
{$R *.dfm}
uses global, uConfigMQTT, uConfigNILM, uDevConfig, math;
procedure TfrmMain.ClearIOTGW();
var
p, i : integer;
begin
for p:=1 to max_gw do
begin
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.ShowNilmTreeView();
var
nilmID : integer;
subNode : TTreenode;
begin
TreeView1.Items.Clear;
for nilmID:=1 to max_gw do
begin
if fNILM[nilmID].idxNo> 0 then
begin
subNode := TreeView1.Items.AddChild(nil, format('%.5d',[nilmID]));
TreeView1.items.AddChild(subNode, 'IDXNO:'+inttostr(fNILM[nilmID].idxNo));
TreeView1.items.AddChild(subNode, 'NAME :'+fNILM[nilmID]._NAME);
TreeView1.items.AddChild(subNode, 'TOPIC:'+fNILM[nilmID]._TOPIC);
end;
end;
end;
procedure TfrmMain.PrintLog(msg : string);
begin
if ListBox1.Items.Count >= 300 then ListBox1.Items.Clear;
ListBox1.Items.Insert(0, FormatDateTime('hh:nn:ss :: ',now)+msg);
end;
procedure TfrmMain.initTimerTimer(Sender: TObject);
var
ini : TInifile;
pwd : string;
begin
// FANTrend1.SetItem(1, 'PF', clLime, 1, 0);
// FANTrend1.SetItem(2, 'Vrms', clYellow, 300, 0);
// FANTrend1.SetItem(3, 'Irms', clSkyBlue, 10, 0);
// FANTrend1.SetItem(4, 'Pwr', clRed, 5000, 0);
{
Series1.Clear;
Series2.Clear;
Series3.Clear;
Series4.Clear;
Series5.Clear;
}
old_NilmID := 0;
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;
if ZConnection1.Connected then ZConnection1.disConnect();
Sleep(300);
ZConnection1.HostName := dbIP;
ZConnection1.Port := dbPort;
ZConnection1.User := dbUser;
ZConnection1.Password := dbPW;
ZConnection1.Database := dbSchema;
frmNILM.ShowNILM();
frmDevConfig.ShowDev();
ShowNilmTreeView();
Timer1.Enabled := True;
initTimer.Enabled := false;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
appPath := '';
appPath := ExtractFilePath(Application.ExeName);
ClearIOTGW();
FMaxPoints := 30; // 차트에 100개의 데이터 포인트만 표시
// 차트 초기화 함수 호출
InitializeChart;
end;
procedure TfrmMain.InitializeChart;
var
ck : Integer;
begin
// 기존 시리즈가 있다면 모두 제거
Chart_Main.SeriesList.Clear;
Series1 := TLineSeries.Create(Self);
Series2 := TLineSeries.Create(Self);
Series3 := TLineSeries.Create(Self);
Series4 := TLineSeries.Create(Self);
Series5 := TLineSeries.Create(Self);
// 라인 시리즈 추가
Chart_Main.AddSeries(Series1);
Chart_Main.AddSeries(Series2);
Chart_Main.AddSeries(Series3);
Chart_Main.AddSeries(Series4);
// 시리즈 설정
Series1.Title := '실시간 PF';
Series1.Color := clBlue; // 선 색상
Series1.LinePen.Width := 1; // 선 두께
Series1.Pointer.Visible := False; // 포인트 표시 여부 (선만 보려면 False)
// 시리즈 설정
Series2.Title := '실시간 Vrms';
Series2.Color := clGray; // 선 색상
Series2.LinePen.Width := 1; // 선 두께
Series2.Pointer.Visible := False; // 포인트 표시 여부 (선만 보려면 False)
// 시리즈 설정
Series3.Title := '실시간 Irms';
Series3.Color := clGreen; // 선 색상
Series3.LinePen.Width := 1; // 선 두께
Series3.Pointer.Visible := False; // 포인트 표시 여부 (선만 보려면 False)
// 시리즈 설정
Series4.Title := '실시간 Pwr';
Series4.Color := clRed; // 선 색상
Series4.LinePen.Width := 1; // 선 두께
Series4.Pointer.Visible := False; // 포인트 표시 여부 (선만 보려면 False)
// 차트 축 설정
Chart_Main.Axes.Bottom.Title.Caption := '시간';
Chart_Main.Axes.Left.Title.Caption := 'PF / Vrms / Irms / Pwr';
Chart_Main.Axes.Left.Minimum := 0; // 최소값 설정 (필요에 따라 조절)
Chart_Main.Axes.Left.Maximum := 100; // 최대값 설정 (필요에 따라 조절)
Chart_Main.Axes.Bottom.DateTimeFormat := 'mm:ss'; // 시간 포맷 설정
// 차트 제목
Chart_Main.Title.Text.Text := '실시간 (PF / Vrms / Irms / Pwr) 모니터링';
Chart_Main.Title.Visible := True;
// 범례 표시
Chart_Main.Legend.Visible := True;
// 애니메이션 효과 (선택 사항)
// Chart1.Options.ClipSeries := False; // 스크롤링 시 부드러운 움직임
for ck := 0 to FMaxPoints-1 do begin
Series1.AddXY(ck, 0, '', clBlue); // x: 시간, y: PF
Series2.AddXY(ck, 0, '', clGray); // x: 시간, y: Vrms
Series3.AddXY(ck, 0, '', clGreen); // x: 시간, y: Irms
Series4.AddXY(ck, 0, '', clRed); // x: 시간, y: Pwr
end;
no := FMaxPoints;
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('Database Connect Error :: '+e.Message);
end;
end;
end;
procedure TfrmMain.ProgramExit1Click(Sender: TObject);
begin
frmMain.Close;
end;
procedure TfrmMain.CONFIG1Click(Sender: TObject);
begin
frmConfigMQTT.Show;
end;
procedure TfrmMain.NILM2Click(Sender: TObject);
begin
frmNILM.Show;
end;
procedure TfrmMain.Device1Click(Sender: TObject);
begin
frmDevConfig.Show;
end;
procedure TfrmMain.TreeView1Click(Sender: TObject);
var
str1, str : string;
li : LongInt;
sub : TTreeNode;
begin
if TreeView1.Selected = nil then exit;
str := TreeView1.Selected.Text;
Statusbar1.Panels.Items[0].text := str;
if Pos(':', str)<= 0 then
begin
select_nilmID := StrTointDef(str, 0);
end;
if TreeView1.Selected.HasChildren then
begin
sub := TreeView1.Selected.getFirstChild;
str := sub.Text;
str1 := Copy(str, Pos(':', str)+1, Length(str)-Pos(':', str));
select_nilm_idxNo := StrTointDef(str1, 0);
printlog(str1);
end;
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
var
vPF, vVrms, vIrms, vPwr : single;
IntvPF, IntvVrms, IntvIrms, IntvPwr : Integer;
strlist : TStringList;
y_maxvalue : Double;
begin
if select_nilmID<= 0 then exit;
try
// try
if not frmMain.ZConnection1.Connected then frmMain.ZConnection1.Connect();
if frmMain.ZConnection1.Connected then
begin
ZReadOnlyQuery1.Active := false;
ZReadOnlyQuery1.SQL.Clear;
ZReadOnlyQuery1.SQL.Add('SELECT * FROM nilm_value WHERE NilmID='+inttostr(select_nilmID));
ZReadOnlyQuery1.Open;
if ZReadOnlyQuery1.RecordCount> 0 then
begin
vPF := ZReadOnlyQuery1.FieldByName('pf_1').AsFloat;
vVrms := ZReadOnlyQuery1.FieldByName('Vrms_1').AsFloat;
vIrms := ZReadOnlyQuery1.FieldByName('Irms_1').AsFloat;
vPwr := ZReadOnlyQuery1.FieldByName('Pwr_1').AsFloat;
intvPF := ZReadOnlyQuery1.FieldByName('pf_1').AsInteger;
intvVrms := ZReadOnlyQuery1.FieldByName('Vrms_1').AsInteger;
intvIrms := ZReadOnlyQuery1.FieldByName('Irms_1').AsInteger;
intvPwr := ZReadOnlyQuery1.FieldByName('Pwr_1').AsInteger;
end;
end;
// finally
// if frmMain.ZConnection1.Connected then frmMain.ZConnection1.Disconnect;
// end;
except
on e : exception do
begin
frmMain.printlog('Database Connect Error :: '+e.Message);
end;
end;
Series1.AddXY(no, vPF*100, '', clBlue); // x: 시간, y: PF
Series2.AddXY(no, vVrms, '', clGray); // x: 시간, y: Vrms
Series3.AddXY(no, vIrms*100, '', clGreen); // x: 시간, y: Irms
Series4.AddXY(no, vPwr, '', clRed); // x: 시간, y: Pwr
if Series1.Count > FMaxPoints then Series1.Delete(0);
if Series2.Count > FMaxPoints then Series2.Delete(0);
if Series3.Count > FMaxPoints then Series3.Delete(0);
if Series4.Count > FMaxPoints then Series4.Delete(0);
Series1.Visible := true;
Series2.Visible := true;
Series3.Visible := true;
Series4.Visible := true;
{
y_maxvalue := 0;
if y_maxvalue < Series1.YValues.MaxValue then y_maxvalue := Series1.YValues.MaxValue;
if y_maxvalue < Series2.YValues.MaxValue then y_maxvalue := Series2.YValues.MaxValue;
if y_maxvalue < Series3.YValues.MaxValue then y_maxvalue := Series3.YValues.MaxValue;
if y_maxvalue < Series4.YValues.MaxValue then y_maxvalue := Series4.YValues.MaxValue;
if Chart_Main.Axes.Left.Maximum <> (y_maxvalue + 100) then
Chart_Main.Axes.Left.Maximum := y_maxvalue + 100;
}
// 차트 자동 스크롤
Chart_Main.Axes.Bottom.SetMinMax(
Series1.XValues.Value[Max(0, Series1.Count - FMaxPoints)],
Series1.XValues.Value[Series1.Count - 1]
);
no := no + 1;
// Series2.Add(intvVrms, '', clRed);
// Series3.Add(intvIrms, '', clGreen);
// Series4.Add(intvPwr, '', $00FF0080);
// Series5.Add(strlist[4].ToInteger, str, $00FF8000);
// FANTrend1.Add(1, vPF, formatdatetime('hh:nn:ss',now()));
// FANTrend1.Add(2, vVrms, formatdatetime('hh:nn:ss',now()));
// FANTrend1.Add(3, vIrms, formatdatetime('hh:nn:ss',now()));
// FANTrend1.Add(4, vPwr, formatdatetime('hh:nn:ss',now()));
end;
end.