			SUBROUTINE TYPE240 (TIME,XIN,OUT,T,DTDT,PAR,INFO,ICNTRL,*) 
C************************************************************************
C Object: Simple PV Battery Component With Dispatch Control
C Simulation Studio Model: Type240
C 
C Authors: Aron Dobos, Michael Wagner
C Date:	 March 09, 2009 last modified: February 24, 2010
C 
C 
C *** 
C *** Model Parameters 
C *** 
C        1    Capacity - [kWh]
C        2    RoundtripEff - [frac]
C        3    InitialEnergy - [kWh]
C        4    MinSOC - [frac]
C        5    MaxRate - [kW/hr]
C        6    DisableSolar - [0;1]
C        7    CanCharge_1 - [0;1]
C        8    CanCharge_2 - [0;1]
C        9    CanCharge_3 - [0;1]
C       10    CanCharge_4 - [0;1]
C       11    CanDischarge_1 - [0;1]
C       12    CanDischarge_2 - [0;1]
C       13    CanDischarge_3 - [0;1]
C       14    CanDischarge_4 - [0;1]
C       15    GridCharge_1 - [0;1]
C       16    GridCharge_2 - [0;1]
C       17    GridCharge_3 - [0;1]
C       18    GridCharge_4 - [0;1]
C *** 
C *** Model Inputs 
C *** 
C		1   Parray	kW [-Inf;+Inf]
C		2   Pdemand	kW [-Inf;+Inf]
C       3   DispatchPeriod - [1,2,3,4]
C *** 
C *** Model Outputs 
C *** 
C		1   BatteryEnergy	kWh [0;+Inf]
C		2   Pgrid_tofrom	kW  [-Inf;+Inf]
C       3   Psysout         kW  [0;+Inf]
C       4   Pbatt_tofrom    kW  [-Inf;+Inf]
C       5   OpMode

C************************************************************************

C    TRNSYS acess functions (allow to acess TIME etc.) 
      USE TrnsysConstants
      USE TrnsysFunctions

C-----------------------------------------------------------------------------------------------------------------------
C    REQUIRED BY THE MULTI-DLL VERSION OF TRNSYS
      !DEC$ATTRIBUTES DLLEXPORT :: TYPE240				!SET THE CORRECT TYPE NUMBER HERE
C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    TRNSYS DECLARATIONS
      IMPLICIT NONE	

	DOUBLE PRECISION XIN, OUT, TIME, PAR, STORED, T, DTDT	
	INTEGER*4 INFO(15),NP,NI,NOUT,ND,NPAR,NIN,NDER,IUNIT,ITYPE,ICNTRL,
     & NSTORED
	CHARACTER*3 OCHECK, YCHECK
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    USER DECLARATIONS - SET THE MAXIMUM NUMBER OF PARAMETERS (NP), INPUTS (NI),
C    OUTPUTS (NOUT), AND DERIVATIVES (ND) THAT MAY BE SUPPLIED FOR THIS TYPE
      PARAMETER (NP=18,NI=3,NOUT=6,ND=0,NSTORED=1)
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    REQUIRED TRNSYS DIMENSIONS
      DIMENSION XIN(NI),OUT(NOUT),PAR(NP),YCHECK(NI),OCHECK(NOUT),
	1   STORED(NSTORED),T(ND),DTDT(ND)
      INTEGER NITEMS
C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    ADD DECLARATIONS AND DEFINITIONS FOR THE USER-VARIABLES HERE


C    PARAMETERS
      DOUBLE PRECISION BatteryCapacity,RoundtripEff,InitialEnergy,
     & MinSOC,MaxRate,CanCharge(4),CanDischarge(4),GridCharge(4)
      INTEGER DisableSolar
     
C    INPUTS
      DOUBLE PRECISION Parray,Pdemand
      INTEGER DispatchPeriod
      
C    OUTPUTS
      DOUBLE PRECISION Pgrid_tofrom,Pbatt_tofrom,Psysout
      INTEGER OpMode
      
C    LOCAL VARIABLES FOR CALCULATIONS    
      DOUBLE PRECISION BatteryEnergy,TimeStep,batt_soc
      DOUBLE PRECISION Pgrid,ChargePower,Pexcess,DischargePower,Pneeded
      INTEGER PeriodCanCharge,PeriodCanDischarge,PeriodGridCharge

C-----------------------------------------------------------------------------------------------------------------------
C       READ IN THE VALUES OF THE PARAMETERS IN SEQUENTIAL ORDER
      BatteryCapacity = PAR(1)
      RoundtripEff = PAR(2)
      InitialEnergy = PAR(3)
      MinSOC = PAR(4)
      MaxRate = PAR(5)
      DisableSolar = INT(PAR(6))
      CanCharge(1) = INT(PAR(7))
      CanCharge(2) = INT(PAR(8))
      CanCharge(3) = INT(PAR(9))
      CanCharge(4) = INT(PAR(10))
      CanDischarge(1) = INT(PAR(11))
      CanDischarge(2) = INT(PAR(12))
      CanDischarge(3) = INT(PAR(13))
      CanDischarge(4) = INT(PAR(14))
      GridCharge(1) = INT(PAR(15))
      GridCharge(2) = INT(PAR(16))
      GridCharge(3) = INT(PAR(17))
      GridCharge(4) = INT(PAR(18))
      
