Author Topic: Get Weather with Online API!  (Read 4829 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Get Weather with Online API!
« on: July 20, 2020, 11:07:57 pm »
As @Dav suggested, here is a demo showing off how to get the weather forecast for a supplied location. You can put either city or zip. Go to weatherstack.com and get your API key! This demo is obviously very limited but if you comment out the "KILL" you can see the file and from there you can figure out what you want to return from the JSON response.
 
weatherapi.png


Code: QB64: [Select]
  1.  
  2. PRINT GetWeather("47172", "forecast", "f")
  3.  
  4. FUNCTION GetWeather$ (location AS STRING, timing AS STRING, units AS STRING) 'timing can be either current or forecast for this demo
  5.     DIM URL AS STRING
  6.     DIM URLFile AS STRING
  7.     DIM WeatherRequest AS STRING
  8.     DIM a%
  9.     DIM Request AS STRING
  10.     URLFile = "weatherapirequest"
  11.     URL = "http://api.weatherstack.com/" + timing + "?access_key=YOURAPIKEYHERE&query=" + FormatAsHTTP(location) + "&units=" + units
  12.     a% = API_Request(URL, URLFile)
  13.     DIM U AS INTEGER
  14.     U = FREEFILE
  15.     OPEN URLFile FOR BINARY AS #U
  16.     IF LOF(U) <> 0 THEN
  17.         Request = SPACE$(LOF(U))
  18.         GET #U, , Request
  19.     ELSE
  20.         CLOSE #U
  21.         KILL URLFile
  22.         GetWeather = ""
  23.         EXIT FUNCTION
  24.     END IF
  25.     CLOSE #U
  26.     KILL URLFile
  27.     IF timing = "forecast" THEN
  28.         WeatherRequest = "Forecast for " + location + ": " + CHR$(10)
  29.         WeatherRequest = WeatherRequest + "Temperature: " + _TRIM$(STR$(VAL(MID$(Request, INSTR(Request, "temperature") + 13, 3)))) + CHR$(10) + "Wind Speed: " + _TRIM$(STR$(VAL(MID$(Request, INSTR(Request, "wind_speed") + 12, 3))))
  30.         GetWeather = WeatherRequest
  31.     ELSE
  32.     END IF
  33.  
  34. FUNCTION FormatAsHTTP$ (Request AS STRING)
  35.     start% = 1
  36.     DO
  37.         position% = INSTR(start%, Request, " ")
  38.         IF position% THEN
  39.             MID$(Request, position%, 1) = "+"
  40.             start% = position% + 1
  41.         END IF
  42.     LOOP UNTIL position% = 0
  43.     FormatAsHTTP = Request
  44.  
  45.     FUNCTION URLDownloadToFileA (BYVAL pCaller AS LONG, szURL AS STRING, szFileName AS STRING, BYVAL dwReserved AS LONG, BYVAL lpfnCB AS LONG)
  46.  
  47. FUNCTION API_Request (URL AS STRING, File AS STRING)
  48.     API_Request = URLDownloadToFileA(0, URL + CHR$(0), File + CHR$(0), 0, 0)
« Last Edit: July 20, 2020, 11:11:08 pm by SpriggsySpriggs »
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #1 on: July 21, 2020, 12:56:42 pm »
I'll look into what @IronMan made in this post https://www.qb64.org/forum/index.php?topic=2343.msg115710#msg115710 and see about making a version which automatically grabs current location (based on public IP) then grabs the appropriate NOAA file for the correct zone, provided I can determine which zone is what using NOAA.
Shuwatch!

Offline IronMan

  • Newbie
  • Posts: 38
    • View Profile
Re: Get Weather with Online API!
« Reply #2 on: July 21, 2020, 02:13:38 pm »
Don't know if this will help you, but here is a list of zones I compiled for all the locations.
* zones.lst (Filesize: 103.81 KB, Downloads: 144)

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #3 on: July 21, 2020, 02:36:20 pm »
@IronMan Absolutely fantastic. This will actually help me a lot.
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #4 on: July 21, 2020, 03:10:01 pm »
Well I'm down to the final stretch. I'm going to be able to finish this API today using ipify to get the public IP, using geo.ipify to get the zip code based on public IP, using smartystreets to get the county and state from the zip code returned from geo.ipify, then the correct text file from NOAA based on the two character state abbreviation returned form smartystreets and the county-zone correlation from @IronMan 's lst file. Piece of cake.
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #5 on: July 21, 2020, 05:58:02 pm »
@IronMan @Dav Finally, here is a version of the weather API that will grab your location automatically then grab the appropriate NOAA weather statement file using IronMan's lst file cross referencing the County and State with the Zone needed and then displays it in the window. Enjoy!
P.S. I made sure I removed those annoying periods at the beginning of the new lines since I know IronMan doesn't like them :)
EDIT: Realized I was getting rid of some necessary line feeds with my Remove function. I've put in the String.Replace function so when I remove the period I put the line feed back in so now it displays better.

 
weatherapi.png


Code: QB64: [Select]
  1.  
  2. PRINT GetWeather
  3.  
  4. FUNCTION GetWeather$
  5.     DIM URL AS STRING
  6.     DIM URLFile AS STRING
  7.     DIM weather AS STRING
  8.     DIM county AS STRING
  9.     DIM a%
  10.     URLFile = "weatherrequest"
  11.     DIM state AS STRING
  12.     state = LCASE$(GetStateFromZipCode)
  13.     URL = "https://tgftp.nws.noaa.gov/data/forecasts/zone/" + state + "/" + CrossRefZoneState(UCASE$(state), GetCountyFromZipCode) + ".txt"
  14.     a% = API_request(URL, URLFile)
  15.     DIM U AS INTEGER
  16.     U = FREEFILE
  17.     OPEN URLFile FOR BINARY AS #U
  18.     IF LOF(U) <> 0 THEN
  19.         weather = SPACE$(LOF(U))
  20.         GET #U, , weather
  21.     ELSE
  22.         CLOSE #U
  23.         KILL URLFile
  24.         GetWeather = ""
  25.         EXIT FUNCTION
  26.     END IF
  27.     CLOSE #U
  28.     KILL URLFile
  29.     weather = String.Replace(weather, CHR$(10) + ".", CHR$(10))
  30.     weather = String.Remove(weather, "$$")
  31.     GetWeather = weather
  32.  
  33. FUNCTION CrossRefZoneState$ (state AS STRING, county AS STRING)
  34.     DIM Z AS INTEGER
  35.     Z = FREEFILE
  36.     DIM zone AS STRING
  37.     DIM zones AS STRING
  38.     IF _FILEEXISTS("zones.lst") THEN
  39.         OPEN "zones.lst" FOR BINARY AS #Z
  40.         zones = SPACE$(LOF(Z))
  41.         GET #Z, , zones
  42.         zone = MID$(zones, INSTR(zones, state + "Z"))
  43.         zone = MID$(zone, INSTR(zone, county) - 7, 6)
  44.         CrossRefZoneState = LCASE$(zone)
  45.     ELSE
  46.         CrossRefZoneState = ""
  47.         EXIT FUNCTION
  48.     END IF
  49.  
  50. FUNCTION GetCountyFromZipCode$
  51.     DIM URL AS STRING
  52.     DIM URLFile AS STRING
  53.     DIM county AS STRING
  54.     DIM a%
  55.     URLFile = "county"
  56.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  57.     a% = API_request(URL, URLFile)
  58.     DIM U AS INTEGER
  59.     U = FREEFILE
  60.     OPEN URLFile FOR BINARY AS #U
  61.     IF LOF(U) <> 0 THEN
  62.         county = SPACE$(LOF(U))
  63.         GET #U, , county
  64.     ELSE
  65.         CLOSE #U
  66.         KILL URLFile
  67.         GetCountyFromZipCode = ""
  68.         EXIT FUNCTION
  69.     END IF
  70.     CLOSE #U
  71.     KILL URLFile
  72.     county = MID$(county, INSTR(county, "county_name") + 14)
  73.     county = LEFT$(county, INSTR(county, CHR$(34)) - 1)
  74.     GetCountyFromZipCode = county
  75.  
  76. FUNCTION GetStateFromZipCode$
  77.     DIM URL AS STRING
  78.     DIM URLFile AS STRING
  79.     DIM state AS STRING
  80.     DIM a%
  81.     URLFile = "statebyzip"
  82.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  83.     a% = API_request(URL, URLFile)
  84.     DIM U AS INTEGER
  85.     U = FREEFILE
  86.     OPEN URLFile FOR BINARY AS #U
  87.     IF LOF(U) <> 0 THEN
  88.         state = SPACE$(LOF(U))
  89.         GET #U, , state
  90.     ELSE
  91.         CLOSE #U
  92.         KILL URLFile
  93.         GetStateFromZipCode = ""
  94.         EXIT FUNCTION
  95.     END IF
  96.     CLOSE #U
  97.     KILL URLFile
  98.     state = MID$(state, INSTR(state, "state_abbreviation") + 21)
  99.     state = LEFT$(state, INSTR(state, CHR$(34)) - 1)
  100.     GetStateFromZipCode = state
  101.  
  102. FUNCTION GetLocationVIAip$
  103.     DIM URL AS STRING
  104.     DIM URLFile AS STRING
  105.     DIM location AS STRING
  106.     DIM a%
  107.     URLFile = "location"
  108.     URL = "https://geo.ipify.org/api/v1?apiKey=YOURAPIKEYHERE&ipAddress=" + GetPublicIP
  109.     a% = API_request(URL, URLFile)
  110.     DIM U AS INTEGER
  111.     U = FREEFILE
  112.     OPEN URLFile FOR BINARY AS #U
  113.     IF LOF(U) <> 0 THEN
  114.         location = SPACE$(LOF(U))
  115.         GET #U, , location
  116.     ELSE
  117.         CLOSE #U
  118.         KILL URLFile
  119.         GetLocationVIAip = ""
  120.         EXIT FUNCTION
  121.     END IF
  122.     CLOSE #U
  123.     KILL URLFile
  124.     location = MID$(location, INSTR(location, "postalCode") + 13)
  125.     location = LEFT$(location, INSTR(location, CHR$(34)) - 1)
  126.     GetLocationVIAip = location
  127.  
  128. FUNCTION GetPublicIP$
  129.     DIM URL AS STRING
  130.     DIM URLFile AS STRING
  131.     DIM publicip AS STRING
  132.     DIM a%
  133.     URLFile = "publicip"
  134.     URL = "https://api.ipify.org/"
  135.     a% = API_request(URL, URLFile)
  136.     DIM U AS INTEGER
  137.     U = FREEFILE
  138.     OPEN URLFile FOR BINARY AS #U
  139.     IF LOF(U) <> 0 THEN
  140.         LINE INPUT #U, publicip
  141.     ELSE
  142.         CLOSE #U
  143.         KILL URLFile
  144.         GetPublicIP = ""
  145.         EXIT FUNCTION
  146.     END IF
  147.     CLOSE #U
  148.     KILL URLFile
  149.     GetPublicIP = publicip
  150.  
  151. FUNCTION String.Remove$ (a AS STRING, b AS STRING)
  152.     DIM c AS STRING
  153.     c = ""
  154.     j = INSTR(a, b)
  155.     IF j > 0 THEN
  156.         r$ = LEFT$(a, j - 1) + c + String.Remove(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b)
  157.     ELSE
  158.         r$ = a
  159.     END IF
  160.     String.Remove = r$
  161.  
  162. FUNCTION String.Replace$ (a AS STRING, b AS STRING, c AS STRING)
  163.     j = INSTR(a, b)
  164.     IF j > 0 THEN
  165.         r$ = LEFT$(a, j - 1) + c + String.Replace(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b, c)
  166.     ELSE
  167.         r$ = a
  168.     END IF
  169.     String.Replace = r$
  170.  
  171.     FUNCTION URLDownloadToFileA (BYVAL pCaller AS LONG, szURL AS STRING, szFileName AS STRING, BYVAL dwReserved AS LONG, BYVAL lpfnCB AS LONG)
  172.  
  173. FUNCTION API_request (URL AS STRING, File AS STRING)
  174.     API_request = URLDownloadToFileA(0, URL + CHR$(0), File + CHR$(0), 0, 0)
* zones.lst (Filesize: 103.81 KB, Downloads: 155)
« Last Edit: July 21, 2020, 09:25:26 pm by SpriggsySpriggs »
Shuwatch!

Offline IronMan

  • Newbie
  • Posts: 38
    • View Profile
Re: Get Weather with Online API!
« Reply #6 on: July 21, 2020, 06:41:29 pm »
SpriggsySpriggs,


Job well done! It works great... :-))

