OpenWeatherMap JSON API forecast for rain and snow - json

I am facing problems forcing my code run smoothly when there is no value for Parameters rain and snow. Actually it loops as long as there are values for these parameters and if not it ends.
I have included gson library for helping me get the values as JSON objects/strings/double etc.
for (int l=0; l<40; l++) {
Forecast fcath = new Forecast();
fcath.setMain_temp(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("main").getAsJsonObject().get("temp").getAsDouble());
fcath.setWeather_description(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("weather").getAsJsonArray().get(0).getAsJsonObject().get("description").getAsString());
fcath.setClouds_all(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("clouds").getAsJsonObject().get("all").getAsInt());
fcath.setWind_speed(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("wind").getAsJsonObject().get("speed").getAsDouble());
fcath.setDt_txt(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("dt_txt").getAsString());
fcath.setRain(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject().get("3h").getAsDouble());
fcath.setSnow(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("snow").getAsJsonObject().get("3h").getAsDouble());
f.add(fcath);
System.out.println("Date: " + f.get(l).getDt_txt() + " Temp: " + f.get(l).getMain_temp() + " Celsius " + " Chance of Rain: " + f.get(l).getRain() + " Chance of Snow: " + f.get(l).getSnow());
}
Without fcath.setRain and fcath.setSnow code lines the output is the following:
Working output photo
Assuming that there is no rain chance in the forecast
e.g.
fcath.setRain(obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject().get("3h").getAsDouble()); == {}
it gives me NullPointerException
NullPointerException photo

Is still hard to say with the information provided, but seems that if the is no rain chance, then probably
obj_fcath.get("list").getAsJsonArray().get(l).getAsJsonObject().get("rain").getAsJsonObject()
is null. Then you cannot do a get("3h").getAsDouble() from a null object.

Related

Repeating a GET request without re-running script

I am trying to create a script that will show the bus times from my local stop on a scrollphatHD on raspberry pi zero w.
I can get the script running and I get the correct bus times, but I am having trouble getting the new bus times without restarting the script.
How can I loop the bus times so that I always get the updated times?
import requests
import signal
import scrollphathd
from scrollphathd.fonts import font3x5
r = requests.get("https://skyss.giantleap.no/public/departures?Hours=1&StopIdentifiers=12015491")
dest = r.json()["PassingTimes"][0]["TripDestination"]
avgang = r.json()["PassingTimes"][0]["DisplayTime"]
dest2 = r.json()["PassingTimes"][1]["TripDestination"]
avgang2 = r.json()["PassingTimes"][1]["DisplayTime"]
linje2 = dest + " " + avgang + ", " + dest2 + " " + avgang2 + ", "
while True:
scrollphathd.write_string(str1, y=1, font=font3x5, brightness=0.5)
scrollphathd.flip(x,y)
scrollphathd.scroll()
scrollphathd.show()
print(linje2)
I want the result to be updated about every 20 seconds or so, but I end up just getting the time from when I start the script over and over.

Converting mysql date to js date works in chrome but not safari

I am using a pipe in angular2 to convert a mysql date to a js date format here is my code:
export class DateToIso {
transform(value) {
let date = new Date(value);
let str = (date.getMonth() + 1) + '.' + date.getDate() + '.' + date.getFullYear()
return str;
}
}
In HTML I use
{{ post[2] | dateToIso}}
to show the converted date. In Chrome I get the correct datetime but not in safari. It returns NaN.NaN.NaN.
I had a similar problem with the currency pipe and it was an internationalization issue. I wrote it up here http://blogs.msmvps.com/deborahk/angular-2-getting-started-problem-solver/
Install the international package: npm install intl#1.1.0 –save
Include the following in index.html:
(I'm using a touch device and the pasted code doesn't work. Please see the link)
I tried it #DeborahK but it didn`t work so I just took the Mysql date "String" and made substrings out of it and rearranged the substrings to a new string and returned it.
export class DateToIso {
transform(value, args) {
let month = value.substr(5,2);
let day = value.substr(8,2);
let timeThen = value.substr(11,5);
let newValue = day + "." + month + " um " + timeThen;
return newValue;
}
}
I believe this is not the best solution but it is working. Hope to get better solutions soon.

Pulling URLs from objects for popup marker window

