unit WDataEd;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, RXGrids, ExtCtrls, Placemnt,data, StdCtrls, Menus, ActnList,
  ComCtrls, ToolWin,Math,ClipBrd;

const
  gdFloatFmt : string = '%8.3n';
  smFloatFmt : string = '%10.0n';
  gdDateFmt  : string = 'dd/mm hh:nn';

  PhDailyCap : array[0..23] of float =
  (
   {  0:00 }	0.00 ,
   {  1:00 }	0.00 ,
   {  2:00 }	0.00 ,
   {  3:00 }	0.00 ,
   {  4:00 }	0.00 ,
   {  5:00 }	0.01 ,
   {  6:00 }	0.15 ,
   {  7:00 }	0.30 ,
   {  8:00 }	0.42 ,
   {  9:00 }	0.59 ,
   { 10:00 }	0.75 ,
   { 11:00 }	0.90 ,
   { 12:00 }	0.95 ,
   { 13:00 }	1.00 ,
   { 14:00 }	1.00 ,
   { 15:00 }	1.00 ,
   { 16:00 }	1.00 ,
   { 17:00 }	0.95 ,
   { 18:00 }	0.91 ,
   { 19:00 }	0.76 ,
   { 20:00 }	0.60 ,
   { 21:00 }	0.34 ,
   { 22:00 }	0.00 ,
   { 23:00 }	0.00
  );