C-----------------------------------------------------------------------------------------------------------------------
C    RETRIEVE THE CURRENT VALUES OF THE INPUTS TO THIS MODEL FROM THE XIN ARRAY IN SEQUENTIAL ORDER

      Parray = XIN(1)
      Pdemand = XIN(2)
      DispatchPeriod = INT(XIN(3))
      
	IUNIT=INFO(1)
	ITYPE=INFO(2)

C-----------------------------------------------------------------------------------------------------------------------
C    SET THE VERSION INFORMATION FOR TRNSYS
      IF(INFO(7).EQ.-2) THEN
	   INFO(12)=16
	   RETURN 1
	ENDIF
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    DO ALL THE VERY LAST CALL OF THE SIMULATION MANIPULATIONS HERE
      IF (INFO(8).EQ.-1) THEN
	   RETURN 1
	ENDIF
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    PERFORM ANY 'AFTER-ITERATION' MANIPULATIONS THAT ARE REQUIRED HERE
C    e.g. save variables to storage array for the next timestep
      IF (INFO(13).GT.0) THEN
	   NITEMS=1
	   STORED(1)=BatteryEnergy ! Battery Energy (stored)
         CALL setStorageVars(STORED,NITEMS,INFO)
	   RETURN 1
	ENDIF
C
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    DO ALL THE VERY FIRST CALL OF THE SIMULATION MANIPULATIONS HERE
      IF (INFO(7).EQ.-1) THEN

C       SET SOME INFO ARRAY VARIABLES TO TELL THE TRNSYS ENGINE HOW THIS TYPE IS TO WORK
         INFO(6)=NOUT				
         INFO(9)=1				
	   INFO(10)=0	!STORAGE FOR VERSION 16 HAS BEEN CHANGED				

C       SET THE REQUIRED NUMBER OF INPUTS, PARAMETERS AND DERIVATIVES THAT THE USER SHOULD SUPPLY IN THE INPUT FILE
C       IN SOME CASES, THE NUMBER OF VARIABLES MAY DEPEND ON THE VALUE OF PARAMETERS TO THIS MODEL....
         NIN=NI
	   NPAR=NP
	   NDER=ND
	       
C       CALL THE TYPE CHECK SUBROUTINE TO COMPARE WHAT THIS COMPONENT REQUIRES TO WHAT IS SUPPLIED IN 
C       THE TRNSYS INPUT FILE
	   CALL TYPECK(1,INFO,NIN,NPAR,NDER)

C       SET THE NUMBER OF STORAGE SPOTS NEEDED FOR THIS COMPONENT
         NITEMS=1
	   CALL setStorageSize(NITEMS,INFO)

C       RETURN TO THE CALLING PROGRAM
         RETURN 1

      ENDIF
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    DO ALL OF THE INITIAL TIMESTEP MANIPULATIONS HERE - THERE ARE NO ITERATIONS AT THE INTIAL TIME
      IF (TIME .LT. (getSimulationStartTime() +
     . getSimulationTimeStep()/2.D0)) THEN

C       SET THE UNIT NUMBER FOR FUTURE CALLS
         IUNIT=INFO(1)
         ITYPE=INFO(2)

C       CHECK THE PARAMETERS FOR PROBLEMS AND RETURN FROM THE SUBROUTINE IF AN ERROR IS FOUND
C         IF(...) CALL TYPECK(-4,INFO,0,"BAD PARAMETER #",0)

C       PERFORM ANY REQUIRED CALCULATIONS TO SET THE INITIAL VALUES OF THE OUTPUTS HERE
C		 BatteryEnergy
			OUT(1)=0
C		 Pgrid_tofrom
			OUT(2)=0
C		 Psysout
			OUT(3)=0
C		 Pbatt_tofrom
			OUT(4)=0
C        Operation Mode
            OUT(5)=-1
C        state of charge
            OUT(6)=0          

C       PERFORM ANY REQUIRED CALCULATIONS TO SET THE INITIAL STORAGE VARIABLES HERE
         NITEMS=1
	   STORED(1)=InitialEnergy  !Battery energy at start
C       PUT THE STORED ARRAY IN THE GLOBAL STORED ARRAY
         CALL setStorageVars(STORED,NITEMS,INFO)

C       RETURN TO THE CALLING PROGRAM
         RETURN 1

      ENDIF
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C    *** ITS AN ITERATIVE CALL TO THIS COMPONENT ***
C-----------------------------------------------------------------------------------------------------------------------

	    
C-----------------------------------------------------------------------------------------------------------------------
C    RETRIEVE THE VALUES IN THE STORAGE ARRAY FOR THIS ITERATION
      NITEMS=1
	CALL getStorageVars(STORED,NITEMS,INFO)
      BatteryEnergy=STORED(1)