your method of removing the extra $$ and .. is a lot more simple than the way I done it. I'm going to have to make a note of this for sure..

weather = STRING.Remove(weather, CHR$(10) + ".")
weather = STRING.Remove(weather, "$$")



My way:


OPEN "fetch1.txt" FOR INPUT AS #1
OPEN "fetch2.txt" FOR OUTPUT AS #2
WHILE NOT EOF(1)
    INPUT #1, LineTxt
    IF LEFT$(LineTxt, 1) = "." THEN
PRINT #2, " "PRINT #2, MID$(LineTxt, 2); " "
ELSE
PRINT #2, LineTxt 'write output to new file fetch2.txt
END IF
WEND
CLOSE #1
CLOSE #2

' Remove $$
OPEN "fetch3.txt" FOR INPUT AS #1
OPEN "forecast.txt" FOR OUTPUT AS #2
WHILE NOT EOF(1)
    INPUT #1, LineTxt2
    IF LineTxt2 = "$$" THEN
LineTxt2 = "  "
PRINT #2, "  "
ELSE
PRINT #2, LineTxt2 'write output to new file forecast.txt
END IF
WEND
CLOSE #1
CLOSE #2


Guess I just like taking the long way around, Hehehehe


Congratulations again on a great job.


Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #7 on: July 21, 2020, 06:44:25 pm »
@IronMan I couldn't have done it nearly as quick without your list of the Zones and how they reference the counties! I was scouring the web trying to find some kind of list like that somewhere because I had no clue what zone my county was without looking at some PDF of my state.
Shuwatch!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Get Weather with Online API!
« Reply #8 on: July 21, 2020, 06:49:05 pm »
Nice job, @SpriggsySpriggs ! You sure did that quickly. 

