Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 19:49 19 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Json

Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 08:57am 01 Dec 2020
Copy link to clipboard 
Print this post

Apologies for starting a new topic as this was part of another thread
but I think it might help others like me who don't understand how JSON works and how to parse it.

Can Anyone who knows JSON tell me why this isn't working, or give me some ideas to get it working?

I need the DAILY data for each of the 10 days

I'm not asking for the answer to how to get the data I need (although it would be nice to get it) even ideas on how to would help immensely

This is my program
Dim As integer e(15000)
DIM STRING q=Chr$(34) '" symbol
system "wget -q -O- "+q$+"https://swd.weatherflow.com/swd/rest/better_forecast?api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8&station_id=35102&lat=53.439&lon=-2.106"+q$,e()
day$=JSON$(e(),"daily[1]day_start_local[2].month_num")'day_num
PRINT day$


I have tried every way I can think of to get the JSON parsed so I get the result I want

this is what I have tried
  Quote  day$=JSON$(e(),"daily.day_start_local[2].day_num")'day_num
day$=JSON$(e(),"dailyday_start_local[2].day_num")'day_num
day$=JSON$(e(),"day_start_local[2].day_num")'day_num
day$=JSON$(e(),"day_start_local[2].day_num")'day_num
day$=JSON$(e(),"daily.day_start_local[2]month_num")'day_num
day$=JSON$(e(),"daily.day_start_local[2].month_num")'day_num
day$=JSON$(e(),"daily[1]day_start_local[2].month_num")'day_num


As you can see I changed the day_num to month_num to check it wasn't something to do with that field

This is the results



