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, MQTT, DB, VclTee.TeeGDIPlus, VCLTee.TeEngine, VCLTee.Series, VCLTee.TeeProcs, VCLTee.Chart, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Phys.PGDef, FireDAC.VCLUI.Wait, FireDAC.Comp.UI, FireDAC.Phys.PG, FireDAC.Comp.DataSet, FireDAC.Comp.Client; type TfrmMain = class(TForm) initTimer: TTimer; StatusBar1: TStatusBar; MainMenu1: TMainMenu; ListBox1: TListBox; File2: TMenuItem; ProgramExit1: TMenuItem; 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; FDConnection1: TFDConnection; FDQuery1: TFDQuery; FDPhysPgDriverLink1: TFDPhysPgDriverLink; FDGUIxWaitCursor1: TFDGUIxWaitCursor; 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; dbIP_PG, dbUser_PG, dbPW_PG, dbSchema_PG : string; dbPort, dbPort_PG, brokerPort : integer; brokerIP, mqtt_user, mqtt_pw : string; old_NilmID : integer; procedure PrintLog(msg : String); procedure ClearIOTGW(); procedure insertSQL(sql : string); procedure ShowNilmTreeView(); function DB_Connect:Boolean; function DB_Close:Boolean; 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); dbIP_PG := ReadString('DATABASE_PG','IP','192.168.200.199'); dbUser_PG := ReadString('DATABASE_PG','User','root'); dbPW_PG := ReadString('DATABASE_PG','PW','54323'); dbSchema_PG := ReadString('DATABASE_PG','Schema','neol'); dbPort_PG := ReadInteger('DATABASE_PG','Port',3306); hubPort := ReadInteger('MQTT_HUB','Port',6969); end; ini.Free; end; // PG ¼­¹öÁ¢¼Ó if not DB_Connect then begin printlog('Database Connect Error :: PG'); end; frmNILM.ShowNILM(); frmDevConfig.ShowDev(); ShowNilmTreeView(); Timer1.Enabled := True; initTimer.Enabled := false; end; function TfrmMain.DB_Connect:Boolean; begin FDPhysPgDriverLink1.VendorLib := '.\libpq-10.dll'; FDConnection1.Connected := False; FDConnection1.Params.Clear; FDConnection1.Params.DriverID := 'PG'; FDConnection1.Params.Database := Trim(dbSchema_PG); FDConnection1.Params.UserName := Trim(dbUser_PG); FDConnection1.Params.Password := Trim(dbPW_PG); FDConnection1.Params.Add('Server=' + Trim(dbIP_PG)); FDConnection1.Params.Add('Port=' + Trim(IntToStr(dbPort_PG))); FDConnection1.Params.Add('CharacterSet=UTF8'); try FDConnection1.Connected := True; Result := True; // Memo1.Lines.Add('¿¬°á ¼º°ø'); // Memo1.Lines.Add('"Q1" ¹öưÀ» ´©¸¥ ÈÄ "Äõ¸®" ¹öưÀ» ´©¸£¼¼¿ä!!'); except on E: Exception do begin Result := False; // Memo1.Lines.Add('¿¬°á ½ÇÆÐ: ' + E.Message); end; end; end; function TfrmMain.DB_Close:Boolean; begin try if FDConnection1.Connected then FDConnection1.Connected := False; Result := True; except Result := False; end; 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 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 // 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.