unit uSimSolar;

interface

uses
  Windows, shellapi,
  Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids,
  Menus,
  jpeg,
  ExtCtrls, ComCtrls,
  fddp,
  uhtmlverdoc,
  NucleoT,
  task2,
  VGlbs02,
  Params,
  listas,
  ancestor,
  horrores,
  xmatdefs,
  actores,
  dire02,
  Evals02,
  ActBat04,
  FntVnts,
  fdsol,
  lexemas,
  ofedem02,
  tabp2d,
  fdefs,
  bases,
  fdias02,
  ocurrenx,
  autoesca,
  uSeresVivos,
  fdsol02horaria,
  fdsol_ktcegh,
  fdr01,
  fdrs,
  facpos,
  matpole,
  actpan04,
  demht,
  ufUbicacion, ufCarga, ufPaneles, ufBaterias, ufSimulacion;

const
  archiDatosSintetizador= 'ModeloKT.txt';

type
  TfSimSolar = class(TForm)
    gbResultados: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    eDDDEsperados: TEdit;
    eDDDpne90: TEdit;
    eDDEEsperados: TEdit;
    eDDEpe90: TEdit;
    eBatDeg_med: TEdit;
    Panel2: TPanel;
    lblUbicacionGeografica: TLabel;
    lblCarga: TLabel;
    lblPaneles: TLabel;
    lblBaterias: TLabel;
    lblSimulacion: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    ProgressBar1: TProgressBar;
    Button6: TButton;
    Button7: TButton;
    MainMenu1: TMainMenu;
    Abrir1: TMenuItem;
    Leer1: TMenuItem;
    Guardar1: TMenuItem;
    Nuevo1: TMenuItem;
    Help1: TMenuItem;
    Contents1: TMenuItem;
    About1: TMenuItem;
    OpenDialog1: TOpenDialog;
    barraDeEstado: TStatusBar;
    lblEnergiaDelDiaMedio: TLabel;
    Button8: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Leer1Click(Sender: TObject);
    procedure Nuevo1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Guardar1Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Contents1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    carpetaDeLaCorrida: string;
    archi: string; // nombre de archivo bajo edición
    xmodificado: boolean; // a true si necesita salvarse
    ultimoAddString: string;

    RW_f: textfile;
    RW_modo: integer;

    // ofrece Guardar con opciones SI NO y CANCELAR
    // Retorna TRUE si se seleccionó CANCELAR indicando que
    // se debe abortar la acción. Si seleccionamos SI guarda y retorna
    // false. Si seleccionamos NO, no guarda y retorna false.
    function Cancelar_GuardarSiNo: boolean;
    procedure ActualizarBarraDeEstado( addString: string );
    procedure setModificado;
    procedure resetModificado;

    procedure ActualizarResumenUbicacion;
    procedure ActualizarResumenCarga;
    procedure ActualizarResumenPaneles;
    procedure ActualizarResumenBaterias;
    procedure ActualizarResumenSimulacion;

//    procedure rws( var f: textfile; var x: integer; modo: integer );
    procedure rwi( var x: integer );
    procedure rwf( var x: NReal );
    procedure rwb( var x: boolean );

    procedure rwEscenario( modo: integer );
    procedure Ejecutar;

  end;

var
  fSimSolar: TfSimSolar;


implementation



{$R *.dfm}


var

  EDiariaWh: NReal;

	DiasPermitidosDeDeficit,
	VentanaDeDeficit,
	VentanaDeExcesos: integer;
  usarModeloCEGHSolar: boolean;