I want to get the relevant data from the DAILY section of the JSON
This is PART of the JSON return from my call
If you want to see the complete return click HERE
  Quote  {"latitude":53.439,"longitude":-2.106,"timezone":"Europe/London","timezone_offset_minutes":0,"current_conditions":{"conditions":"Clear","icon":"cc-clear-day","air_temperature":0.0,"sea_level_pressure":1028.0,"relative_humidity":96,"wind_avg":0.0,"wind_direction":15,"wind_direction_cardinal":"NNE","wind_direction_icon":"wind-rose-nne","wind_gust":0.0,"uv":0,"feels_like":0.0,"includes_station_data":false},"forecast":{"daily":[{"day_start_local":1606780800,"day_num":1,"month_num":12,"conditions":"Partly Cloudy","icon":"partly-cloudy-day","sunrise":1606723218,"sunset":1606751644,"air_temp_high":6.0,"air_temp_low":0.0,"air_temp_high_color":"0053ee","air_temp_low_color":"0000e1","precip_probability":10,"precip_icon":"chance-sleet","precip_type":"sleet"},{"day_start_local":1606867200,"day_num":2,"month_num":12,"conditions":"Rain Likely","icon":"rainy","sunrise":1606809707,"sunset":1606838000,"air_temp_high":7.0,"air_temp_low":3.0,"air_temp_high_color":"006ae4","air_temp_low_color":"001ee1","precip_probability":80,"precip_icon":"chance-rain","precip_type":"rain"},{"day_start_local":1606953600,"day_num":3,"month_num":12,"conditions":"Rain Likely","icon":"rainy","sunrise":1606896193,"sunset":1606924360,"air_temp_high":4.0,"air_temp_low":2.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":60,"precip_icon":"chance-rain","precip_type":"rain"},{"day_start_local":1607040000,"day_num":4,"month_num":12,"conditions":"Snow Likely","icon":"snow","sunrise":1606982677,"sunset":1607010724,"air_temp_high":3.0,"air_temp_low":1.0,"air_temp_high_color":"001ee1","air_temp_low_color":"0000e1","precip_probability":70,"precip_icon":"chance-snow","precip_type":"snow"},{"day_start_local":1607126400,"day_num":5,"month_num":12,"conditions":"Rain Likely","icon":"rainy","sunrise":1607069159,"sunset":1607097091,"air_temp_high":4.0,"air_temp_low":3.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":70,"precip_icon":"chance-rain","precip_type":"rain"},{"day_start_local":1607212800,"day_num":6,"month_num":12,"conditions":"Wintry Mix Possible","icon":"possibly-sleet-day","sunrise":1607155639,"sunset":1607183461,"air_temp_high":5.0,"air_temp_low":2.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":40,"precip_icon":"chance-sleet","precip_type":"sleet"},{"day_start_local":1607299200,"day_num":7,"month_num":12,"conditions":"Wintry Mix Possible","icon":"possibly-sleet-day","sunrise":1607242116,"sunset":1607269835,"air_temp_high":4.0,"air_temp_low":3.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":40,"precip_icon":"chance-sleet","precip_type":"sleet"},{"day_start_local":1607385600,"day_num":8,"month_num":12,"conditions":"Rain Likely","icon":"rainy","sunrise":1607328591,"sunset":1607356212,"air_temp_high":5.0,"air_temp_low":3.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":50,"precip_icon":"chance-rain","precip_type":"rain"},{"day_start_local":1607472000,"day_num":9,"month_num":12,"conditions":"Wintry Mix Possible","icon":"possibly-sleet-day","sunrise":1607415064,"sunset":1607442593,"air_temp_high":5.0,"air_temp_low":3.0,"air_temp_high_color":"003bf2","air_temp_low_color":"001ee1","precip_probability":40,"precip_icon":"chance-sleet","precip_type":"sleet"},{"day_start_local":1607558400,"day_num":10,"month_num":12,"conditions":"Rain Likely","icon":"rainy","sunrise":1607501534,"sunset":1607528977,"air_temp_high":6.0,"air_temp_low":3.0,"air_temp_high_color":"0053ee","air_temp_low_color":"001ee1","precip_probability":50,"precip_icon":"chance-rain","precip_type":"rain"}],"hourly":[{[/QUOTE}
Edited 2020-12-01 18:58 by lew247
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 09:28am 01 Dec 2020
Copy link to clipboard 
Print this post

Hi  

I always start with JSON by viewing it in: http://jsonviewer.stack.hu/  >> in the text tab.

View the structure in the View tab.

What I see is that the structure is:

forecast >> daily >> day (with 10 elements - one for each day)




Is this as simple as you need to also include the forecast element in your query and then retrieve the data?

The data for each day is in >>>

forecast.daily[0]  << will return all the data in daily {0}

But I have to admit, I would only ever access JSON via Python (dont hate me)

Nim
(edit for spelling)
Edited 2020-12-01 19:36 by Nimue
Entropy is not what it used to be
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 09:55am 01 Dec 2020
Copy link to clipboard 
Print this post

....  So, for example:

import json
from urllib.request import urlopen

weather = urlopen('https://swd.weatherflow.com/swd/rest/better_forecast?api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8&station_id=35102&lat=53.439&lon=-2.106')
wjson = weather.read()
wjdata = json.loads(wjson)
print (wjdata['forecast']['daily'][0]['day_start_local'])



Will print "1606780800"  >>> which is the forecast.daily[0].day_start_local element data...

So in your case, do you need:

day$=JSON$(e(),"forecast.daily[0].day_start_local")'  << would be equivalent, but not quite sure on the format you need for your parser.

Importantly, the day$ string you are creating will only contain the single element you are retrieving (in this case day_start_local).  

To retrieve all the element data, day$=JSON$(e(),"forecast.daily[0]")'  << would now contain all the elements for daily[0], but would need further parsing to extract each element.


Nim
Edited 2020-12-01 20:09 by Nimue
Entropy is not what it used to be
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 843
Posted: 11:43am 01 Dec 2020
Copy link to clipboard 
Print this post

The JSON syntax works as detailed by Nim. I use Firefox and it displays the raw data and also the formatted JSON

The code below pulls various bits for days 0-9 in a loop.

eg.

? JSON$(e(),"forecast.daily[7].conditions")
will get day 7.



Dim As integer e(15000),i
DIM STRING q=Chr$(34) '" symbol
system "wget -q -O- "+q$+"https://swd.weatherflow.com/swd/rest/better_forecast?api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8&station_id=35102&lat=53.439&lon=-2.106"+q$,e()
for i=48 to 57  'Ascii for 0 to 9

' ? JSON$(e(),"forecast.daily["+chr$(i)+"].day_start_local")
 ? JSON$(e(),"forecast.daily["+chr$(i)+"].day_num")+"/";
 ? JSON$(e(),"forecast.daily["+chr$(i)+"].month_num")+"  ";  
 ? JSON$(e(),"forecast.daily["+chr$(i)+"].conditions")+"  Max=";
 ? JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_high")+"  Min=";
 ? JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_low")
next i




Gerry
Latest F4 Latest H7
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 01:42pm 01 Dec 2020
Copy link to clipboard 
Print this post

Thats brilliant
Thank you both so much  
Gerry you're amazing
Nimue that JSON viewer link is brilliant, I've bookmarked it for future use
Edited 2020-12-01 23:45 by lew247
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 02:36pm 01 Dec 2020
Copy link to clipboard 
Print this post

I Love this forum  
This works perfectly  
Dim As integer e(15000),i
DIM STRING q=Chr$(34) '" symbol
system "wget -q -O- "+q$+"https://swd.weatherflow.com/swd/rest/better_forecast?api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8&station_id=35102&lat=53.439&lon=-2.106"+q$,e()

for i=48 to 57  'Ascii for 0 to 9
cond$ = JSON$(e(),"forecast.daily["+chr$(i)+"].conditions")
test$ = JSON$(e(),"forecast.daily["+chr$(i)+"].day_start_local")
icon$ = JSON$(e(),"forecast.daily["+chr$(i)+"].icon")
thigh$= JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_high")
tlow$ = JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_low")
precpr$ = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_probability")
precpicon$ = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_icon")
preciptype$ = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_type")

print test$
print cond$
print icon$
print thigh$
print tlow$
print precpr$
print precpicon$
print preciptype$
next i


I just wish there was a way to rename each string$ each time it goes through the 10 cycles
so test$ would be
test1$
test2$
etc
icon$
icon1$
icon2$ and so on
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 02:50pm 01 Dec 2020
Copy link to clipboard 
Print this post

  lew247 said  I Love this forum  

I just wish there was a way to rename each string$ each time it goes through the 10 cycles
so test$ would be
test1$
test2$
etc
icon$
icon1$
icon2$ and so on



Can you make test$ an array?  So that test$(i) refers to each pass?

Naming discrete variables on the fly feels like self modifying code and that's never a good thing (and not sure you can do that in MMBASIC)



for i=48 to 57  'Ascii for 0 to 9
cond$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].conditions")
test$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].day_start_local")
icon$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].icon")
thigh$(i)= JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_high")
tlow$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].air_temp_low")
precpr$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_probability")
precpicon$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_icon")
preciptype$(i) = JSON$(e(),"forecast.daily["+chr$(i)+"].precip_type")


