Calculate cell temperature using an emperical heat loss factor model
    as implemented in PVsyst.

    The heat loss factors provided through the 'model_params' argument
    represent the combined effect of convection, radiation and conduction,
    and their values are experimentally determined.

    Parameters
    ----------
    poa_global : numeric
        Total incident irradiance in W/m^2.

    temp_air : numeric
        Ambient dry bulb temperature in degrees C.

    wind_speed : numeric, default 1.0
        Wind speed in m/s measured at the same height for which the wind loss
        factor was determined.  The default value is 1.0, which is the wind
        speed at module height used to determine NOCT.

    eta_m : numeric, default 0.1
        Module external efficiency as a fraction, i.e., DC power / poa_global.

    alpha_absorption : numeric, default 0.9
        Absorption coefficient

    model_params : string, tuple, or list (no dict), default 'freestanding'
        Heat loss factors to be used.

        If string, can be:

            * 'freestanding' (default)
                Modules with rear surfaces exposed to open air (e.g. rack
                mounted).
            * 'insulated'
                Modules with rear surfaces in close proximity to another
                surface (e.g. roof mounted).

        If tuple/list, supply parameters in the following order:

            * constant_loss_factor : float
                Combined heat loss factor coefficient. Freestanding
                default is 29, fully insulated arrays is 15.

            * wind_loss_factor : float
                Combined heat loss factor influenced by wind. Default is 0.

    Returns
    -------
    temp_cell : numeric or Series
        Cell temperature in degrees Celsius

    References
    ----------
    [1]"PVsyst 6 Help", Files.pvsyst.com, 2018. [Online]. Available:
    http://files.pvsyst.com/help/index.html. [Accessed: 10- Dec- 2018].

    [2] Faiman, D. (2008). "Assessing the outdoor operating temperature of
    photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.

def pvsyst_celltemp(poa_global, temp_air, wind_speed=1.0, eta_m=0.1,
                    alpha_absorption=0.9, model_params='freestanding'):
    """
    Calculate cell temperature using an emperical heat loss factor model
    as implemented in PVsyst.

    The heat loss factors provided through the 'model_params' argument
    represent the combined effect of convection, radiation and conduction,
    and their values are experimentally determined.

    Parameters
    ----------
    poa_global : numeric
        Total incident irradiance in W/m^2.

    temp_air : numeric
        Ambient dry bulb temperature in degrees C.

    wind_speed : numeric, default 1.0
        Wind speed in m/s measured at the same height for which the wind loss
        factor was determined.  The default value is 1.0, which is the wind
        speed at module height used to determine NOCT.

    eta_m : numeric, default 0.1
        Module external efficiency as a fraction, i.e., DC power / poa_global.

    alpha_absorption : numeric, default 0.9
        Absorption coefficient

    model_params : string, tuple, or list (no dict), default 'freestanding'
        Heat loss factors to be used.

        If string, can be:

            * 'freestanding' (default)
                Modules with rear surfaces exposed to open air (e.g. rack
                mounted).
            * 'insulated'
                Modules with rear surfaces in close proximity to another
                surface (e.g. roof mounted).

        If tuple/list, supply parameters in the following order:

            * constant_loss_factor : float
                Combined heat loss factor coefficient. Freestanding
                default is 29, fully insulated arrays is 15.

            * wind_loss_factor : float
                Combined heat loss factor influenced by wind. Default is 0.

    Returns
    -------
    temp_cell : numeric or Series
        Cell temperature in degrees Celsius

    References
    ----------
    [1]"PVsyst 6 Help", Files.pvsyst.com, 2018. [Online]. Available:
    http://files.pvsyst.com/help/index.html. [Accessed: 10- Dec- 2018].

    [2] Faiman, D. (2008). "Assessing the outdoor operating temperature of
    photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.
    """

    pvsyst_presets = TEMP_MODEL_PARAMS['pvsyst']

    if isinstance(model_params, str):
        model_params = model_params.lower()
        constant_loss_factor, wind_loss_factor = pvsyst_presets[model_params]
    elif isinstance(model_params, (tuple, list)):
        constant_loss_factor, wind_loss_factor = model_params
    else:
        raise TypeError(
            "Please provide model_params as a str, or tuple/list."
        )

    total_loss_factor = wind_loss_factor * wind_speed + constant_loss_factor
    heat_input = poa_global * alpha_absorption * (1 - eta_m)
    temp_difference = heat_input / total_loss_factor
    temp_cell = temp_air + temp_difference

    return temp_cell