var
	PerfilCDC: TPerfilCDC;
	EstacionalCDC: TEstacionalesCDC;

	Bat_CT:NReal;
	Bat_TN:NReal;
	Bat_ID:NReal;
	Bat_IR:NReal;
	Bat_VN:NReal;
	Bat_rc:NReal; { rendimiento de carga }
	Bat_x1:NReal;
	Bat_y1:NReal;
	Bat_x2:NReal;
	Bat_y2:NReal;

	NPaneles:integer;
	Paneles_PotenciaPicoPorPanel:NReal;
	Paneles_InclinacionDePaneles:NReal;
  Paneles_UsarUnAnguloPorMes: integer;
  Paneles_Angulos: TArrMensual;



	ImpFecha: boolean;
	CapacidadDeBateria,
	PPCB: NReal;
	NumeroDePanelesDe48W:NReal;
	Latitud,
	Longitud: NReal;

	DiasDeDeficitResultante, DiasDeExcesoResultante: NReal;

	Quantum: NReal;

	xF: TFuenteDeSol; //Usa la clase abstracta, puede ser FuenteAnilloRuidoso o
                    //TFDSol_ktcegh
	xpanel: ActPan04.TPanelSolar;


	Demanda: TDemHT;
	bateria: ActBat04.TBateriaHD;
	e1, e2 :Evals02.TEvaluador;
  histoAniosVidaBat: THistograma;
	confianza: NReal;
	contador:integer;
	txt:string;


	auto:boolean;



procedure TfSimSolar.About1Click(Sender: TObject);
begin
  htmlverdoc( 'creditos' );
end;

procedure TfSimSolar.ActualizarBarraDeEstado( addString: string );
var
  s: string;
begin
  s:= archi;
  if xmodificado then
    s:= s+' (Modificado)';
  barraDeEstado.SimpleText:= s+' '+addString;
  ultimoAddString:= addString;
end;

procedure TfSimSolar.setModificado;
begin
  xModificado:= true;
  ActualizarBarraDeEstado( ultimoAddString );
  self.gbResultados.Visible:= false;
end;



procedure TfSimSolar.actualizarResumenUbicacion;
begin
  lblUbicacionGeografica.Caption:= 'Latitud [º]: '+FloatToStrF(Latitud, ffFixed, 6, 1 )+', Longitud [º]: '+FloatToStrF( Longitud, ffFixed, 6, 1 );
end;

procedure TfSimSolar.ActualizarResumenCarga;
var
  EnergiaDiaria: NReal;
  PromedioFactores: NReal;
  kHora: integer;
  mes: T_Mes;
begin
  EnergiaDiaria:= 0;
  for kHora:= 0 to 23 do
      EnergiaDiaria:= EnergiaDiaria + PerfilCDC[ kHora ];
  PromedioFactores:= 0;
  for mes:= Enero to Diciembre do
    PromedioFactores:= PromedioFactores + EstacionalCDC[ mes ];
  PromedioFactores:= PromedioFactores / 12.0;
  EnergiaDiaria:= EnergiaDiaria * PromedioFactores;
  lblCarga.Caption:= 'Consumo medio diario [Wh/día]: '+FloatToStrF( EnergiaDiaria, ffFixed, 6,2 );
end;


procedure TfSimSolar.ActualizarResumenPaneles;
begin

  if Paneles_UsarUnAnguloPorMes= 0then
      lblPaneles.Caption:= 'Paneles: '+IntToStr( nPaneles )+
            ' x '+FloatToStrF( Paneles_PotenciaPicoPorPanel, ffFixed, 6,1 )+'Wpico, angulo [º]: '+
            FloatToStrF( Paneles_InclinacionDePaneles, ffFixed, 6, 1  )
  else
      lblPaneles.Caption:= 'Paneles: '+IntToStr( nPaneles )+
            ' x '+FloatToStrF( Paneles_PotenciaPicoPorPanel, ffFixed, 6,1 )+'Wpico, angulo [º] Mín: '+
            FloatToStrF( Minimo(Paneles_Angulos), ffFixed, 6, 1  )+' Máximo: '+FloatToStrF( Maximo(Paneles_Angulos), ffFixed, 6, 1  )

end;