so that cond$(0) = refrers to daily 0, cond$(1) daily 1 etc etc  -- you'd need to dimension your array appropriately as they are immutable.

Nim
Edited 2020-12-02 01:29 by Nimue
Entropy is not what it used to be
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 04:34pm 01 Dec 2020
Copy link to clipboard 
Print this post

Unfortunately no
that won't work because it has to end with $ and not an integer
You can't add a number in the middle of a String in a loop
I went through everything I could think of to make it work
Even putting
aa - 0
for i=48 to 57  'Ascii for 0 to 9
cond$("aa") = JSON$(e(),"forecast.daily["+chr$(i)+"].conditions")
codd("aa")$ and so on but nothing worked
and even if it did work then it would just do the same thing 10 times over
its easy enough to write them out in full now that the JSON is working
Thanks for trying though
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 06:27pm 01 Dec 2020
Copy link to clipboard 
Print this post

I don't get one thing
In the Pi-Cromite manual it says
  Quote  JSON$(array%(),string$)
Returns a string representing a specific item out of the JSON input stored in the longstring array%()
e.g.JSON$(a%(), “name”)JSON$(a%(), “coord.lat”)JSON$(a%(), “weather[0].description”)JSON$(a%(),”list[4].weather[0].description


This is what the JSON of THIS LINK returns

I can't figure out how to get the obs array in a string using JSON
a$ = JSON$(e(),"obs") should have worked according to the manual
or possibly
a$ JSON$(a%(), "obs.0")
Neither works
I did try JSON$(e%() as well as JSON$(e()

Anyone who knows JSON know the answer why it isn't working?
Edited 2020-12-02 04:28 by lew247
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 367
Posted: 06:47pm 01 Dec 2020
Copy link to clipboard 
Print this post

  lew247 said  Unfortunately no
that won't work because it has to end with $ and not an integer
You can't add a number in the middle of a String in a loop
I went through everything I could think of to make it work
Even putting
aa - 0
for i=48 to 57  'Ascii for 0 to 9
cond$("aa") = JSON$(e(),"forecast.daily["+chr$(i)+"].conditions")
codd("aa")$ and so on but nothing worked
and even if it did work then it would just do the same thing 10 times over
its easy enough to write them out in full now that the JSON is working
Thanks for trying though


Nps

Is this a use case for EVALUATE (FUNCTION) - to build the string to actually execute?   That said, its above my MMBASIC-fu.

Nim
Entropy is not what it used to be
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3008
Posted: 06:52pm 01 Dec 2020
Copy link to clipboard 
Print this post

I have trouble making sense of this, and can't test, but does this not work?

a$ = JSON$(e(),"obs[0]")

Returning the entire string contents, "1606847855,1015.5,4.7,93,0,0,2.77,1" of the zeroth element of the obs array?

Likewise would a$ = JSON$(e(),"obs[0][0]") return "1606847855".

(Hard to look at this without having a Pi that runs mmbasic (after upgrading to Buster--why, why?).)
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3008
Posted: 07:39pm 01 Dec 2020
Copy link to clipboard 
Print this post

The Armmite F4 has JSON$. FWIW I tried many combinations, and could not figure it out.

> dim string qt=chr$(34)
> a$="{"+qt+"obs"+qt+":[[1606847855,1015.5,4.7,93,0,0,2.77,1]]}"
> ?a$
{"obs":[[1606847855,1015.5,4.7,93,0,0,2.77,1]]}
> dim integer ls(1000)
> longstring append ls(),a$
> ?json$(ls(),"obs[0]")
Error: Dimensions
> ?json$(ls(),"obs[0][0]")
Error: Dimensions
> ?json$(ls(),"obs")
Error: Dimensions
> longstring print ls()
{"obs":[[1606847855,1015.5,4.7,93,0,0,2.77,1]]}
> ?json$(ls(),"obs")
Error: Dimensions
> ?json$(ls(),"obs[0].")
Error: Dimensions
> ?json$(ls(),"obs[1][1]")
Error: Dimensions
> ?json$(ls(),"obs[1]")
Error: Dimensions
> ?json$(ls%(),"obs")
Error: Dimensions
> ?json$(ls(),"obs[0].[0]")
Error: Dimensions
>

PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 07:45pm 01 Dec 2020
Copy link to clipboard 
Print this post

I'm trying to Return the  entire string contents, "1606847855,1015.5,4.7,93,0,0,2.77,1" as you thought
because once I can do that I can figure out how to get it to return each field as part of the JSON return

Unfortunately a$ = JSON$(e(),"obs[0]")
returned


and

a$ = JSON$(e(),"obs[0][0]") crashed MM


Edited 2020-12-02 05:50 by lew247
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3008
Posted: 12:35am 02 Dec 2020
Copy link to clipboard 
Print this post

  lizby said  The Armmite F4 has JSON$.


Hmmm. I think I went down this road before. The H7 has JSON$, as shown in the manual. There is no manual for the F4 so far as I know. As I see it now, and as I seem to remember, ?json$(ls(),"obs[0][0]") yielding "Error: Dimensions" is because the function, json$, doesn't exist, so the interpreter thinks it's an array and it hasn't been dimensioned.

So I'm back to being unable to test. I may be able to dig out an H7 tomorrow.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 08:53am 02 Dec 2020
Copy link to clipboard 
Print this post

  lizby said  
  lizby said  The Armmite F4 has JSON$.


Hmmm. I think I went down this road before. The H7 has JSON$, as shown in the manual. There is no manual for the F4 so far as I know. As I see it now, and as I seem to remember, ?json$(ls(),"obs[0][0]") yielding "Error: Dimensions" is because the function, json$, doesn't exist, so the interpreter thinks it's an array and it hasn't been dimensioned.

So I'm back to being unable to test. I may be able to dig out an H7 tomorrow.

I'm using a Pi Zero W with Pi-Cromite
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 09:06am 02 Dec 2020
Copy link to clipboard 
Print this post

  Quote  ? JSON$(e(),"obs[0][0]") 'crashes
? JSON$(e(),"obs[0]") 'crashes
? JSON$(e(),"obs") 'crashes
? JSON$(a(),"obs.0") 'crashes
? JSON$(a(),"obs.1") 'crashes


I'm guessing it's one of the Pi-Cromite bugs that never got fixed.
The disadvantages of PI being the only Micromite that has WI-FI
Edited 2020-12-02 19:06 by lew247
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 843
Posted: 10:15am 02 Dec 2020
Copy link to clipboard 
Print this post

It looks like the JSON implementation does not handle an array of arrays
so you need to pull out the required string by finding the text between
[[ and ]].
Then use FIELD$ to pull the data from the bit pulled out.

See code below.

(I think we have discovered this before)







Dim As integer e(15000),i
DIM STRING q=Chr$(34) '" symbol
DIM STRING obs$

system "wget -q -O- "+q$+"https://swd.weatherflow.com/swd/rest/observations/?device_id=35102&api_key=20c70eae-e62f-4d3b-b3a4-8586e90f3ac8"+q$,e()
longstring PRINT e()  ' print weather to test it works*
? JSON$(e(),"status.status_message")                 'status
? JSON$(e(),"summary.pessure_trend")  '[0]

' The JSON parser seems not to handle an array of arrays
' so just cut out the string we want by finding [[ and ]] and cut the out
' what is in between as obs$
obs$=LGETSTR$(e(),LINSTR(e(),"[[")+2,LINSTR(e(),"]]")-LINSTR(e(),"[[")-2)
? obs$
' now use field$ to pull out the required data.
? field$(obs$,1)
? field$(obs$,2)
? field$(obs$,3)
? field$(obs$,4)
? field$(obs$,5)
? field$(obs$,6)
? field$(obs$,7)
? field$(obs$,8)


Latest F4 Latest H7
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 11:49am 02 Dec 2020
Copy link to clipboard 
Print this post

  disco4now said  It looks like the JSON implementation does not handle an array of arrays
so you need to pull out the required string by finding the text between
[[ and ]].
Then use FIELD$ to pull the data from the bit pulled out.
(I think we have discovered this before)

Yes we did and it works fine, I was just hoping to simplify it
Edited 2020-12-02 22:13 by lew247
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 09:11am 21 Mar 2021
Copy link to clipboard 
Print this post

Is there a way to get a program to skip if an element is missing?

for example in a weather forecast
lightning_strike_last_epoch is the time of the last lightning strike which I can parse with no problem

but with a new station, this element is completely missing and the program cannot parse what isn't there.

How can you tell the program to skip the element if it's not in the data being parsed?
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024