async def test_invalid_json_retry_successful(aresponses, dump_response): """Test a successful retry after getting a failed JSON error. Note that we have to bust the cache before executing this test since all tests use the same event loop. """ cache = SimpleMemoryCache() await cache.delete(DEFAULT_CACHE_KEY) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text="This isn't JSON", status=200), ) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text=json.dumps(dump_response), status=200), ) async with aiohttp.ClientSession() as session: client = Client(session=session) data = await client.dump() assert len(data) == 6
async def test_invalid_json_retry_failure(aresponses): """Test a failed retry after getting a failed JSON error. Note that we have to bust the cache before executing this test since all tests use the same event loop. """ cache = SimpleMemoryCache() await cache.delete(DEFAULT_CACHE_KEY) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text="This isn't JSON", status=200), ) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text="This isn't JSON", status=200), ) with pytest.raises(RequestError): async with aiohttp.ClientSession() as session: client = Client(session=session) await client.dump()
async def test_caching(aresponses, dump_response): """Test that the caching mechanism works properly. Note that we have to bust the cache before executing this test since all tests use the same event loop. """ aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text=json.dumps(dump_response), status=200), ) cache = SimpleMemoryCache() await cache.delete(DEFAULT_CACHE_KEY) async with aiohttp.ClientSession() as session: client = Client(session=session) cache_exists = await cache.exists(DEFAULT_CACHE_KEY) assert not cache_exists await client.within_radius(TEST_LATITUDE, TEST_LONGITUDE, TEST_RADIUS_METRIC) cache_exists = await cache.exists(DEFAULT_CACHE_KEY) assert cache_exists
async def test_within_metric(): """Test retrieving the nearest strikes within a kilometer radius.""" async with aiohttp.ClientSession() as session: client = Client(session=session) data = await client.within_radius(TEST_LATITUDE, TEST_LONGITUDE, TEST_RADIUS_METRIC) assert len(data) == 2 first_strike = next(iter(data.values())) assert first_strike["distance"] == 30.971194229766567
async def test_invalid_unit(): """Test raising a proper exception when an incorrect radius unit is used.""" async with aiohttp.ClientSession() as session: client = Client(session=session) with pytest.raises(ValueError): await client.within_radius(TEST_LATITUDE, TEST_LONGITUDE, TEST_RADIUS_METRIC, unit="random_unit")
async def async_setup_entry(hass, config_entry): """Set up the WWLLN as config entry.""" websession = aiohttp_client.async_get_clientsession(hass) hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = Client(websession) hass.async_create_task( hass.config_entries.async_forward_entry_setup(config_entry, 'geo_location')) return True
async def test_bad_request(aresponses): """Test that the proper exception is raised during a recurring bad request.""" aresponses.add("wwlln.net", "/bad_endpoint", "get", aresponses.Response(text="", status=404)) aresponses.add("wwlln.net", "/bad_endpoint", "get", aresponses.Response(text="", status=404)) with pytest.raises(RequestError): async with aiohttp.ClientSession() as session: client = Client(session=session) await client.request("get", "http://wwlln.net/bad_endpoint")
async def test_invalid_cache_duration(caplog): """Test the cache duration floor.""" async with aiohttp.ClientSession() as session: _ = Client(session=session, cache_seconds=1) logs = [ l for l in [ "Setting cache timeout to lowest allowed" in e.message for e in caplog.records ] if l is not False ] assert len(logs) == 1
async def test_within_imperial(): """Test retrieving the nearest strikes within a mile radius.""" async with aiohttp.ClientSession() as session: client = Client(session=session) data = await client.within_radius(TEST_LATITUDE, TEST_LONGITUDE, TEST_RADIUS_IMPERIAL, unit="imperial") assert len(data) == 2 first_strike = next(iter(data.values())) assert first_strike["distance"] == 19.24482243239678
async def test_dump(aresponses, dump_response): """Test that dumping the WWLLN data works.""" aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text=json.dumps(dump_response), status=200), ) async with aiohttp.ClientSession() as session: client = Client(session=session) data = await client.dump() assert len(data) == 6
async def test_no_explicit_session(aresponses, dump_response): """Test an API call with no explicitly-provided aiohttp ClientSession. Note that we have to bust the cache before executing this test since all tests use the same event loop. """ cache = SimpleMemoryCache() await cache.delete(DEFAULT_CACHE_KEY) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text=json.dumps(dump_response), status=200), ) client = Client() data = await client.dump() assert len(data) == 6
async def main() -> None: """Create the aiohttp session and run the example.""" async with ClientSession() as session: try: # Create a client: client = Client(session=session) # Get all strike data: print(await client.dump()) # Get strike data within a 50km radius around a set of coordinates _and_ # within the last hour: print( await client.within_radius( TARGET_LATITUDE, TARGET_LONGITUDE, TARGET_RADIUS_KM, window=timedelta(hours=1), ) ) except WWLLNError as err: print(err)
async def test_within_window(aresponses, dump_response): """Test retrieving the nearest strikes within a 10-minute window.""" # Bust the cache since we're parametrizing the input data: cache = SimpleMemoryCache() await cache.delete(DEFAULT_CACHE_KEY) aresponses.add( "wwlln.net", "/new/map/data/current.json", "get", aresponses.Response(text=json.dumps(dump_response), status=200), ) async with aiohttp.ClientSession() as session: client = Client(session=session) data = await client.within_radius( TEST_LATITUDE, TEST_LONGITUDE, TEST_RADIUS_METRIC, window=timedelta(minutes=10), ) assert len(data) == 1
async def async_setup_entry(hass, config_entry): """Set up the WWLLN as config entry.""" if not config_entry.unique_id: hass.config_entries.async_update_entry( config_entry, unique_id=( f"{config_entry.data[CONF_LATITUDE]}, " f"{config_entry.data[CONF_LONGITUDE]}" ), ) hass.data[DOMAIN] = {} hass.data[DOMAIN][DATA_CLIENT] = {} websession = aiohttp_client.async_get_clientsession(hass) hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = Client(websession) hass.async_create_task( hass.config_entries.async_forward_entry_setup(config_entry, "geo_location") ) return True
async def main() -> None: """Create the aiohttp session and run the example.""" async with ClientSession() as websession: try: # Create a client: client = Client(websession) # Get all strike data: # print(await client.dump()) # Get strike data within a specified radius around a set of coordinates _and_ # within the target time: strike_data = await client.within_radius( TARGET_LATITUDE, TARGET_LONGITUDE, TARGET_RADIUS_MILES, unit="imperial", window=timedelta(minutes=TARGET_TIME_MINUTES), ) if len(strike_data) == 0: print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),end = ' ') print("No data for this location, radius and time window.") if (len(strike_data) > 0): print("********************************") dup = 0 strike_data = str(strike_data) strike_data = strike_data.replace("\'", "\"") decoded = json.loads(strike_data) if myCSV == 1: export_data = open('./wwlln_lightning.csv', 'w') # create the csv writer object csvwriter = csv.writer(export_data) count = 0 dup = 0 nodup = 0 # pdb.set_trace() if mySQL == 1: conn = sqlite3.connect('./lightning-strike.db') cur = conn.cursor() cur.execute('select max(runevent) from runevents') row = (cur.fetchone()) cur.close if row[0] is None: eventnumber = 1 else: eventnumber = int(row[0]) + 1 print("Recording event number: ",end='') print (eventnumber) cur.close curtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(curtime) for strike in decoded: if count == 0: header = (["EventID", "Datetime", "Latitude", "Longitude", "Distance"]) csvwriter.writerow(header) count += 1 myEventID = strike # pdb.set_trace() unixtime = int(decoded[strike]["unixTime"]) myDate = datetime.datetime.fromtimestamp(unixtime) myDate = myDate.strftime("%Y-%m-%d %H:%M:%S") myLat = decoded[strike]["lat"] myLong = decoded[strike]["long"] myDist = round(decoded[strike]["distance"],2) csvwriter.writerow( [myEventID, myDate, myLat,myLong,myDist ] ) # pdb.set_trace() if mySQL == 1: myData = [(eventnumber,myEventID,myDate,myLat,myLong,myDist)] cur = conn.cursor() cur.execute('select count(*) from events where eventid = (?)', [myEventID]) rowcount = cur.fetchone()[0] if rowcount > 0: dup = dup + 1 else: nodup = nodup + 1 cur.close() cur = conn.cursor() cur.executemany('INSERT OR IGNORE INTO events VALUES (?,?,?,?,?,?)', myData) # conn.commit() export_data.close() for key in decoded: if debug == 1: print(key) print(decoded[key]["distance"]) b[key]= decoded[key]["distance"] b2[key]= decoded[key]["unixTime"] c = sorted(b.items(), key=lambda x: x[1]) c2 = sorted(b2.items(), key=lambda x: x[1],reverse=True) key_closest = c[0][0] key_recent = c2[0][0] if debug == 1: print("Sorted by distance\n") for x in range(len(c)): print("key = ",c[x][0]," ","distance = ",decoded[c[x][0]]["distance"]) print(decoded[c[x][0]]) print("\n") print("\n") print("Radius (miles)= ",TARGET_RADIUS_MILES) print("Window (minutes)= ", TARGET_TIME_MINUTES) print("Number of records= ",end='') print(len(decoded)) if mySQL == 1: print ("Inserted " + str(nodup) + " rows, ignored " + str(dup) + " rows") print("\n") print("Closest strike key= ",key_closest) x = key_closest print("key = ",x," ","distance = ",round(decoded[x]["distance"],2)) print(decoded[x]) print('{}-{:>02}-{:>02} {:>02}:{:>02}:{:>02}'.format(*gmtime(decoded[x]["unixTime"]))) diff = datetime.datetime.utcnow() - datetime.datetime.utcfromtimestamp(decoded[x]["unixTime"]) print("h:m:s ago = ",diff) minutes = round(diff.seconds/60,1) print("minutes ago= ",minutes) print("\n") print("most recent strike key= ",key_recent) x = key_recent print("key = ",x," ","distance = ",round(decoded[x]["distance"],2)) print(decoded[x]) print('{}-{:>02}-{:>02} {:>02}:{:>02}:{:>02}'.format(*gmtime(decoded[x]["unixTime"]))) diff = datetime.datetime.utcnow() - datetime.datetime.utcfromtimestamp(decoded[x]["unixTime"]) print("h:m:s ago = ",diff) minutes = round(diff.seconds/60,1) print("minutes ago= ",minutes) print("\n") if mySQL == 1: cur = conn.cursor() cur.executemany('INSERT INTO runevents VALUES (?,?,?,?,?,?,?)',\ [(eventnumber,curtime, TARGET_LATITUDE, TARGET_LONGITUDE, TARGET_RADIUS_MILES, nodup, dup)]) cur.close # this commit should be for runevens and events as well. # an atomic unit so to speak. conn.commit() conn.close() except WWLLNError as err: print(err)