- Dav

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #9 on: July 21, 2020, 09:26:10 pm »
I'm starting to wonder how this would be using Dav's espeak library.....
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #10 on: July 21, 2020, 10:33:59 pm »
Ok, for a good laugh, run this and hear the most terrible AI voice speak out your local weather report! @Dav , eSpeak is a wonderful library! (Check the post below for a true weather report experience)

Code: QB64: [Select]
  1.  
  2. DIM Weather AS STRING
  3. Weather = GetWeather
  4. PRINT Weather
  5. Weather = MID$(Weather, INSTR(Weather, "OVERNIGHT"))
  6. eSpeak Weather
  7.  
  8. FUNCTION GetWeather$
  9.     DIM URL AS STRING
  10.     DIM URLFile AS STRING
  11.     DIM weather AS STRING
  12.     DIM county AS STRING
  13.     DIM a%
  14.     URLFile = "weatherrequest"
  15.     DIM state AS STRING
  16.     state = LCASE$(GetStateFromZipCode)
  17.     URL = "https://tgftp.nws.noaa.gov/data/forecasts/zone/" + state + "/" + CrossRefZoneState(UCASE$(state), GetCountyFromZipCode) + ".txt"
  18.     a% = API_request(URL, URLFile)
  19.     DIM U AS INTEGER
  20.     U = FREEFILE
  21.     OPEN URLFile FOR BINARY AS #U
  22.     IF LOF(U) <> 0 THEN
  23.         weather = SPACE$(LOF(U))
  24.         GET #U, , weather
  25.     ELSE
  26.         CLOSE #U
  27.         KILL URLFile
  28.         GetWeather = ""
  29.         EXIT FUNCTION
  30.     END IF
  31.     CLOSE #U
  32.     KILL URLFile
  33.     weather = String.Replace(weather, CHR$(10) + ".", CHR$(10))
  34.     weather = String.Remove(weather, "$$")
  35.     GetWeather = weather
  36.  
  37. FUNCTION CrossRefZoneState$ (state AS STRING, county AS STRING)
  38.     DIM Z AS INTEGER
  39.     Z = FREEFILE
  40.     DIM zone AS STRING
  41.     DIM zones AS STRING
  42.     IF _FILEEXISTS("zones.lst") THEN
  43.         OPEN "zones.lst" FOR BINARY AS #Z
  44.         zones = SPACE$(LOF(Z))
  45.         GET #Z, , zones
  46.         zone = MID$(zones, INSTR(zones, state + "Z"))
  47.         zone = MID$(zone, INSTR(zone, county) - 7, 6)
  48.         CrossRefZoneState = LCASE$(zone)
  49.     ELSE
  50.         CrossRefZoneState = ""
  51.         EXIT FUNCTION
  52.     END IF
  53.  
  54. FUNCTION GetCountyFromZipCode$
  55.     DIM URL AS STRING
  56.     DIM URLFile AS STRING
  57.     DIM county AS STRING
  58.     DIM a%
  59.     URLFile = "county"
  60.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  61.     a% = API_request(URL, URLFile)
  62.     DIM U AS INTEGER
  63.     U = FREEFILE
  64.     OPEN URLFile FOR BINARY AS #U
  65.     IF LOF(U) <> 0 THEN
  66.         county = SPACE$(LOF(U))
  67.         GET #U, , county
  68.     ELSE
  69.         CLOSE #U
  70.         KILL URLFile
  71.         GetCountyFromZipCode = ""
  72.         EXIT FUNCTION
  73.     END IF
  74.     CLOSE #U
  75.     KILL URLFile
  76.     county = MID$(county, INSTR(county, "county_name") + 14)
  77.     county = LEFT$(county, INSTR(county, CHR$(34)) - 1)
  78.     GetCountyFromZipCode = county
  79.  
  80. FUNCTION GetStateFromZipCode$
  81.     DIM URL AS STRING
  82.     DIM URLFile AS STRING
  83.     DIM state AS STRING
  84.     DIM a%
  85.     URLFile = "statebyzip"
  86.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  87.     a% = API_request(URL, URLFile)
  88.     DIM U AS INTEGER
  89.     U = FREEFILE
  90.     OPEN URLFile FOR BINARY AS #U
  91.     IF LOF(U) <> 0 THEN
  92.         state = SPACE$(LOF(U))
  93.         GET #U, , state
  94.     ELSE
  95.         CLOSE #U
  96.         KILL URLFile
  97.         GetStateFromZipCode = ""
  98.         EXIT FUNCTION
  99.     END IF
  100.     CLOSE #U
  101.     KILL URLFile
  102.     state = MID$(state, INSTR(state, "state_abbreviation") + 21)
  103.     state = LEFT$(state, INSTR(state, CHR$(34)) - 1)
  104.     GetStateFromZipCode = state
  105.  
  106. FUNCTION GetLocationVIAip$
  107.     DIM URL AS STRING
  108.     DIM URLFile AS STRING
  109.     DIM location AS STRING
  110.     DIM a%
  111.     URLFile = "location"
  112.     URL = "https://geo.ipify.org/api/v1?apiKey=YOURAPIKEYHERE&ipAddress=" + GetPublicIP
  113.     a% = API_request(URL, URLFile)
  114.     DIM U AS INTEGER
  115.     U = FREEFILE
  116.     OPEN URLFile FOR BINARY AS #U
  117.     IF LOF(U) <> 0 THEN
  118.         location = SPACE$(LOF(U))
  119.         GET #U, , location
  120.     ELSE
  121.         CLOSE #U
  122.         KILL URLFile
  123.         GetLocationVIAip = ""
  124.         EXIT FUNCTION
  125.     END IF
  126.     CLOSE #U
  127.     KILL URLFile
  128.     location = MID$(location, INSTR(location, "postalCode") + 13)
  129.     location = LEFT$(location, INSTR(location, CHR$(34)) - 1)
  130.     GetLocationVIAip = location
  131.  
  132. FUNCTION GetPublicIP$
  133.     DIM URL AS STRING
  134.     DIM URLFile AS STRING
  135.     DIM publicip AS STRING
  136.     DIM a%
  137.     URLFile = "publicip"
  138.     URL = "https://api.ipify.org/"
  139.     a% = API_request(URL, URLFile)
  140.     DIM U AS INTEGER
  141.     U = FREEFILE
  142.     OPEN URLFile FOR BINARY AS #U
  143.     IF LOF(U) <> 0 THEN
  144.         LINE INPUT #U, publicip
  145.     ELSE
  146.         CLOSE #U
  147.         KILL URLFile
  148.         GetPublicIP = ""
  149.         EXIT FUNCTION
  150.     END IF
  151.     CLOSE #U
  152.     KILL URLFile
  153.     GetPublicIP = publicip
  154.  
  155. FUNCTION String.Remove$ (a AS STRING, b AS STRING)
  156.     DIM c AS STRING
  157.     c = ""
  158.     j = INSTR(a, b)
  159.     IF j > 0 THEN
  160.         r$ = LEFT$(a, j - 1) + c + String.Remove(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b)
  161.     ELSE
  162.         r$ = a
  163.     END IF
  164.     String.Remove = r$
  165.  
  166. FUNCTION String.Replace$ (a AS STRING, b AS STRING, c AS STRING)
  167.     j = INSTR(a, b)
  168.     IF j > 0 THEN
  169.         r$ = LEFT$(a, j - 1) + c + String.Replace(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b, c)
  170.     ELSE
  171.         r$ = a
  172.     END IF
  173.     String.Replace = r$
  174.  
  175.     FUNCTION URLDownloadToFileA (BYVAL pCaller AS LONG, szURL AS STRING, szFileName AS STRING, BYVAL dwReserved AS LONG, BYVAL lpfnCB AS LONG)
  176.  
  177. FUNCTION API_request (URL AS STRING, File AS STRING)
  178.     API_request = URLDownloadToFileA(0, URL + CHR$(0), File + CHR$(0), 0, 0)
  179.  
  180.     FUNCTION WinExec (lpCmdLine AS STRING, BYVAL nCmdShow AS LONG)
  181.  
  182. SUB eSpeak (lines$)
  183.     Filename$ = "espeak.exe -v en " + CHR$(34) + lines$ + CHR$(34)
  184.     x = WinExec(Filename$ + CHR$(0), 0)
