
    1-iH                     6   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	 	 ddl
mZmZ n# e$ r ddl
mZmZ Y nw xY w ee          j        dz  d	z  Zd
Zdee         fdZd<dededee         fdZdedefdZ	 d=dedededefdZ	 	 	 	 d>dededededee         f
dZ	 	 	 d?dededededef
dZd<dededee         fdZ	 	 d@dededededef
dZ	 	 	 	 dAdedededededefd Zd!ededefd"Zdefd#Ze d$k    r e!d%            e!d&            e            Z" e!d'e"             e            Z# e!d( e$e#                      e#D ].Z% e!d)e%d*          d+e%&                    d,d-           d.           / ed/d0          Z'e'r) e!d1            e!d2e'd*          d+e'd3          d.            ed4d/d5          Z(e(&                    d6          r> e!d7            e!d8e(d9         d*                      e!d:e(d;          d.           dS dS dS )Ba  
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                     t                                           sdS 	 t          t           d          5 } t          j        |           }ddd           n# 1 swxY w Y   |                    d          }|r_t          j        |                    dd                    }t          j	        |j
                  |z
  }|t          t                    k    rdS |S # t          $ r Y dS w xY w)z
    Load cached British Gas tariff data.

    Returns:
        Dictionary with tariff data, or None if not available/stale
    Nr
scraped_atZ+00:00hours)TARIFF_FILEexistsopenjsonloadgetr   fromisoformatreplacenowtzinfor   CACHE_MAX_AGE_HOURS	Exception)fdatar   scraped_timeages        9/home/mac944/apps/billy-energy/scraper/british_gas_api.pyget_cached_datar'   &   s&     t+s## 	 q9Q<<D	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  XXl++
 	#1*2D2DS(2S2STTL,|233lBCY%899999t   tts;   C AC AC AA7C C 
C$#C$postcoderegionc                 v   t                      }|sg S |                    dg           }| s=|s;|D ]6}|                    d          r|                    d          r
|d         c S 7g S | rt          |           }|                    d          }|rgd |D             }t          | |          }|D ]H}|                    d          r1|                    d          |k    r|                    dg           c S I|r|D ]}|                    d          s|                    dd                                          }	|                                |	v s|	|                                v r|                    dg           c S |D ]6}|                    d          r|                    d          r
|d         c S 7g 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                 b    g | ],}|                     d           |                     d          -S r,   r)   r   .0r   s     r&   
<listcomp>z+get_british_gas_tariffs.<locals>.<listcomp>c   3     V V VQQUU9EUEU Vx V V V     r'   r   r
   r   lower)
r(   r)   r#   r+   r   dno_infotarget_regionavailable_regionsmatched_regionr_regions
             r&   get_british_gas_tariffsr>   A   s    D 	hhy"%%G  F  	$ 	$AuuY $AEE)$4$4 $|###	  0'11 X.. 	0 V V' V V V1(<MNNN  0 055## 0h>(I(I55B/////  , 	, 	,A55## uuXr**0022H||~~))X-G-GuuY+++++ .H     55 	 i 0 0 	 Y<Ir5   c                    t          |           }|                    d          }t                      }g }d}d}|r|                    dg           }|D ]]}|                    d          rF|                    d          |k    r-|                    dg           }|                    d          } n^|s^|D ][}|                    d          rD|                    d          r/|                    dg           }|                    d          }d} n\| |                    d          |                    d	          |                    d          |                    d
          d|t          |          |||rd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-   Tdno_codedno_namepostcode_prefix)codenamer)   rB   z+Using national tariffs from fallback region)r(   dnor-   tariff_countusing_fallbackactual_regionnote)r
   r   r'   len)	r(   r9   r:   r#   r-   rG   rH   r+   r   s	            r&   get_tariffs_with_region_inforK   |   s    $H--HLL**M DGNM ((9b))  	 	AuuY AEE(OO}$D$D%%	2.. !h  	  55## i(8(8 eeIr22G$%EE(OOM%)NE LL,,LL,,ll8,,'||,=>>	
 
 G(&AOY==UY  r5   tariffannual_electricity_kwhannual_gas_kwhc                    |                      di           }|                      di           }|                     dd          pd}|                     dd          pd}||z  dz  d|z  dz  z   }d}|dk    rA|                     dd          pd}	|                     dd          pd}