type
  TfmWDataEd = class(TForm)
    Panel1: TPanel;
    FormStorage: TFormStorage;
    BtnBatCap: TButton;
    CoolBar1: TCoolBar;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ActionList1: TActionList;
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    actViGraph: TAction;
    ToolButton2: TToolButton;
    actChgWG: TAction;
    actPwGraph: TAction;
    PW1: TMenuItem;
    actCEGraph: TAction;
    CE1: TMenuItem;
    actTTLGraph: TAction;
    N2: TMenuItem;
    BtnVelFac: TButton;
    BtnBatCapGr: TButton;
    BtnPwrFacGr: TButton;
    Panel2: TPanel;
    gdEditor: TRxDrawGrid;
    Panel3: TPanel;
    BtnWGGr: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    lbPL: TLabel;
    lbPW: TLabel;
    lbPPH: TLabel;
    Label7: TLabel;
    lbXPWC: TLabel;
    lbXHZC: TLabel;
    lbMaxBatCap: TLabel;
    lbPWC: TLabel;
    lbPHZC: TLabel;
    Label13: TLabel;
    lbPHZ: TLabel;
    Button1: TButton;
    Label4: TLabel;
    lbPPHC: TLabel;
    actPHZGraph: TAction;
    N3: TMenuItem;
    BtnPLGraph: TButton;
    actPPhGraph: TAction;
    N4: TMenuItem;
    Label5: TLabel;
    lbPDL: TLabel;
    BtnEQU: TButton;
    Button2: TButton;
    btnNewMean: TButton;
    btnSort: TButton;
    ToolButton3: TToolButton;
    actLoadWindData: TAction;
    OpenDialog: TOpenDialog;
    BtnFCalc: TButton;
    BtnphCapGr: TButton;
    ToolButton4: TToolButton;
    actEQUBat: TAction;
    PopupMenu2: TPopupMenu;
    N5: TMenuItem;
    ToolButton5: TToolButton;
    actNewDevList: TAction;
    Button3: TButton;
    procedure gdEditorDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure gdEditorGetEditText(Sender: TObject; ACol, ARow: Integer;
      var Value: String);
    procedure gdEditorSelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    function gdEditorAcceptEditKey(Sender: TObject;
      var Key: Char): Boolean;
    procedure gdEditorSetEditText(Sender: TObject; ACol, ARow: Integer;
      const Value: String);
    procedure actViGraphExecute(Sender: TObject);
    procedure actChgWGExecute(Sender: TObject);
    procedure gdEditorFixedCellClick(Sender: TObject; ACol, ARow: Integer);
    procedure actPwGraphExecute(Sender: TObject);
    procedure actCEGraphExecute(Sender: TObject);
    procedure BtnBatCapClick(Sender: TObject);
    procedure actTTLGraphExecute(Sender: TObject);
    procedure BtnVelFacClick(Sender: TObject);
    procedure BtnBatCapGrClick(Sender: TObject);
    procedure BtnPwrFacGrClick(Sender: TObject);
    procedure BtnWGGrClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure actPHZGraphExecute(Sender: TObject);
    procedure BtnPLGraphClick(Sender: TObject);
    procedure actPPhGraphExecute(Sender: TObject);
    procedure BtnEQUClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure btnNewMeanClick(Sender: TObject);
    procedure btnSortClick(Sender: TObject);
    procedure actLoadWindDataExecute(Sender: TObject);
    procedure FormStorageRestorePlacement(Sender: TObject);
    procedure FormStorageSavePlacement(Sender: TObject);
    procedure BtnFCalcClick(Sender: TObject);
    procedure BtnphCapGrClick(Sender: TObject);
    procedure actEQUBatExecute(Sender: TObject);
    procedure ToolButton5Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure actNewDevListExecute(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    WG        : TWindPwrCurve;
    {
    VI        : TMeasurments;
    PW        : array of float;
    PL        : array of float;
    PPh       : array of float;
    CE        : array of float;
    PHZ       : array of float;
    PDL       : array of float;
    }
    procedure logStep( i : integer;
                     _pw  : float;
                     _pph : float;
                     _pl  : float;
                     _phz : float;
                     _pdl : float;
                     _ce  : float);
  public
    { Public declarations }
    function ReCalc(AWG : TWindPWrCurve) : TCalcResult;
    constructor Create(AMeasurments : TMeasurments); reintroduce;
  end;




var
  fmWDataEd: TfmWDataEd;
  GCR      : TCalcResult;  

implementation

uses WVelPeriodGr, GraphBase,series, EnergyGraph, EnergyPerBat, PwrCurveGr,
  RootsEqu;


{$R *.DFM}


procedure RandomArrayFill(var AR : array of Float; maxValue : float);
var
 i : integer;
begin
  for i:=0 to High(AR) do
   ar[i] := MaxValue * Random;
end;

{ TfmWDataEd }

constructor TfmWDataEd.Create(AMeasurments: TMeasurments);
var
 i : integer;
 dfWGFNm : string;
begin
  inherited create(Application);
  Randomize;
  //VI := AMeasurments;
  gdEditor.RowCount := length(vi) + 1;
  //setLength(pwu,VI.Count);
  RandomArrayFill(PL,800);

  for i:=0 to High(pph) do
    pph[i] := phPower* phDailyCap[i mod 24];

  dfWGFNm := ExtractFileDir(ParamStr(0))+'\default.pow';
  WG := TWindPwrCurve.Create;
  WG.LoadFromWaspPow(dfWGFNm);
  ReCalc(WG);
end;

procedure TfmWDataEd.gdEditorDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);


const
  HeaderTitles : array[0..7] of string =
  (
  'Ημερομηνία',
  'Ταχύτητα'#13'Ανέμου',
  'Παραγωγή'#13' Α/Γ',
  'Παραγωγή'#13' Φ/Β',
  'Φορτίο'#13' Ζήτησης',
  'Χωρητικότητα'#13' Μπαταρίας',
  'Παραγωγή'#13' Η/Ζ',
  'Περίσεια'#13' Ενέργειας'
  );

begin
  with Sender As TRxDrawGrid do
  begin
    if ARow=0 then
       DrawMultiLine(Rect,HeaderTitles[ACol],taCenter)
    else
     case ACol of
        0 : CTextRect(Canvas,Rect,FormatDateTime(gdDateFmt,(DateBase+(ARow-1)/24)));
        1 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[vi[ARow-1]]));
        2 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[PW[ARow-1]]));
        3 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[pph[ARow-1]]));
        4 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[PL[ARow-1]]));
        5 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[CE[ARow-1]]));
        6 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[PHZ[ARow-1]]));
        7 : CTextRect(Canvas,Rect,Format(gdFloatFmt,[PDL[ARow-1]]));
     end;
  end;