procedure TfSimSolar.ActualizarResumenBaterias;
begin
  lblBaterias.Caption:= 'Cap.[Ah]: '+FloatToStrF( CapacidadDeBateria, ffFixed, 6, 1 )+
        ' [V]: '+FloatToStrF( Bat_VN, ffFixed, 6, 1 )
        +' PPCB[p.u.]: '+FloatToStrF( PPCB, ffFixed, 6, 3 );
end;

procedure TfSimSolar.ActualizarResumenSimulacion;
begin
  Self.lblSimulacion.Caption:= 'Años a simular: '+IntToStr( periodosTotales )+', Días Permitidos de Déficit: '+IntToStr( DiasPermitidosDeDeficit ) + ',' + #13 + 'Usar Modelo CEGH Solar: ' + BoolToStr(usarModeloCEGHSolar, true);
end;
procedure TfSimSolar.resetModificado;
begin
  xModificado:= false;
  ActualizarBarraDeEstado( ultimoAddString );

end;

procedure TfSimSolar.Button1Click(Sender: TObject);
var
  fUbicacion: TfUbicacion;
  res: integer;
begin
  fUbicacion:= TfUbicacion.Create(Self);
  fUbicacion.SetDatos( Latitud, Longitud );
  res:= fUbicacion.ShowModal;
  if res =1  then
  begin
    fUbicacion.getDatos( Latitud, Longitud );
    actualizarResumenUbicacion;
    SetModificado;
  end;
  fUbicacion.Free;
end;

procedure TfSimSolar.Button2Click(Sender: TObject);
var
  fCarga: TfCarga;
  res: integer;
begin
  fCarga:= TfCarga.Create(Self);
  fCarga.SetDatos( PerfilCDC, EstacionalCDC );
  res:= fCarga.ShowModal;
  if res= 1 then
  begin
    fCarga.GetDatos( PerfilCDC, EstacionalCDC );
    actualizarResumenCarga;
    SetModificado;
  end;
  fCarga.Free;
end;

procedure TfSimSolar.Button3Click(Sender: TObject);
var
  fPaneles: TfPaneles;
  res: integer;
begin
  fPaneles:= TfPaneles.Create(Self);
  fPaneles.SetDatos(
        nPaneles,
        Paneles_PotenciaPicoPorPanel,
        Paneles_InclinacionDePaneles,
        Paneles_UsarUnAnguloPorMes,
        Paneles_Angulos  );
  res:= fPaneles.ShowModal;
  if res =1  then
  begin
  fPaneles.GetDatos(
        nPaneles,
        Paneles_PotenciaPicoPorPanel,
        Paneles_InclinacionDePaneles,
        Paneles_UsarUnAnguloPorMes,
        Paneles_Angulos  );

    actualizarResumenPaneles;
    SetModificado;
  end;
  fPaneles.Free;
end;

procedure TfSimSolar.Button4Click(Sender: TObject);
var
  fBaterias: TfBaterias;
  res: integer;
begin
  fBaterias:= TfBaterias.Create(Self);
  fBaterias.SetDatos(
    CapacidadDeBateria, // Ah @ 100h
    Bat_CT, // coeficiente de variación de la capacidad con la temperatura
    Bat_TN, // temperatura nominal.
    Bat_ID, // [A] corriente máxima de descarga
    Bat_IR, // [A] corriente máxima de recarga
    Bat_VN, // [V] tensión nominal de la batería.
    PPCB, // Profundidad Permitida de uso de Capacidad de la Batería.
    Bat_rc, // rendimiento de carga
    Bat_x1, // profundidad de descarga del punto PC2
    Bat_y1, // número de ciclos del punto PC1
    Bat_x2, // profundidad de descarga del punto PC2
    Bat_y2 // número de ciclos del punto PC2
  );
  res:= fBaterias.ShowModal;
  if res =1  then
  begin
  fBaterias.GetDatos(
    CapacidadDeBateria, // Ah @ 100h
    Bat_CT, // coeficiente de variación de la capacidad con la temperatura
    Bat_TN, // temperatura nominal.
    Bat_ID, // [A] corriente máxima de descarga
    Bat_IR, // [A] corriente máxima de recarga
    Bat_VN, // [V] tensión nominal de la batería.
    PPCB, // Profundidad Permitida de uso de Capacidad de la Batería.
    Bat_rc, // rendimiento de carga
    Bat_x1, // profundidad de descarga del punto PC2
    Bat_y1, // número de ciclos del punto PC1
    Bat_x2, // profundidad de descarga del punto PC2
    Bat_y2 // número de ciclos del punto PC2
 );

    actualizarResumenBaterias;
    SetModificado;
  end;
  fBaterias.Free;