||	z  dz  d|
z  dz  z   }t          ||z   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   m     r   round)rL   rM   rN   elecrQ   elec_unit_rateelec_standing	elec_costgas_costgas_unit_rategas_standings              r&   calculate_annual_costr`      s      ::mR((D
**UB

C XX/338qNHH4a88=AM'.83>3CVY\C\]I H 1155:ww6::?a"]2S8S<=ORU=UVX%q)))r5   T  .  tariff_typec                     t          |           }|sdS rfd|D             }|sdS d}t          d          }|D ]'}t          |||          }||k     r|}i ||||dd}(|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                     g | ]B}|                     d d                                                                          k    @|CS )typer6   )r   r8   )r2   trc   s     r&   r3   z$find_best_tariff.<locals>.<listcomp>   sI    ZZZvr):):)@)@)B)BkFWFWFYFY)Y)Y1)Y)Y)Yr5   inf)electricity_kwhgas_kwh)calculated_annual_costusage)r>   floatr`   )	r(   rM   rN   rc   r-   best	best_costrL   costs	      `     r&   find_best_tariffrr      s    $ &x888G t  [ZZZZgZZZ t DeI  $V-C^TT)I*.'=-   D Kr5   current_annual_costc                    t          |          }|sdddS g }|D ]}t          |||          }| |z
  }|                    |                    d          |                    d          |t	          |d          |dk    |                    d	          |                    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
    re   FzABritish Gas tariff data not available. Run the scraper to update.	availablemessagerD   rg   rV   r   rP   rQ   )rD   rg   annual_costsaving
is_cheaperrP   rQ   c                     | d         S )Nrx    )xs    r&   <lambda>z!compare_tariffs.<locals>.<lambda>1  s    1]#3 r5   )keyNTrz   ry   )rv   current_costbest_tariffall_tariffspotential_saving)r>   r`   appendr   rX   sort)
rs   r(   rM   rN   r-   comparisonsrL   rq   ry   ro   s
             r&   compare_tariffsr     sC   $ &x888G 
Z
 
 	

 K  $V-C^TT$t+JJv&&JJv&&FA&& 1*!::m44::e$$
 
 	 	 	 	 33444(2;q>>dD +".2PtL7IPDNNq  r5   c                    t                      }|sdS |                    dg           }| rt          |           }|                    d          }|rfd |D             }t          | |          }|D ]G}|                    d          r0|                    d          |k    r|                    d          c S H|r|D ]}|                    d          s|                    dd                                          }	|                                |	v s|	|                                v r|                    d          c S |D ]6}|                    d          r|                    d          r
|d         c S 7d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                 b    g | ],}|                     d           |                     d          -S r/   r0   r1   s     r&   r3   z!get_ev_tariff.<locals>.<listcomp>Y  r4   r5   r,   	ev_tariffr6   r7   )
r(   r)   r#   r+   r9   r:   r;   r<   r   r=   s
             r&   get_ev_tariffr   >  s    D thhy"%%G  
.'11 X.. 	. V V' V V V1(<MNNN . .55## .h>(I(I55-----  * 	* 	*A55## uuXr**0022H||~~))X-G-Guu[))))) .H  " "55 	"k 2 2 	"[>!!!4r5         ?r   off_peak_percentagec           
         |                      di           }|                      di           }||z  }|d|z
  z  }|                     dd          pd}|                     dd          pd}	|                     dd          pd}
||z  dz  }||	z  dz  }d	|
z  dz  }||z   |z   }d}|dk    rA|                     d
d          pd}|                     dd          pd}||z  dz  d	|z  dz  z   }||z   }t          |d          t          |d          t          |d          t          |d          t          |d          t          |d          t          |d          d|t          |d          d|t          ||z  dz  ||	z  dz  z
  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
    rP   rQ   r	   peak_unit_rate_pencer   off_peak_unit_rate_pencerS   rT   rU   rR   rV   )peak_kwh	peak_costoff_peak_kwhoff_peak_coststanding_charge_costtotal)kwhr   )rx   rP   rQ   r   savings_from_off_peakrW   )r   rM   rN   r   rY   rQ   r   r   	peak_rateoff_peak_rater[   r   r   elec_standing_costtotal_elec_costr]   r^   r_   