C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    CHECK THE INPUTS FOR PROBLEMS
C      IF(...) CALL TYPECK(-3,INFO,'BAD INPUT #',0,0)
C	IF(IERROR.GT.0) RETURN 1
C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    *** PERFORM ALL THE CALCULATION HERE FOR THIS MODEL. ***
C-----------------------------------------------------------------------------------------------------------------------

C     get dispatch control variables
      Pgrid = 0
      TimeStep = getSimulationTimeStep()
      
      IF (DisableSolar .ne. 0) THEN
        Parray = 0
      ENDIF
      
      IF (DispatchPeriod .lt. 1) THEN
        DispatchPeriod = 1
      ENDIF
      
      IF (DispatchPeriod .gt. 4) THEN
        DispatchPeriod = 4
      ENDIF
      
      OpMode = -1
      
      IF (BatteryCapacity .le. 0) THEN
        Psysout = Parray
        Pgrid_tofrom = 0
        batt_soc=0
      ELSE
      
        PeriodCanCharge = CanCharge( DispatchPeriod )
        PeriodCanDischarge = CanDischarge( DispatchPeriod )
        PeriodGridCharge = GridCharge( DispatchPeriod )

        IF (PeriodGridCharge .ne. 0) THEN
      
C     we are forcing charging from the grid in this period
C     Power [kW] = MaxRate [kWh/hr]
          ChargePower = MaxRate
          IF ( BatteryEnergy+ChargePower*TimeStep 
     &         .gt. BatteryCapacity ) THEN
              ChargePower = (BatteryCapacity - BatteryEnergy)/TimeStep
          ENDIF
        
          Pbatt_tofrom = ChargePower * RoundtripEff
          BatteryEnergy = BatteryEnergy + Pbatt_tofrom*TimeStep
          Pgrid = 0-(Pdemand+Pbatt_tofrom)
          OpMode = 5
        
        ELSE
      
          IF ( Parray .gt. Pdemand ) THEN
            Pexcess = Parray - Pdemand
          
            IF ( (PeriodCanCharge .eq. 0) .or. 
     &           (BatteryEnergy .ge. BatteryCapacity) ) THEN
              Pgrid = Pexcess
              OpMode = 1
            ELSE
              ChargePower = Pexcess
            
              IF ( ChargePower .gt. MaxRate ) THEN
                ChargePower = MaxRate
              ENDIF
            
              IF ( BatteryEnergy + ChargePower*TimeStep
     &                .gt. BatteryCapacity ) THEN
                ChargePower = (BatteryCapacity - BatteryEnergy)/TimeStep
              ENDIF
            
              Pbatt_tofrom = ChargePower * RoundtripEff
              BatteryEnergy = BatteryEnergy + Pbatt_tofrom*TimeStep
              Pgrid = Pexcess - ChargePower
              OpMode = 2
            ENDIF
          
          ELSEIF ( Pdemand .gt. Parray ) THEN
        
            IF ( (PeriodCanDischarge .eq. 0) .or.
     &           (BatteryEnergy/BatteryCapacity .lt. MinSOC) ) THEN
              Pgrid = Parray - Pdemand
              OpMode = 3
            ELSE
              Pneeded = Pdemand - Parray
              DischargePower = Pneeded
            
              IF (DischargePower .gt. MaxRate ) THEN
                DischargePower = MaxRate
              ENDIF
              
              IF ( (BatteryEnergy-DischargePower*TimeStep) 
     &            / BatteryCapacity .lt. MinSOC) THEN
                DischargePower = 
     &                 (BatteryEnergy-MinSOC*BatteryCapacity)/TimeStep
              ENDIF
            
              Pbatt_tofrom = 0 - DischargePower
              BatteryEnergy = BatteryEnergy + Pbatt_tofrom*TimeStep
              Pgrid = 0-(Pneeded-DischargePower)
              OpMode = 4
            ENDIF
          ENDIF
        ENDIF
      
        Pgrid_tofrom = Pgrid
        Psysout = Pdemand+Pgrid
        
        batt_soc= BatteryEnergy/BatteryCapacity
        
      ENDIF
      
C-----------------------------------------------------------------------------------------------------------------------

C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    SET THE STORAGE ARRAY AT THE END OF THIS ITERATION IF NECESSARY
      NITEMS=1
      STORED(1)=BatteryEnergy
	CALL setStorageVars(STORED,NITEMS,INFO)
C-----------------------------------------------------------------------------------------------------------------------
C-----------------------------------------------------------------------------------------------------------------------
C    SET THE OUTPUTS FROM THIS MODEL IN SEQUENTIAL ORDER AND GET OUT

C		 Battery energy
      OUT(1)=BatteryEnergy
C		 Energy to/from grid
      OUT(2)=Pgrid_tofrom
C		 System output power
      OUT(3)=Psysout
C		 Energy to/from battery
      OUT(4)=Pbatt_tofrom
C        Operation Mode
      OUT(5)=OpMode			
C        State of charge
      OUT(6)=batt_soc

C-----------------------------------------------------------------------------------------------------------------------
C    EVERYTHING IS DONE - RETURN FROM THIS SUBROUTINE AND MOVE ON
      RETURN 1
      END
C-----------------------------------------------------------------------------------------------------------------------