end;

procedure TfmWDataEd.gdEditorGetEditText(Sender: TObject; ACol,
  ARow: Integer; var Value: String);
begin
  case ACol of
    1 : Value := Format(gdFloatFmt,[vi[ARow-1]]);
  end;
end;

procedure TfmWDataEd.gdEditorSelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
  with Sender As TRxDrawGrid do
  begin
    if ACol=1 then
      Options := Options + [goEditing]
    else
      Options := Options - [goEditing];
  end
end;

function TfmWDataEd.gdEditorAcceptEditKey(Sender: TObject;
  var Key: Char): Boolean;
begin
  with Sender as TRxDrawGrid do
  case Col of
    1 : result := (key in ['0'..'9',DecimalSeparator]);
    else result := True;
  end
end;

procedure TfmWDataEd.gdEditorSetEditText(Sender: TObject; ACol,
  ARow: Integer; const Value: String);
begin
  case ACol of
    1 : vi[ARow-1] := StrToFloat(Value);
  end
end;

procedure TfmWDataEd.actViGraphExecute(Sender: TObject);
begin
{
  with TfmWVelPeriodGr.Create(Application) do
  try
    AssignWindData(VI);
    ShowModal;
  finally
    Free;
  end;
}
end;

procedure TfmWDataEd.actChgWGExecute(Sender: TObject);
var
 AWG : TWindPwrCurve;
begin
  AWG := DM.SelectPwrCurve;
  if AWG<>Nil then
  begin
    WG.Free;
    WG:=AWG;
    with apeCalc(vi, pph,pl,wg,MaxBateryCapacity,LogStep) do
    begin
      lbPL.Caption   := Format('%10.0n',[spl]);
      lbPW.Caption   := Format('%10.0n',[spw]);
      lbPHZ.Caption  := Format('%10.0n',[sphz]);
      lbPPH.Caption  := Format('%10.0n',[spph]);
      lbPDL.Caption  := Format('%10.0n',[spdl]);

      lbPHZC.Caption := Format('%10.2n%%',[100*cphz]);
      lbPWC.Caption   := Format('%10.2n%%',[100*cpw]);
      lbPPHC.Caption  := Format('%10.2n%%',[100*cpph]);
    end;
  end;
end;

procedure TfmWDataEd.gdEditorFixedCellClick(Sender: TObject; ACol,
  ARow: Integer);

procedure RandomVI;
var
 ViMean : float;
 ViSTD  : float;
 i      : integer;
begin
  ViMean := mean(vi);
  vistd  := StdDev(vi);
  for i:=0 to High(vi) do
      vi[i] := RandomNorm(vimean,vistd);
  Recalc(wg);
  gdEditor.Refresh;
end;


begin
  if (ARow=0) and (ACol<>0) then
  begin
    case ACol of
       1 : RandomVI;
       2 : ShowMessageFmt(smFloatFmt,[Sum(PW)]);
       3 : ShowMessageFmt(smFloatFmt,[Sum(pph)]);
       4 : ShowMessageFmt(smFloatFmt,[Sum(PL)]);
       6 : ShowMessageFmt(smFloatFmt,[Sum(phz)]);
       7 : ShowMessageFmt(smFloatFmt,[Sum(pdl)]);
    end;
  end
  else
  if (ARow=0) and (ACol=0) then
  begin
    ShowMessageFmt(smFloatFmt+' = '+smFloatFmt,[sum(pw)+sum(pph)+sum(phz)-sum(pdl)+MaxBateryCapacity-ce[high(ce)],sum(pl)]);
  end;
end;

procedure TfmWDataEd.actPwGraphExecute(Sender: TObject);
begin
  GeneralGraph(DateBase,'',PW);
end;

procedure TfmWDataEd.actCEGraphExecute(Sender: TObject);
begin
  GeneralGraph(DateBase,'',CE);