total_costs                      r&   calculate_ev_annual_costr   q  s   & ==++D
--r
"
"C *,??L%-@)@AH /338qIHH7;;@qMHH4a88=AM 9$s*I =036M},s2-/2DDO H 1155:ww6::?a"]2S8S<=ORU=UV 8+J Z++h**y!,,!,22"=!44$)*<a$@$@?A..
 
 "8Q''
 
  3!&9(<s(BxR_G_beGe'fhi!j!j  r5   c                    t          |          }|sdddS t          ||||          }|d         }| |z
  }d| |                    dd          d	|t          |d
          |dk    |                    di                               d          |                    di                               d          |                    di                               d          |                    di                               d          |                    di                               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
    re   FzDBritish Gas EV tariff data not available. Run the scraper to update.ru   rx   TrD   zEV Power TariffEVrV   r   rP   r   r   rS   rQ   rR   )electricity_peak_penceelectricity_off_peak_penceelectricity_standing_pencegas_unit_pencegas_standing_pence)rD   rg   rx   ry   rz   ratescost_breakdown)rv   r   r   r   recommendation)r   r   r   rX   _get_ev_recommendation)	rs   r(   rM   rN   r   r   r   ev_costry   s	            r&   compare_ev_tariffr     s   , x000I 
]
 
 	

 .	 N ]+G 7*F +MM&*;<<"FA&& 1**3--r*J*J*N*NOe*f*f.7mmM2.N.N.R.RSm.n.n.7mmM2.N.N.R.RSj.k.k"+--r":":">">?P"Q"Q&/mmE2&>&>&B&BCZ&[&[  -
 
 '-qjjFFa09LMM'  r5   ry   c                     | dk    rdt          |            dS | dk    rdt          |            dS | dk    rdS d	t          |             d
S )z6Generate a plain English recommendation for EV tariff.rT   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.izaSimilar 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.)rX   )ry   r   s     r&   r   r     sj    ||gfgggg	!qE&MMqqqq	#rrrufW~~rrrrr5   c            
         t                                           sdddS 	 t          t           d          5 } t          j        |           }ddd           n# 1 swxY w Y   |                    d          }|rt          j        |                    dd                    }t          j	        |j
                  |z
  }d	|t          |                                d
z  d          |t          t                    k     t          |                    dg                     dS dS # t           $ r}dd| dcY d}~S d}~ww xY w)zi
    Check how fresh the cached data is.

    Returns:
        Dictionary with freshness information
    Fz8No cached data. Run: python british_gas_scraper.py --allru   r   Nr   r   r   Ti  r	   r   r+   )rv   r   	age_hoursis_freshregions_countzError reading cache: )r   r   r   r   r   r   r   r   r   r   r   rX   total_secondsr   r    rJ   r!   )r"   r#   r   r$   r%   es         r&   get_data_freshnessr     s     
Q
 
 	


+s## 	 q9Q<<D	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  XXl++
 
	#1*2D2DS(2S2STTL,|233lBC "("3#4#4#6#6#=qAA)2E"F"F"FF!$TXXi%<%<!=!=  	
	 
	  
 
 
2q22
 
 	
 	
 	
 	
 	
 	

sA   D! A
D! AD! AC D! !
D=+D82D=8D=__main__zBritish Gas Tariff APIz2==================================================z
Data freshness: z
Available tariffs: z  - rD   u   : £rx   zN/Az/yeari  )rM   rN   z/
Best tariff for 3000 kWh elec + 12000 kWh gas:z  rl   i  )rs   rM   rN   rv   u&   
Compared to £1800/year current cost:z  Best: r   u     Potential saving: £r   )NN)r   )Nra   rb   N)Nra   rb   )r   r   )Nra   rb   r   ))__doc__r   pathlibr   typingr   r   r   r   r   
dno_lookupr
   r   ImportError__file__parentr   r    dictr'   strr>   rK   rn   r`   rr   r   r   r   r   r   r   __name__print	freshnessr-   rJ   rh   r   ro   
comparisonr|   r5   r&   <module>r      sM   (        ' ' ' ' ' ' ' ' ' ' ( ( ( ( ( ( ( (FFFFFFFFFF F F FEEEEEEEEEEF
 d8nn#h.1KK $    68 8c 8# 8d 8 8 8 8v33 34 3 3 3 3r  *  * *! *  * 	 *  *  *  *H $(!	/ //!/ / 	/
 d^/ / / /h $(!	4 444 "4 	4
 
4 4 4 4n0 0C 0 0x~ 0 0 0 0l !$	> >>!> > 	>
 
> > > >F $(!!$< <<< "< 	<
 < 
< < < <~	s5 	su 	s 	s 	s 	s 	s!
D !
 !
 !
 !
J z	E
"###	E(OOO #"$$I	E
*y
*
*+++ &%''G	E
0##g,,
0
0111 H HFQvYFFAEE-$?$?FFFGGGG 4NNND LABBBJ4<JJT*B%CJJJKKK ! #  J
 ~~k"" N8999<M26:<<===Lz2D'ELLLMMMMM= 6N Ns   ) 99