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 KingdomPosts: 1676 |
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 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 |
||||
Nimue Guru Joined: 06/08/2020 Location: United KingdomPosts: 367 |
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 KingdomPosts: 367 |
.... 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: AustraliaPosts: 843 |
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 KingdomPosts: 1676 |
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 KingdomPosts: 1676 |
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 KingdomPosts: 367 |
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 KingdomPosts: 1676 |
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 KingdomPosts: 1676 |
I don't get one thing In the Pi-Cromite manual it says 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 KingdomPosts: 367 |
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 StatesPosts: 3008 |
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 StatesPosts: 3008 |
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 KingdomPosts: 1676 |
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 StatesPosts: 3008 |
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 KingdomPosts: 1676 |
I'm using a Pi Zero W with Pi-Cromite |
||||
lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1676 |
? 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: AustraliaPosts: 843 |
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 KingdomPosts: 1676 |
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 KingdomPosts: 1676 |
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 |