3
1-iH                 @   s~  d Z ddlZddlmZ ddlmZmZmZ ddlmZm	Z	 yddl
mZmZ W n$ ek
rt   ddl
mZmZ Y nX eejd d	 Zd
Zee dddZdFeeee dddZeedddZdGeeeedddZdHeeeeee dddZdIeeeeedddZdJeeee ddd ZdKeeeeed"d#d$ZdLeeeeeed%d&d'Zeeed(d)d*Zedd+d,Ze d-krze!d. e!d/d0  e Z"e!d1e"  e Z#e!d2e$e#  x0e#D ](Z%e!d3e%d4  d5e%j&d6d7 d8 qW ed9dd:Z'e'r.e!d; e!d<e'd4  d5e'd=  d8 ed>d9dd?Z(e(j&d@rze!dA e!dBe(dC d4   e!dDe(dE  d8 dS )Ma  
British Gas Tariff API

Provides functions to read cached British Gas tariff data
for use in the main bill analyser application.

Usage:
    from scraper.british_gas_api import get_british_gas_tariffs, find_best_tariff

    # Get all tariffs for a region
    tariffs = get_british_gas_tariffs(postcode="HP20 1HP")

    # Find best matching tariff
    best = find_best_tariff(
        postcode="HP20 1HP",
        annual_electricity_kwh=2900,
        annual_gas_kwh=12000
    )
    N)Path)OptionalListDict)datetime	timedelta   )get_dno_for_postcodefind_matching_regionoutputzbritish-gas-tariffs.json   )returnc              C   s   t j sdS yftt d} tj| }W dQ R X |jd}|rptj|jdd}tj	|j
| }|ttdkrpdS |S  tk
r   dS X dS )z
    Load cached British Gas tariff data.

    Returns:
        Dictionary with tariff data, or None if not available/stale
    Nr
scraped_atZz+00:00)hours)TARIFF_FILEexistsopenjsonloadgetr   fromisoformatreplacenowtzinfor   CACHE_MAX_AGE_HOURS	Exception)fdatar   scraped_timeage r"   9/home/mac944/apps/billy-energy/scraper/british_gas_api.pyget_cached_data&   s    
r$   )postcoderegionr   c       
      C   s@  t  }|sg S |jdg }|  rT| rTx(|D ] }|jdr,|jdr,|d S q,W g S | rt| }|jd}|rdd |D }t| |}x0|D ](}|jdr|jd|kr|jdg S qW |rxL|D ]D}|jdsq|jddj }	|j |	kp|	|j kr|jdg S qW x.|D ]&}|jdr|jdr|d S qW g S )a  
    Get British Gas tariffs, optionally filtered by postcode or region.

    Uses DNO lookup to accurately match postcodes to their electricity
    distribution region, ensuring users see correct regional pricing.

    Args:
        postcode: UK postcode to find regional tariffs
        region: Region name (alternative to postcode)

    Returns:
        List of tariff dictionaries for the matched region
    regionssuccesstariffsr&   c             S   s    g | ]}|j d r|j dqS )r(   r&   )r   ).0r   r"   r"   r#   
<listcomp>c   s    z+get_british_gas_tariffs.<locals>.<listcomp> )r$   r   r	   r
   lower)
r%   r&   r   r'   r   dno_infotarget_regionavailable_regionsmatched_regionr_regionr"   r"   r#   get_british_gas_tariffsA   s:    






r3   )r%   r   c       	      C   s   t | }|jd}t }g }d}d}|r|jdg }x<|D ]4}|jdr:|jd|kr:|jdg }|jd}P q:W |sx<|D ]4}|jdr||jdr||jdg }|jd}d}P q|W | |jd|jd	|jd|jd
d|t||||rdnddS )z
    Get British Gas tariffs with detailed region matching info.

    Args:
        postcode: UK postcode

    Returns:
        Dictionary with tariffs and region matching details
    r&   FNr'   r(   r)   TZdno_codeZdno_namepostcode_prefix)codenamer&   r4   z+Using national tariffs from fallback region)r%   Zdnor)   Ztariff_countusing_fallbackactual_regionZnote)r	   r   r$   len)	r%   r.   r/   r   r)   r7   r8   r'   r   r"   r"   r#   get_tariffs_with_region_info|   s<    