end;


procedure TfSimSolar.Button5Click(Sender: TObject);
begin
  gbResultados.Visible:= false;
  Button1.Enabled:= false;
  Button2.Enabled:= false;
  Button3.Enabled:= false;
  Button4.Enabled:= false;
  Button5.Enabled:= false;
  Button6.Enabled:= false;
  self.ProgressBar1.Max:= PeriodosTotales;
  randseed:= 31;
  fddp.FijarSemilla(31);
  Ejecutar;
  gbResultados.Visible:= true;
  Button1.Enabled:= true;
  Button2.Enabled:= true;
  Button3.Enabled:= true;
  Button4.Enabled:= true;
  Button5.Enabled:= true;
  Button6.Enabled:= true;
end;

procedure TfSimSolar.Button6Click(Sender: TObject);
var
  fSimulacion: TfSimulacion;
  res: integer;
begin
  fSimulacion:= TfSimulacion.Create(Self);
  fSimulacion.SetDatos(  PeriodosTotales, DiasPermitidosDeDeficit, usarModeloCEGHSolar  );
  res:= fSimulacion.ShowModal;
  if res =1  then
  begin
    fSimulacion.GetDatos(  PeriodosTotales, DiasPermitidosDeDeficit, usarModeloCEGHSolar );
    actualizarResumenSimulacion;
    SetModificado;
  end;
  fSimulacion.Free;
end;

procedure TfSimSolar.Button7Click(Sender: TObject);
begin
  htmlverdoc( '' );
end;

procedure TfSimSolar.Button8Click(Sender: TObject);
begin
  htmlverdoc( 'resultados' );
end;

function TfSimSolar.Cancelar_GuardarSiNo: boolean;
var
  k: integer;

begin
  k:=  application.messagebox( 'Atención!', 'Desea guardar el archivo actual?', MB_YESNOCANCEL );
  case k of
  IDYES:
    begin
      Self.rwEscenario( 1 );
      resetModificado;
      result:= false;
    end;
  IDNO:
    begin
      result:= false;
    end;
  IDCANCEL:
    begin
      result:= true;
    end;
  else
    result:= true;
  end;


end;


procedure TfSimSolar.Contents1Click(Sender: TObject);
begin
  htmlverdoc( 'manualdelusuario' );
end;


procedure TfSimSolar.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  k: integer;

begin
  CanClose:= true;
  if not xModificado then exit;
  k:=  application.messagebox( 'Hay cambios sin guardar. ¿Desea guardar los cambios antes de salir?', 'Confirmación', MB_YESNOCANCEL );
  case k of
  IDYES:
  begin
    if archi='' then
    begin
      Guardar1Click(self);
      modalresult:= 2;
      if archi='' then  // quiere decir que no guardó
        canclose:= false;
    end
    else
      modalresult:= 1; // salir y guardar
  end;
  IDNO: modalresult:= 2; // salir pero no guardar
  IDCANCEL: CanClose:= false;
  else
    Canclose:= false;
  end;
end;

procedure TfSimSolar.FormCreate(Sender: TObject);
begin
  Sysutils.DecimalSeparator:= '.';
  Nuevo1Click(Self);
  self.resetModificado;


  uhtmlverdoc.apphandle:= self.Handle;