end;






function TfmWDataEd.ReCalc(AWG: TWindPWrCurve) : TCalcResult;
var
 CR : TCalcResult;
begin
  CR := apeCalc(vi,pph,pl,wg,MaxBateryCapacity,LogStep);
  with CR do
  begin
    lbPL.Caption   := Format('%10.0n',[spl]);
    lbPW.Caption   := Format('%10.0n',[spw]);
    lbPHZ.Caption  := Format('%10.0n',[sphz]);
    lbPPH.Caption  := Format('%10.0n',[spph]);
    lbPDL.Caption  := Format('%10.0n',[spdl]);

    lbPHZC.Caption := Format('%10.2n%%',[100*cphz]);
    lbPWC.Caption   := Format('%10.2n%%',[100*cpw]);
    lbPPHC.Caption  := Format('%10.2n%%',[100*cpph]);
  end;
end;


procedure TfmWDataEd.BtnBatCapClick(Sender: TObject);
var
  ABateryCap : string;
begin
  ABateryCap := FloatToStr(MaxBateryCapacity);
  if InputQuery('Χωριτηκότητα','Βαταρία Wh',ABateryCap) then
  begin
    MaxBateryCapacity := StrToFloat(ABateryCap);
    Recalc(WG);
    gdEditor.Refresh;
  end;
end;

procedure TfmWDataEd.actTTLGraphExecute(Sender: TObject);

var
 fmGraph : TFmEnergyGraph;
begin
  fmGraph := TFmEnergyGraph.Create(Application);
  with fmGraph do
  try
    with apeCalc(vi, pph,pl,wg,MaxBateryCapacity,nil) do
    begin
      Series1.AddPie(cphz,'hz',clRed);
      Series1.AddPie(cpw,'pw',clGreen);
      Series1.AddPie(cpph,'pph',clYellow);
    end;
    ShowModal;
  finally
    Free;
  end;
end;

procedure TfmWDataEd.BtnVelFacClick(Sender: TObject);
var
  AVelocityFac : string;
begin
  AVelocityFac := FloatToStr(VelocityFactor);
  if InputQuery('Ταχύτητα Ανέμου','Συντελεστής',AVelocityFac) then
  begin
    VelocityFactor := StrToFloat(AVelocityFac);
    Recalc(WG);
    gdEditor.Refresh;
  end;
end;



procedure TfmWDataEd.BtnBatCapGrClick(Sender: TObject);
var
  iMaxBatCap : float;
  i          : integer;
  CR         : TCalcResult;
  mxBat         : float;
begin
  iMaxBatCap := MaxBateryCapacity;
  with TFmEnergyPerBat.Create(Application) do
  try
    for i := 0 to 10 do
    begin
      mxBat :=  (0.5+i/10)*iMaxBatCAp ;
      //CR:=Recalc(WG);
      CR := apeCalc(vi,pph,pl,wg,mxBat,nil);
      srPHZ.AddXY(mxBat,CR.sphz);
      srPW.AddXY(mxBat,CR.spl*CR.cpw);
      srPPH.AddXY(mxBat,CR.spl*CR.cpph);
      srPDL.AddXY(mxBat,CR.spdl);
    end;
    ShowModal;
  finally
    Free;
  end
end;

procedure TfmWDataEd.BtnPwrFacGrClick(Sender: TObject);
var
  i          : integer;
  CR         : TCalcResult;
begin
  with TFmEnergyPerBat.Create(Application) do
  try
    for i := 0 to PwrFactorSteps do
    begin
      Wg.PwrFactor := 0.5 + i/PwrFactorSteps;
      CR := apeCalc(vi,pph,pl,wg,MaxBateryCapacity,nil);
      //Recalc(WG);
      {
      sphz := Sum(phz);
      spw  := sum(pl)-sphz;
      spdl := sum(pdl);
      }
      with CR do
      begin
        srPHZ.AddXY(wg.pwrFactor*100,sphz);
        srPW.AddXY(wg.pwrFactor*100,spl*cpw);
        srPPH.AddXY(wg.pwrFactor*100,spl*cpph);
        srPDL.AddXY(wg.pwrFactor*100,spdl);
      end
    end;
    ShowModal;
  finally
    wg.PwrFactor := 1.0;
    Free;
  end