r:   )tariffannual_electricity_kwhannual_gas_kwhr   c             C   s   | j di }| j di }|j ddp&d}|j ddp6d}|| d d| d  }d}|dkr|j ddpjd}	|j ddpzd}
||	 d d|
 d  }t|| dS )	a3  
    Calculate annual cost for a tariff based on usage.

    Args:
        tariff: Tariff dictionary with rates
        annual_electricity_kwh: Annual electricity usage in kWh
        annual_gas_kwh: Annual gas usage in kWh (0 for electricity only)

    Returns:
        Estimated annual cost in pounds
    electricitygasunit_rate_pencer   standing_charge_penced   im     )r   round)r;   r<   r=   elecr?   Zelec_unit_rateelec_standingZ	elec_costgas_costgas_unit_rategas_standingr"   r"   r#   calculate_annual_cost   s    rJ   T  .  )r%   r<   r=   tariff_typer   c       	         sz   t | d}|sdS  r( fdd|D }|s0dS d}td}x8|D ]0}t|||}||k rB|}||||dd}qBW |S )a  
    Find the best (cheapest) British Gas tariff for given usage.

    Args:
        postcode: Postcode to find regional tariffs
        annual_electricity_kwh: Annual electricity usage (default: UK average)
        annual_gas_kwh: Annual gas usage (default: UK average, 0 for elec only)
        tariff_type: Filter by type ("Fixed", "Variable", etc.)

    Returns:
        Best tariff with calculated cost, or None if no tariffs available
    )r%   Nc                s(   g | ] }|j d dj  j kr|qS )typer,   )r   r-   )r*   t)rM   r"   r#   r+      s    z$find_best_tariff.<locals>.<listcomp>inf)Zelectricity_kwhZgas_kwh)calculated_annual_costusage)r3   floatrJ   )	r%   r<   r=   rM   r)   bestZ	best_costr;   costr"   )rM   r#   find_best_tariff   s$    

rV   )current_annual_costr%   r<   r=   r   c       
   
   C   s   t |d}|sdddS g }x\|D ]T}t|||}| | }|j|jd|jd|t|d|dk|jd	|jd
d q"W |jdd d |r|d nd}	d| |	||	r|	d r|	d nddS )aa  
    Compare current tariff cost against British Gas options.

    Args:
        current_annual_cost: Current annual energy cost in pounds
        postcode: Postcode for regional tariffs
        annual_electricity_kwh: Annual electricity usage
        annual_gas_kwh: Annual gas usage

    Returns:
        Comparison results with potential savings
    )r%   FzABritish Gas tariff data not available. Run the scraper to update.)	availablemessager6   rN   rC   r   r>   r?   )r6   rN   annual_costsaving
is_cheaperr>   r?   c             S   s   | d S )NrZ   r"   )xr"   r"   r#   <lambda>1  s    z!compare_tariffs.<locals>.<lambda>)keyNTr\   r[   )rX   current_costbest_tariffZall_tariffspotential_saving)r3   rJ   appendr   rD   sort)
rW   r%   r<   r=   r)   Zcomparisonsr;   rU   r[   rT   r"   r"   r#   compare_tariffs  s.    

re   c       
      C   s   t  }|sdS |jdg }| r|t| }|jd}|r|dd |D }t| |}x.|D ]&}|jdrR|jd|krR|jdS qRW |rxJ|D ]B}|jdsq|jddj }	|j |	ks|	|j kr|jdS qW x(|D ] }|jdr|jdr|d S qW dS )	a  
    Get British Gas EV Power tariff for a region.

    The EV tariff has time-of-use pricing:
    - Peak rate: Standard daytime electricity rate
    - Off-peak rate: Cheaper overnight rate (12am-5am)

    Args:
        postcode: UK postcode to find regional EV tariff
        region: Region name (alternative to postcode)

    Returns:
        EV tariff dictionary with peak/off-peak rates, or None if not available
    Nr'   r&   c             S   s    g | ]}|j d r|j dqS )r(   r&   )r   )r*   r   r"   r"   r#   r+   Y  s    z!get_ev_tariff.<locals>.<listcomp>r(   	ev_tariffr,   )r$   r   r	   r
   r-   )
r%   r&   r   r'   r.   r/   r0   r1   r   r2   r"   r"   r#   get_ev_tariff>  s0    





rg         ?)rf   r<   r=   off_peak_percentager   c          	   C   sF  | j di }| j di }|| }|d|  }|j ddp:d}|j ddpJd}	|j ddpZd}
|| d }||	 d }d	|
 d }|| | }d}|dkr|j d