end;


procedure ImprimirFecha(var alp); far;
begin
	ImpFecha:= true;
end;





procedure TfSimSolar.Guardar1Click(Sender: TObject);
begin
  if openDialog1.Execute then
  begin
    archi:=opendialog1.FileName;
  	self.rwEscenario( 1 );
    resetModificado;
    carpetaDeLaCorrida:= extractFileDir( archi );
    chdir( carpetaDeLaCorrida );
  end;
end;


procedure TfSimSolar.rwf( var x: NReal );
begin
  case RW_modo of
    0: readln( RW_f, x );
    1: writeln( RW_f, x );
  end;
end;


procedure TfSimSolar.rwi( var x: integer );
begin
  case RW_modo of
    0: readln( RW_f, x );
    1: writeln( RW_f, x );
  end;
end;

procedure TfSimSolar.rwb( var x: boolean );
var
  i: integer;
begin
  case RW_modo of
    0: begin
         rwi( i );
         x:= i <> 0;
       end;
    1: begin
        if x then i:= 1 else i:= 0;
        rwi( i );
    end;
  end;
end;

(*
procedure TfSimSolar.rws( var f: textfile; var x: integer; modo: integer );
begin
  case modo of
    0: readln( f, x );
    1: writeln( f, x );
  end;
end;
  *)

procedure TfSimSolar.rwEscenario(  modo: integer );
var
  k: integer;
  kmes: T_Mes;

begin
  RW_modo:= modo;
  assignfile( RW_f, archi );
  case modo of
    0: reset( RW_f );
    1: rewrite( RW_f );
  end;
  rwf( Latitud);
  rwf( Longitud);
	for k:=0 to 23 do rwf( PerfilCDC[k] );

  for kmes:=enero to diciembre do rwf( EstacionalCDC[kmes] );
	rwf( CapacidadDeBateria);
	rwf( Bat_CT);
	rwf( Bat_TN);
	rwf( Bat_ID);
	rwf( Bat_IR);
	rwf( Bat_VN);
	rwf( PPCB);
	rwf( Bat_rc); { rendimiento de carga }
	rwf( Bat_x1);
	rwf( Bat_y1);
	rwf( Bat_x2);
	rwf( Bat_y2);

  rwi( NPaneles );
	rwf( Paneles_PotenciaPicoPorPanel);
	rwf( Paneles_InclinacionDePaneles);
  rwi( Paneles_UsarUnAnguloPorMes );
  for k := 1 to 12 do
      rwf( NReal( Paneles_Angulos[ T_Mes(k-1)]) );

	rwi( PeriodosTotales );
	rwi( DiasPermitidosDeDeficit);


  try
    rwb(usarModeloCEGHSolar);
  except
    usarModeloCEGHSolar:= true;
  end;
  closefile( RW_f );
end;

function GetExeDir: string;
var
  s: string;
begin
    s:= ParamStr( 0 );
    s:= ExtractFileDir( s );
    result:= s;
end;


procedure ALInicio;  far;

label FinPrint;

begin

// LeerEscenario

	VentanaDeDeficit := 2 * DiasPermitidosDeDeficit;
	VentanaDeExcesos := VentanaDeDeficit;

	NumeroDePanelesDe48W:= NPaneles*Paneles_PotenciaPicoPorPanel/48;
	auto:= false;


(******
	{$IFDEF PANLOG}
	assign(fbat, 'CapBat.log');
	rewrite(fbat);
	{$ENDIF}
******)

	Latido:= NucleoT.Tic_Hora;
	PasoDeTiempo:= 3600;

	RandSeed:=31;
	contador:=0;