end;

procedure TfmWDataEd.BtnWGGrClick(Sender: TObject);
begin
  with TFmPwrCurveGr.Create(nil) do
  try
    ShowModal;
  finally
    Free;
  end;
end;

procedure TfmWDataEd.FormCreate(Sender: TObject);
var
 i : integer;
  dfWGFNm : string;
begin
  lbMaxBatCap.Caption := Format('%10.0n',[MaxBateryCapacity]);
  gdEditor.RowHeights[0] := Round(gdEditor.RowHeights[0]*2);

    Randomize;
  //VI := AMeasurments;
  gdEditor.RowCount := length(vi) + 1;
  //setLength(pwu,VI.Count);
  RandomArrayFill(PL,800);

  for i:=0 to High(pph) do
    pph[i] := phPower* phDailyCap[i mod 24];

  dfWGFNm := ExtractFileDir(ParamStr(0))+'\default.pow';
  WG := TWindPwrCurve.Create;
  WG.LoadFromWaspPow(dfWGFNm);
  ReCalc(WG);
end;

procedure TfmWDataEd.Button1Click(Sender: TObject);
var
 i : integer;
begin
  if InputFloat('Ισχύς Φωτοβολταϊκού:',phPower) then
  begin
    for i:=0 to High(pph) do
      pph[i] := phPower * phDailyCap[i mod 24];
    Recalc(WG);
    gdEditor.Refresh;
  end;
end;

procedure TfmWDataEd.actPHZGraphExecute(Sender: TObject);
begin
  GeneralGraph(DateBase,'',Phz);
end;

procedure TfmWDataEd.BtnPLGraphClick(Sender: TObject);
var
 DailyMeans : array[0..23] of float;
 i : integer;
begin
  FillArray(DailyMeans,0);
  for i:=0 to High(PL) do
      DailyMeans[i mod 24] := DailyMeans[i mod 24] + pl[i];
  for i:=0 to 23 do
    DailyMeans[i] := DailyMeans[i]/Length(pl)*24;
  GeneralGraph(0,'',DailyMeans);
end;

procedure TfmWDataEd.actPPhGraphExecute(Sender: TObject);
begin
  GeneralGraph(DateBase,'',Pph);
end;

var
 HZTarget : float = 0;


function HZEq(BatCap : double) : double; far;
begin
  with fmWDataEd do
  begin
    GCR := apeCalc(vi,pph,pl,wg,BatCap,LogStep);
    Result := GCR.sphz-HZTarget;
   {
     MaxBateryCapacity := BatCap;
     Recalc(WG);
     Result := sum(phz)-HZTarget;
    }
  end;
end;

procedure TfmWDataEd.BtnEQUClick(Sender: TObject);

var
  root,
  value : float;
  iter : integer;
  err  : byte;
  spl  : float;
begin
  fmWDataEd := Self;
  spl := sum(pl);
  HzTarget := HZTargetCoef*spl;
  err      := 0;
  bisect(0,100*spl,1e-3,100,root,value,iter,err,@HZEq);

  if Err=0 then
  begin
    showMessageFmt('root[%d]=%8.3f, %8.3f',[iter,root,value]);
    MaxBateryCapacity := root;
  end
  else
   ShowMessageFmt('error num : %d iters[%d]',[err,iter]);


  with GCR do
  begin
    lbPL.Caption   := Format('%10.0n',[spl]);
    lbPW.Caption   := Format('%10.0n',[spw]);
    lbPHZ.Caption  := Format('%10.0n',[sphz]);
    lbPPH.Caption  := Format('%10.0n',[spph]);
    lbPDL.Caption  := Format('%10.0n',[spdl]);

    lbPHZC.Caption := Format('%10.2n%%',[100*cphz]);
    lbPWC.Caption   := Format('%10.2n%%',[100*cpw]);
    lbPPHC.Caption  := Format('%10.2n%%',[100*cpph]);
    lbMaxBatCap.Caption := Format('%10.0n',[MaxBateryCapacity]);
  end;