* espeak.exe (Filesize: 312 KB, Downloads: 199)
« Last Edit: July 21, 2020, 10:55:22 pm by SpriggsySpriggs »
Shuwatch!

Marked as best answer by SpriggsySpriggs on July 21, 2020, 06:50:29 pm

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Get Weather with Online API!
« Reply #11 on: July 21, 2020, 10:50:21 pm »
And with a more advanced Text To Speech library that sounds far more natural!:
Run my attached exe "weatherapi.exe" to hear how it sounds. It has my API keys inside it so please don't run it 250 times LOL
You may notice I had to change the spelling in the string that gets sent to the TTS. That's because it kept mispronouncing those specific words.

Code: QB64: [Select]
  1. 'OPTION _EXPLICIT
  2.  
  3. DIM Weather AS STRING
  4. Weather = GetWeather
  5. PRINT Weather
  6.  
  7. 'eSpeak Weather
  8.  
  9. TTS FormatForTTS(Weather)
  10.  
  11.  
  12. FUNCTION GetWeather$
  13.     DIM URL AS STRING
  14.     DIM URLFile AS STRING
  15.     DIM weather AS STRING
  16.     DIM county AS STRING
  17.     DIM a%
  18.     URLFile = "weatherrequest"
  19.     DIM state AS STRING
  20.     state = LCASE$(GetStateFromZipCode)
  21.     URL = "https://tgftp.nws.noaa.gov/data/forecasts/zone/" + state + "/" + CrossRefZoneState(UCASE$(state), GetCountyFromZipCode) + ".txt"
  22.     a% = API_request(URL, URLFile)
  23.     DIM U AS INTEGER
  24.     U = FREEFILE
  25.     OPEN URLFile FOR BINARY AS #U
  26.     IF LOF(U) <> 0 THEN
  27.         weather = SPACE$(LOF(U))
  28.         GET #U, , weather
  29.     ELSE
  30.         CLOSE #U
  31.         KILL URLFile
  32.         GetWeather = ""
  33.         EXIT FUNCTION
  34.     END IF
  35.     CLOSE #U
  36.     KILL URLFile
  37.     weather = String.Replace(weather, CHR$(10) + ".", CHR$(10))
  38.     weather = String.Remove(weather, "$$")
  39.     GetWeather = weather
  40.  
  41. FUNCTION CrossRefZoneState$ (state AS STRING, county AS STRING)
  42.     DIM Z AS INTEGER
  43.     Z = FREEFILE
  44.     DIM zone AS STRING
  45.     DIM zones AS STRING
  46.     IF _FILEEXISTS("zones.lst") THEN
  47.         OPEN "zones.lst" FOR BINARY AS #Z
  48.         zones = SPACE$(LOF(Z))
  49.         GET #Z, , zones
  50.         zone = MID$(zones, INSTR(zones, state + "Z"))
  51.         zone = MID$(zone, INSTR(zone, county) - 7, 6)
  52.         CrossRefZoneState = LCASE$(zone)
  53.     ELSE
  54.         CrossRefZoneState = ""
  55.         EXIT FUNCTION
  56.     END IF
  57.  
  58. FUNCTION GetCountyFromZipCode$
  59.     DIM URL AS STRING
  60.     DIM URLFile AS STRING
  61.     DIM county AS STRING
  62.     DIM a%
  63.     URLFile = "county"
  64.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  65.     a% = API_request(URL, URLFile)
  66.     DIM U AS INTEGER
  67.     U = FREEFILE
  68.     OPEN URLFile FOR BINARY AS #U
  69.     IF LOF(U) <> 0 THEN
  70.         county = SPACE$(LOF(U))
  71.         GET #U, , county
  72.     ELSE
  73.         CLOSE #U
  74.         KILL URLFile
  75.         GetCountyFromZipCode = ""
  76.         EXIT FUNCTION
  77.     END IF
  78.     CLOSE #U
  79.     KILL URLFile
  80.     county = MID$(county, INSTR(county, "county_name") + 14)
  81.     county = LEFT$(county, INSTR(county, CHR$(34)) - 1)
  82.     GetCountyFromZipCode = county
  83.  
  84. FUNCTION GetStateFromZipCode$
  85.     DIM URL AS STRING
  86.     DIM URLFile AS STRING
  87.     DIM state AS STRING
  88.     DIM a%
  89.     URLFile = "statebyzip"
  90.     URL = "https://us-zipcode.api.smartystreets.com/lookup?auth-id=YOURAUTHIDHERE&auth-token=YOURAUTHTOKENHERE&zipcode=" + GetLocationVIAip
  91.     a% = API_request(URL, URLFile)
  92.     DIM U AS INTEGER
  93.     U = FREEFILE
  94.     OPEN URLFile FOR BINARY AS #U
  95.     IF LOF(U) <> 0 THEN
  96.         state = SPACE$(LOF(U))
  97.         GET #U, , state
  98.     ELSE
  99.         CLOSE #U
  100.         KILL URLFile
  101.         GetStateFromZipCode = ""
  102.         EXIT FUNCTION
  103.     END IF
  104.     CLOSE #U
  105.     KILL URLFile
  106.     state = MID$(state, INSTR(state, "state_abbreviation") + 21)
  107.     state = LEFT$(state, INSTR(state, CHR$(34)) - 1)
  108.     GetStateFromZipCode = state
  109.  
  110. FUNCTION GetLocationVIAip$
  111.     DIM URL AS STRING
  112.     DIM URLFile AS STRING
  113.     DIM location AS STRING
  114.     DIM a%
  115.     URLFile = "location"
  116.     URL = "https://geo.ipify.org/api/v1?apiKey=YOURAPIKEYHERE&ipAddress=" + GetPublicIP
  117.     a% = API_request(URL, URLFile)
  118.     DIM U AS INTEGER
  119.     U = FREEFILE
  120.     OPEN URLFile FOR BINARY AS #U
  121.     IF LOF(U) <> 0 THEN
  122.         location = SPACE$(LOF(U))
  123.         GET #U, , location
  124.     ELSE
  125.         CLOSE #U
  126.         KILL URLFile
  127.         GetLocationVIAip = ""
  128.         EXIT FUNCTION
  129.     END IF
  130.     CLOSE #U
  131.     KILL URLFile
  132.     location = MID$(location, INSTR(location, "postalCode") + 13)
  133.     location = LEFT$(location, INSTR(location, CHR$(34)) - 1)
  134.     GetLocationVIAip = location
  135.  
  136. FUNCTION GetPublicIP$
  137.     DIM URL AS STRING
  138.     DIM URLFile AS STRING
  139.     DIM publicip AS STRING
  140.     DIM a%
  141.     URLFile = "publicip"
  142.     URL = "https://api.ipify.org/"
  143.     a% = API_request(URL, URLFile)
  144.     DIM U AS INTEGER
  145.     U = FREEFILE
  146.     OPEN URLFile FOR BINARY AS #U
  147.     IF LOF(U) <> 0 THEN
  148.         LINE INPUT #U, publicip
  149.     ELSE
  150.         CLOSE #U
  151.         KILL URLFile
  152.         GetPublicIP = ""
  153.         EXIT FUNCTION
  154.     END IF
  155.     CLOSE #U
  156.     KILL URLFile
  157.     GetPublicIP = publicip
  158.  
  159. FUNCTION String.Remove$ (a AS STRING, b AS STRING)
  160.     DIM c AS STRING
  161.     DIM j
  162.     DIM r
  163.     DIM r$
  164.     c = ""
  165.     j = INSTR(a, b)
  166.     IF j > 0 THEN
  167.         r$ = LEFT$(a, j - 1) + c + String.Remove(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b)
  168.     ELSE
  169.         r$ = a
  170.     END IF
  171.     String.Remove = r$
  172.  
  173. FUNCTION String.Replace$ (a AS STRING, b AS STRING, c AS STRING)
  174.     DIM j
  175.     DIM r$
  176.     j = INSTR(a, b)
  177.     IF j > 0 THEN
  178.         r$ = LEFT$(a, j - 1) + c + String.Replace(RIGHT$(a, LEN(a) - j + 1 - LEN(b)), b, c)
  179.     ELSE
  180.         r$ = a
  181.     END IF
  182.     String.Replace = r$
  183.  
  184.     FUNCTION URLDownloadToFileA (BYVAL pCaller AS LONG, szURL AS STRING, szFileName AS STRING, BYVAL dwReserved AS LONG, BYVAL lpfnCB AS LONG)
  185.  
  186. FUNCTION API_request (URL AS STRING, File AS STRING)
  187.     API_request = URLDownloadToFileA(0, URL + CHR$(0), File + CHR$(0), 0, 0)
  188.  
  189.     FUNCTION WinExec (lpCmdLine AS STRING, BYVAL nCmdShow AS LONG)
  190.  
  191. SUB eSpeak (lines AS STRING)
  192.     DIM Filename AS STRING
  193.     DIM x
  194.     Filename = "espeak.exe -v en " + CHR$(34) + lines$ + CHR$(34)
  195.     x = WinExec(Filename$ + CHR$(0), 0)
  196.  
  197. SUB TTS (lines AS STRING)
  198.     DIM x
  199.     x = WinExec("voice -r 2 -d " + lines + CHR$(0), 0)
  200.  
  201. FUNCTION FormatForTTS$ (lines AS STRING)
  202.     IF INSTR(lines, "OVERNIGHT") THEN
  203.         lines = MID$(lines, INSTR(lines, "OVERNIGHT"))
  204.     ELSEIF INSTR(lines, "TODAY") THEN
  205.         lines = MID$(lines, INSTR(lines, "TODAY"))
  206.     ELSEIF INSTR(lines, "TONIGHT") AND INSTR(lines, "TODAY") = 0 THEN
  207.         lines = MID$(lines, INSTR(lines, "TONIGHT"))
  208.     END IF
  209.     lines = String.Remove(lines, CHR$(10))
  210.     lines = String.Replace(lines, "wind", "wend")
  211.     lines = String.Replace(lines, "mph", "miles per hour")
  212.     lines = String.Replace(lines, "thunderstorms", "thunnderstorms")
  213.     FormatForTTS = lines
* voice.exe (Filesize: 14.5 KB, Downloads: 164)
* weatherapi.exe (Filesize: 1.24 MB, Downloads: 185)
« Last Edit: July 22, 2020, 06:58:30 am by SpriggsySpriggs »
Shuwatch!