//  fdsol_ktcegh.test;

  if usarModeloCEGHSolar then
    xF:= TFDSol_ktcegh.Create('Sol', Latitud, Longitud, GetExeDir+'\'+archiDatosSintetizador)
  else
	xF:=  FuenteAnilloRuidoso.Create('Sol', Latitud, Longitud );


if Paneles_UsarUnAnguloPorMes= 0 then
	xpanel:= TPanelSolar.Create(
      'Paneles',
			NumeroDePanelesDe48W * 0.36, {  rea en m2 del panel }
			xF, { Fuente de energ¡a solar }
			Paneles_InclinacionDePaneles,
      NumerodePanelesDe48W * 48
      )
else
	xpanel:= TPanelSolar.Create(
      'Paneles',
			NumeroDePanelesDe48W * 0.36, {  rea en m2 del panel }
			xF, { Fuente de energ¡a solar }
			Paneles_Angulos,
      NumerodePanelesDe48W * 48
      );



	Quantum := 0;
	Demanda:= TDemHT.Create(
    'Demanda',
		PerfilCDC,
		EstacionalCDC,
    1.0/1000.0, // para pasarlo a kW
    8);
	Demanda.AcumQ(Quantum);

	Bateria:= TBateriaHD.Create(
    'Batería',
			CapacidadDeBateria, {Ah}
			Bat_TN,  {TN}
			Bat_CT, {CT}
			Bat_IR,  {ImaxR}
			Bat_ID,   {ImaxD}
			Bat_VN,  {VN}
			PPCB,
			Bat_rc,
			bat_x1, bat_x2, bat_y1, bat_y2 );



	e1:= TEvaluador.Create( 8, 8, Deficit, Quantum * VentanaDeDeficit, VentanaDeDeficit);
	e2:= TEvaluador.Create( 1, 4, Exceso, 20*Quantum * VentanaDeExcesos, VentanaDeExcesos);
  histoAniosVidaBat:= THistograma.Create(0, 20, 100);

	NucleoT.CadaDia.AgregarProcTarea(@ImprimirFecha, VACIA);



	NucleoT.CadaHora.AgregarProcTarea(@Gestion, VACIA);
	NucleoT.CadaAnio.AgregarProcTarea(@CadaPeriodoDeEvaluacion, VACIA);


  FinPrint:

end;

procedure AlFinal; far;
var
	fout: text;
  k: T_Mes;
  whdia: NReal;
//  histogs: Text;
begin

	assign(fout, 'simsolar-sal2.xlt' );
  {$I-}
	append(fout);
  {$I+}
  if ioresult <> 0 then
  begin
    rewrite( fout );

    write( fout, 'Fecha' );
  	write(fout,#9,'CapBat[Ah]');
	  write(fout,#9,'PPCB[p.u.]');
  	write(fout,#9,'nP48W[u]');
    write(fout,#9,'betaMín[º]');
    write(fout,#9,'betaMáx[º]');
  	write(fout,#9,'ddd-pne90%');
  	write(fout,#9,'ddd-vm' );
	  write(fout,#9,'ddd-pne10%');
  	write(fout,#9,'Dem.Prom. [Wh/día]');
    write(fout,#9,'dde-pe90%' );
    write(fout,#9,'dde-vm' );
    write(fout,#9,'dde-pe10%');
    write(fout,#9,'Años de vida de la batería' );
    for k := enero to diciembre do
      write(fout, #9, '[Wh/día] '+IntToStr( Ord(k )+1 ) );
    for k := enero to diciembre do
      write(fout, #9, '[º]'+IntToStr( Ord(k )+1 ) );
    writeln( fout );
  end;

  write( fout, DateTimeToStr( now ) );
	write(fout, #9,CapacidadDeBateria:6:2);
	write(fout, #9,PPCB:6:2);
	write(fout, #9,NumeroDePanelesDe48W:6:2);

  write(fout, #9, minimo(paneles_Angulos):6:2);
  write(fout, #9, maximo(paneles_Angulos):6:2);

	write(fout, #9,e1.histo.xArea(0.9)/Quantum:8:2);
	write(fout, #9,e1.histo.ValorMedio/Quantum:8:2);
	write(fout, #9,e1.histo.xArea(0.1)/Quantum:8:2);
	write(fout,  #9, (Quantum/3600.0):12:2);
	write(fout, #9,e2.histo.xArea(0.1)/Quantum:8:2);
	write(fout, #9,e2.histo.ValorMedio/Quantum:8:2);
	write(fout, #9,e2.histo.xArea(0.9)/Quantum:8:2);
	write(fout, #9,FloatToStrF(histoAniosVidaBat.ValorMedio, ffFixed, 6, 1 ));

  whdia:= suma( perfilCDC );
  for k := enero to diciembre do
    write(fout, #9, FloatToStrF( (EstacionalCDC[k]* whdia), ffFixed, 12,2 ));

  for k := enero to diciembre do
    write(fout, #9, FloatToStrF(Paneles_Angulos[k], ffFixed, 6, 1 ) );


  writeln( fout, '' );
	close(fout);

  fSimSolar.eDDDEsperados.Text:= FloatToStrF( e1.histo.ValorMedio/Quantum, ffFixed, 6, 1 );
  fSimSolar.eDDDpne90.Text:= FloatToStrF( e1.histo.xArea(0.9)/Quantum, ffFixed, 6, 1 );
  fSimSolar.eDDEEsperados.Text:=FloatToStrF( e2.histo.ValorMedio/Quantum, ffFixed, 6, 1 );
  fSimSolar.eDDEpe90.Text:=FloatToStrF( e2.histo.xArea(0.1)/Quantum, ffFixed, 6, 1 );
  fSimSolar.eBatDeg_med.Text:= FloatToStrF(histoAniosVidaBat.ValorMedio, ffFixed, 6, 1 );

{  Assign(histogs, 'histos.txt');
  rewrite(histogs);
  writeln(histogs, 'Dias de Deficit');
  e1.histo.WriteTxt(histogs);
  Writeln(histogs);
  writeln(histogs, 'Dias de Exceso');
  e2.histo.WriteTxt(histogs);
  close(histogs);}

  fSimSolar.lblEnergiaDelDiaMedio.Caption:= 'Energía del día medio [Wh]:'+
    FloatToStrF( Quantum/3600, ffFixed, 6, 1 );

  histoAniosVidaBat.Free;
  e2.Free;
  e1.Free;
  Bateria.Free;
  Demanda.Free;
  xpanel.Free;
  xf.Free;
end;


var
  tmpsal: textfile;

procedure Pesca; far;
begin

	DiasDeDeficitResultante := e1.GetValor/Quantum;
  DiasDeExcesoResultante:= e2.GetValor/Quantum;
  writeln( tmpsal, DiasDeDeficitResultante, #9, DiasDeExcesoResultante );

  fSimSolar.ProgressBar1.Position:= NumeroDePeriodo+1;
//	if NumeroDePeriodo+1 < PeriodosTotales then


	e1.evaluar;
	e2.evaluar;

  if Bateria.SumaDegradante>= Bateria.A_Degradante then
  begin
    // hay que cambiar la batería

    histoAniosVidaBat.Anotar( Bateria.NHorasEnSumaDegradante/Bateria.SumaDegradante*Bateria.A_Degradante / 365.0/24 );
    Bateria.LimpiarSumaDegradante;
  end;
  Bateria.Ciclado.Clear;

end;


procedure TfSimSolar.Ejecutar;
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }

    assignfile( tmpsal, 'ddye.xlt' );
    rewrite( tmpsal );
    writeln( tmpsal, 'Déficit y exceso de energía expresados en días equivalentes de energía.' );
    writeln( tmpsal, 'Déficit', #9, 'Exceso' );

    ImpFecha:= False;
    Proc_Arrancar:=AlInicio;
    Proc_Pescar:=Pesca;
    Proc_Finalizar:=Alfinal;

    Simular;

    closefile( tmpsal );


  except
    on E:Exception do
      showmessage(E.Classname+': '+ E.Message);
  end;
end;

procedure TfSimSolar.Leer1Click(Sender: TObject);
begin
  if openDialog1.Execute then
  begin
    archi:=opendialog1.FileName;
    carpetaDeLaCorrida:= extractFileDir( archi );
    chdir( carpetaDeLaCorrida );
  	Self.rwEscenario( 0 );
    self.ActualizarResumenUbicacion;
    self.ActualizarResumenCarga;
    self.ActualizarResumenPaneles;
    self.ActualizarResumenBaterias;
    self.ActualizarResumenSimulacion;
    resetModificado;
    Self.gbResultados.Visible:= false;
  end;
end;

procedure TfSimSolar.Nuevo1Click(Sender: TObject);
var
  k: integer;
  mes: T_Mes;
begin
  if xmodificado then
    if Cancelar_GuardarSiNo then exit;

  Latitud:= 31.7;
  Longitud:= 56;

  archi:= '';
  resetModificado;

  for k:= 0 to 23 do
    PerfilCDC[k]:= 0;

    PerfilCDC[8]:= 3.0;
    PerfilCDC[9]:= 3.0;
    PerfilCDC[11]:= 13.0;
    PerfilCDC[12]:= 73.0;
    PerfilCDC[13]:= 13.0;
    PerfilCDC[14]:= 13.0;
    PerfilCDC[17]:= 10.0;
    PerfilCDC[18]:= 19.00;
    PerfilCDC[19]:= 9.0;
    PerfilCDC[10]:= 9.0;

  EDiariaWh:= 0;
  for k:=0 to 23 do
    EDiariaWh:= EDiariaWh + PerfilCDC[k];


  for mes:= Enero to Marzo do
    EstacionalCDC[mes]:= 1.2;

  for mes:= Abril to Setiembre do
    EstacionalCDC[mes]:= 1.0;

  for mes:= Octubre to Diciembre do
    EstacionalCDC[mes]:= 1.2;

// Valores del banco de baterías por defecto
  CapacidadDeBateria:= 150.0; // Ah
	Bat_CT:=  0.001; // coeficiente de variación de la capacidad con la temperatura
	Bat_TN:= 25.0; // temperatura nominal.
	Bat_ID:= 30.0; // [A] corriente máxima de descarga
	Bat_IR:= 20.0; // [A] corriente máxima de recarga
	Bat_VN:= 12.0; // [V] tensión nominal de la batería.
	PPCB:= 0.3; // Profundidad Permitida de uso de Capacidad de la Batería.
	Bat_rc:= 0.92; // rendimiento de carga
	Bat_x1:= 0.3; // profundidad de descarga del punto PC1
	Bat_y1:= 1200.0; // número de ciclos del punto PC1
	Bat_x2:= 0.5; // profundidad de descarga del punto PC2
	Bat_y2:= 200; // número de ciclos del punto PC2

(* Los puntos PC1 y PC2 definen la característica de vida útil
de la batería en función de la cantidad de ciclos de carga y descarga
que soporta según la profundidad de los ciclos. *)

	NPaneles:= 1;
	Paneles_PotenciaPicoPorPanel:= 48;
	Paneles_InclinacionDePaneles:= 50;
  Paneles_UsarUnAnguloPorMes:= 0;
  for k:= 1 to 12 do
    Paneles_Angulos[T_Mes(k-1)]:= Paneles_InclinacionDePaneles;


	PeriodosTotales:= 100;
//	inc(PeriodosTotales);
	DiasPermitidosDeDeficit:= 10;

  usarModeloCEGHSolar:= true;
  
  setModificado;

  self.ActualizarResumenUbicacion;
  self.ActualizarResumenCarga;
  self.ActualizarResumenPaneles;
  self.ActualizarResumenBaterias;
  self.ActualizarResumenSimulacion;

end;

end.