end;


procedure TfmWDataEd.Button2Click(Sender: TObject);

   function wbRand(c,k : float) : float;
   begin
     result :=  exp(ln(-ln(random))/k+ln(c))
   end;

var
 i : integer;
 c,k,fm,fsd : float;
begin
  for i:=0 to High(Vi) do
    vi[i] := wbRand(6.484,1.697);
  begin
    FitWeibull(Mean(vi),stdDev(vi),C,k,fm,fsd);
    ShowMessageFmt('c=%0.3f k=%0.3f',[c,k]);
  end;
  reCalc(wg);
  gdEditor.Refresh;
end;

procedure TfmWDataEd.btnNewMeanClick(Sender: TObject);
var
 vMean : float;
 nMean : float;
 i     : integer;
begin
  vMean := Mean(vi);
  nMean := vMean;
  if InputFloat('Νεος ΜΟ:',nMean) then
  begin
    for i:=0 to High(vi) do
      vi[i]:=vi[i]*nMean/vMean;
    Recalc(WG);
  end;
end;

procedure VisualSwap(var A, B : float);
var
 FA : float;
begin
  FA := B;
  A  := B;
  B  := FA;
end;

procedure QuickSort(var A: array of float; iLo, iHi: Integer);
var
  Lo, Hi : integer;
  Mid, T: float;
begin
  Lo := iLo;
  Hi := iHi;
  Mid := A[(Lo + Hi) div 2];
  repeat
    while A[Lo] < Mid do Inc(Lo);
    while A[Hi] > Mid do Dec(Hi);
    if Lo <= Hi then
    begin
      T := A[Lo];
      A[Lo] := A[Hi];
      A[Hi] := T;
      Inc(Lo);
      Dec(Hi);
    end;
  until Lo > Hi;
  if Hi > iLo then QuickSort(A, iLo, Hi);
  if Lo < iHi then QuickSort(A, Lo, iHi);
end;

procedure TfmWDataEd.btnSortClick(Sender: TObject);
begin
  QuickSort(vi,0,High(vi));
  recalc(wg);
end;

procedure TfmWDataEd.actLoadWindDataExecute(Sender: TObject);
begin
  if OpenDialog.Execute then
  begin
    //Raise Exception.Create ('under modifications');
    //vi.LoadFromAsciiFile(OpenDialog.FileName);
    LoadAsciiFile(OpenDialog.FileName,vi);
    gdEditor.Refresh;
    Recalc(WG);
  end;
end;

procedure TfmWDataEd.FormStorageRestorePlacement(Sender: TObject);
begin
  OpenDialog.InitialDir := FormStorage.ReadString('InitialDir','');
end;

procedure TfmWDataEd.FormStorageSavePlacement(Sender: TObject);
begin
  if OpenDialog.FileName<>'' then
     FormStorage.WriteString('InitialDir',ExtractFilePath(OpenDialog.FileName));
end;

procedure TFmWDataEd.logStep( i : integer;
                     _pw  : float;
                     _pph : float;
                     _pl  : float;
                     _phz : float;
                     _pdl : float;
                     _ce  : float);
begin
  pw[i]  := _pw;
  phz[i] := _phz;
  pdl[i] := _pdl;
  ce[i]  := _ce;
end;

procedure TfmWDataEd.BtnFCalcClick(Sender: TObject);

var
 CR : TCalcResult;