dpd}|j ddpd}|| d d	| d  }|| }t|dt|dt|dt|dt|dt|dt|dd|t|dd|t|| d ||	 d  ddS )a  
    Calculate annual cost for an EV tariff with peak/off-peak split.

    Args:
        ev_tariff: EV tariff dictionary with peak/off-peak rates
        annual_electricity_kwh: Total annual electricity usage in kWh
        annual_gas_kwh: Annual gas usage in kWh (0 for electricity only)
        off_peak_percentage: Fraction of electricity used during off-peak (0.0-1.0)
                            Default 0.5 assumes 50% overnight charging

    Returns:
        Dictionary with cost breakdown
    r>   r?   r   peak_unit_rate_pencer   off_peak_unit_rate_pencerA   rB   im  r@   rC   )peak_kwh	peak_costoff_peak_kwhoff_peak_costZstanding_charge_costtotal)Zkwhrp   )rZ   r>   r?   ri   Zsavings_from_off_peak)r   rD   )rf   r<   r=   ri   rE   r?   rn   rl   Z	peak_rateZoff_peak_raterF   rm   ro   Zelec_standing_costZtotal_elec_costrG   rH   rI   Z
total_costr"   r"   r#   calculate_ev_annual_costq  s8    rq   )rW   r%   r<   r=   ri   r   c       	      C   s   t |d}|sdddS t||||}|d }| | }d| |jddd	|t|d
|dk|jdi jd|jdi jd|jdi jd|jdi jd|jdi jdd|d|dkr|ndt||dS )a  
    Compare current tariff cost against British Gas EV Power tariff.

    Useful for EV owners to see if switching to time-of-use pricing saves money.

    Args:
        current_annual_cost: Current annual energy cost in pounds
        postcode: Postcode for regional tariffs
        annual_electricity_kwh: Annual electricity usage
        annual_gas_kwh: Annual gas usage
        off_peak_percentage: Fraction of electricity used during off-peak hours

    Returns:
        Comparison results with potential savings
    )r%   FzDBritish Gas EV tariff data not available. Run the scraper to update.)rX   rY   rZ   Tr6   zEV Power TariffZEVrC   r   r>   rj   rk   rA   r?   r@   )Zelectricity_peak_penceZelectricity_off_peak_penceZelectricity_standing_penceZgas_unit_penceZgas_standing_pence)r6   rN   rZ   r[   r\   Zratescost_breakdown)rX   r`   rf   rb   Zrecommendation)rg   rq   r   rD   _get_ev_recommendation)	rW   r%   r<   r=   ri   rf   rr   Zev_costr[   r"   r"   r#   compare_ev_tariff  s4    

rt   )r[   ri   r   c             C   sR   | dkrdt |  dS | dkr0dt |  dS | dkr<dS d	t |   d
S dS )z6Generate a plain English recommendation for EV tariff.rB   u   This could save you £z0/year. Great for EV owners who charge overnight.r   u   Small saving of £z>/year. Consider if you can shift more usage to off-peak hours.2   zaSimilar cost to your current tariff. Only worth switching if you can increase overnight charging.u   Would cost £zC/year more. Not recommended unless you can charge mostly overnight.Ni)rD   )r[   ri   r"   r"   r#   rs     s    rs   c              C   s   t j sdddS ytt d} tj| }W dQ R X |jd}|rtj|jdd}tj	|j
| }d	|t|j d
 d|ttdk t|jdg dS W n, tk
r } zdd| dS d}~X nX dS )zi
    Check how fresh the cached data is.

    Returns:
        Dictionary with freshness information
    Fz8No cached data. Run: python british_gas_scraper.py --all)rX   rY   r   Nr   r   z+00:00Ti  r   )r   r'   )rX   r   Z	age_hoursZis_freshZregions_countzError reading cache: )r   r   r   r   r   r   r   r   r   r   r   rD   total_secondsr   r   r9   r   )r   r   r   r    r!   er"   r"   r#   get_data_freshness  s$    
rx   __main__zBritish Gas Tariff API=ru   z
Data freshness: z
Available tariffs: z  - r6   u   : £rZ   zN/Az/yeari  )r<   r=   z/
Best tariff for 3000 kWh elec + 12000 kWh gas:z  rQ   i  )rW   r<   r=   rX   u&   
Compared to £1800/year current cost:z  Best: ra   u     Potential saving: £rb   )NN)r   )NrK   rL   N)NrK   rL   )NN)r   rh   )NrK   rL   rh   ))__doc__r   pathlibr   Ztypingr   r   r   r   r   Z
dno_lookupr	   r
   ImportError__file__parentr   r   dictr$   strr3   r:   rS   rJ   rV   re   rg   rq   rt   rs   rx   __name__print	freshnessr)   r9   rO   r   rT   Z
comparisonr"   r"   r"   r#   <module>   sp   ;9    
/  
26 
>   9%

(