New to leaflet, and basically everything programming related.
I am making a brewery map showing locations of breweries, distilleries, vineyards, etc around the state.
What I want to do is have a popup that gives:
Name, Address, URL to that specific website.
I've figured out the Name/Address part, but I just can't figure out how to pull the URL from the object's properties. I've tried many iterations, none work (or even partially work).
As well, my searches have been fruitless, but I can't be the only one who has tried to do this. Bad search skills?
//load GeoJSON from an external file
$.getJSON("breweries.geojson",function(data){
var pintGlass = L.icon({
iconUrl: 'glass.png',
iconSize: [24,48]
});
var popupMarker = L.geoJson(data,{
pointToLayer: function(feature,latlng){
var marker = L.marker(latlng,{icon: pintGlass});
marker.bindPopup("<strong>" + feature.properties.NAME + "</strong> </br/>" + feature.properties.STREETNUM
+ " " + feature.properties.STREET + ", " + feature.properties.CITY + <a href=feature.properties.URL>feature.properties.URL</a>);
return marker;
}
});
var clusters = L.markerClusterGroup();
clusters.addLayer(popupMarker);
map.addLayer(clusters);
});
The last bit of the marker.bindPopup is the trouble spot. I've tried single quotes, double quotes, no luck. I tried creating a variable to pull the object.properties.URL out and insert that variable into the with no luck.
The problem is exactly at the following point, where you are trying to create a String:
+ <a href=feature.properties.URL>feature.properties.URL</a>
which should be
+ "" + feature.properties.URL + ""
It appears that you a not enclosing your strings correctly.
Try this and let me know if it works:
marker.bindPopup("<strong>" + feature.properties.NAME + "</strong></br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + " " + feature.properties.URL + "");
I know you've got a couple of "working" answers but i'de like to point out a few things. At the moment your ending up with markup like this:
<a href=http://example.org>http://example.org</a>
But it's best practice in HTML to make sure attribute values are wrapped in double quotes like this:
http://example.org
To accomplish that you'll have to do the following:
"" + feature.properties.URL + ""
Notice the slashes proceding the double quotes, a slash escapes the following double quote so that it gets treated like a string. Things like this can get pretty ugly very quick. That's why it's best when you're concatenating HTML with javascript that you simply use single quotes:
'' + feature.properties.URL + ''
That way you won't have to escape any double quotes in your strings.
And i'de like to point out a thing that Leaflet users often overlook is the wonderful L.Util.template method:
Simple templating facility, accepts a template string of the form 'Hello {a}, {b}' and a data object like {a: 'foo', b: 'bar'}, returns evaluated string ('Hello foo, bar'). You can also specify functions instead of strings for data values — they will be evaluated passing data as an argument.
http://leafletjs.com/reference.html#util-template
Using that takes away a lot of the hassle of what you're doing now, for example:
var values = {
a: feature.properties.NAME,
b: feature.properties.STREETNUM,
c: feature.properties.STREET,
d: feature.properties.CITY,
e: feature.properties.URL
};
var templateString = '<strong>{a}</strong><br>{b} {c}, {d} {e}';
var htmlString = L.Util.template(templateString, values);

How to deal with information received in two packets

This is the case. I want to make a game, client being made in flash and server on java. From server side, the first byte i write on the stream is the protocol id, like this:
try
{
Output.writeByte(LOGIN);
Output.writeByte((byte)ID);
Output.writeByte(new_position.x);
Output.writeByte(new_position.y);
Output.flush();
}
After the 'onResponse' event is triggered, the socket is read like this:
type:int = socket_client.readByte();
if (type == 0x1)
FP.console.log("You are logged as " + socket_client.readByte() + " in x:" + socket_client.readByte() + " y:" + socket_client.readByte() );
else if (type == 0x2)
FP.console.log("You are now in x:" + socket_client.readByte() + " y:" + socket_client.readByte());
As you probably have guessed by now, this gives me some problems. Sometimes, server sends the information split in two, so the above code throws an EOF exception. Tracing the following code gives me sometimes this result:
trace("SIZE: " + socket_client.bytesAvailable);
//var type:int = socket_client.readByte();
var values:String = "";
while (socket_client.bytesAvailable > 0)
values += socket_client.readByte() + " ";
trace(values);`
Values:
SIZE: 1
2
SIZE: 2
2 6
The first '2' is the protocol id, the second and the third stands for x and y values.
Now, the question is, how can i prevent this to happen? How could i 'wait' until i have all the information needed?
Btw, on java this never happens, but i have no more control than on as3.
Add BufferedOutputStream in output initialization like this:
Output = new DataOutputStream(new BufferedOutputStream(connection.getOutputStream()));
Basically you need to switch your message format from [type, data] to [type, length, data]. Then, wait to process the data until bytesAvailable >= length, otherwise put it into a buffer.
Here is an example SOCKET_DATA handler that uses this logic:
https://github.com/magicalhobo/Flash-CS5-mobile-proxy/blob/master/com/magicalhobo/mobile/proxy/MobileClient.as#L110

"CalendarApp: Mismatch: etags" when adding reminders - Google Apps Scripts

I have a small Google Apps Script that processes a date column in a spreadsheet and generates entries in a Calendar (birthdays).
Work is fine, but when adding reminders to the (recently-created) CalendarEvent, an error is thrown :
Service error: CalendarApp: Mismatch: etags = ["GUQKRgBAfip7JGA6WhJb"], version = [63489901413]
I've tried to perform 1 second sleep after creating event (wait for changes to be done in calendar), but no luck on this...
BTW, events are created succesfully, only reminders cannot be added.
PD: the calendar is one I own, but not my primary calendar.
Here is part of the code:
try
{
birthday = new Date(Data[i][BirthColumn]);
birthday.setFullYear(today.getFullYear());
birthday.setUTCHours(12);
birthlist += Data[i][NameColumn] + " --> " + birthday + "\n";
calendarevent = cal.createAllDayEventSeries("¡Cumpleaños " + Data[i][NameColumn] + "!", birthday, CalendarApp.newRecurrence().addYearlyRule().times(YearsInAdvance));
if (calendarevent == null)
success = false;
else
{
//This sentence fails every single time.
calendarevent.addEmailReminder(0);
calendarevent.addPopupReminder(0);
calendarevent.addSmsReminder(0);
}
}
catch (ee)
{
var row = i + 1;
success = false;
errlist += "Error on row " + row + ": check name and birth date. Exception Error: " + ee.message + "\n";
}
This is the portion of the code I finally change to make it work, as Serge insas suggest me before:
if (calendarevent == null)
success = false;
else
{
cal.getEventSeriesById(calendarevent.getId()).addEmailReminder(0);
cal.getEventSeriesById(calendarevent.getId()).addPopupReminder(0);
cal.getEventSeriesById(calendarevent.getId()).addSmsReminder(0);
}
This is a known issue
See comment nr 67 for a working workaround : the trick is to re-call the event for every item you want to add (reminder, popup...) using cal.getEventSeriesById(eventID) after you get the Id simply with .getId()
I use it in some scripts and it solved the issue for me.