begin
  CR := apeCalc(vi,pph,pl,wg,MaxBateryCapacity,LogStep);
  with CR do
  begin
    lbPL.Caption   := Format('%10.0n',[spl]);
    lbPW.Caption   := Format('%10.0n',[spw]);
    lbPHZ.Caption  := Format('%10.0n',[sphz]);
    lbPPH.Caption  := Format('%10.0n',[spph]);
    lbPDL.Caption  := Format('%10.0n',[spdl]);

    lbPHZC.Caption := Format('%10.2n%%',[100*cphz]);
    lbPWC.Caption   := Format('%10.2n%%',[100*cpw]);
    lbPPHC.Caption  := Format('%10.2n%%',[100*cpph]);
  end;
end;

procedure TfmWDataEd.BtnphCapGrClick(Sender: TObject);
var
  ii         ,
  i          : integer;
  CR         : TCalcResult;
  pPPh          : float;
  mxPph         : float;
  iPPh          : TFloatArray;
begin
  mxPph := phPower;
  setLength(iPPh,Length(vi));
  with TFmEnergyPerBat.Create(Application) do
  try
    for i := 0 to 10 do
    begin
      pPPh :=  (0.5+i/10)*mxPPh ;

      for ii:=0 to High(iPPh) do
          ipph[ii] := pPPh * phDailyCap[ii mod 24];

      CR := apeCalc(vi,ipph,pl,wg,MaxBateryCapacity,nil);
      srPHZ.AddXY(pPPh,CR.sphz);
      srPW.AddXY(pPPh,CR.spl*CR.cpw);
      srPPH.AddXY(pPPh,CR.spl*CR.cpph);
      srPDL.AddXY(pPPh,CR.spdl);
    end;
    ShowModal;
  finally
    SetLength(iPPh,0);
    Free;
  end
end;

procedure TfmWDataEd.actEQUBatExecute(Sender: TObject);
var
  root,
  value : float;
  iter : integer;
  err  : byte;
  spl  : float;
begin
  fmWDataEd := Self;
  spl := sum(pl);
  HzTarget := HZTargetCoef*spl;
  err      := 0;
  bisect(0,100*spl,1e-5,100,root,value,iter,err,@HZEq);

  if Err=0 then
  begin
    showMessageFmt('root[%d]=%8.3f, %8.3f',[iter,root,value]);
    MaxBateryCapacity := root;
  end
  else
   ShowMessageFmt('error num : %d iters[%d]',[err,iter]);


  with GCR do
  begin
    lbPL.Caption   := Format('%10.0n',[spl]);
    lbPW.Caption   := Format('%10.0n',[spw]);
    lbPHZ.Caption  := Format('%10.0n',[sphz]);
    lbPPH.Caption  := Format('%10.0n',[spph]);
    lbPDL.Caption  := Format('%10.0n',[spdl]);

    lbPHZC.Caption := Format('%10.2n%%',[100*cphz]);
    lbPWC.Caption   := Format('%10.2n%%',[100*cpw]);
    lbPPHC.Caption  := Format('%10.2n%%',[100*cpph]);
    lbMaxBatCap.Caption := Format('%10.0n',[MaxBateryCapacity]);
  end;

end;



procedure TfmWDataEd.ToolButton5Click(Sender: TObject);
var
 FNm : string;
begin
  FNm := DM.SelectDevListFile;
  if FNm<>'' then
    with TDevList.Create do
    try
      LoadFromFile(Fnm);
      ConstructPowerDemand(pl);
      gdEditor.Refresh;
    finally
      Free;
    end;
end;

procedure TfmWDataEd.FormDestroy(Sender: TObject);
begin
//  SetLength(pl,0);
end;

procedure TfmWDataEd.actNewDevListExecute(Sender: TObject);
var
 FNm : string;
begin
  FNm := DM.SelectDevListFile;
  if FNm<>'' then
    with TDevList.Create do
    try
      LoadFromFile(Fnm);
      ConstructPowerDemand(pl);
      gdEditor.Refresh;
    finally
      Free;
    end;
end;


procedure TfmWDataEd.Button3Click(Sender: TObject);
var
 s : string;
 i : integer;
begin
  s := '';
  for i:=0 to 8760-1 do
    s := s + format('%0.3f',[pw[i]]) + #13#10;
  ClipBoard.AsText := s;
end;

end.
