Created
January 11, 2024 06:16
-
-
Save kylemsguy/5875f3d37eab25739db835b319c3030c to your computer and use it in GitHub Desktop.
Modern Pebble Watch Face OpenWeather API fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var weathersleep = false; | |
var ready = false; | |
var settings; | |
var manuallongitude; | |
var manuallatitude; | |
var manuallocation; | |
var fetchtime = 60; | |
var apikey = "{API_KEY_HERE}"; | |
function iconFromWeatherId(weatherId) { | |
if (weatherId < 300) { | |
return 7; | |
} else if (weatherId < 400) { | |
return 6; | |
} else if (weatherId == 511) { | |
return 8; | |
} else if (weatherId < 600) { | |
return 6; | |
} else if (weatherId < 700) { | |
return 8; | |
} else if (weatherId < 800) { | |
return 10; | |
} else if (weatherId == 800) { | |
return 1; | |
} else if (weatherId == 801) { | |
return 2; | |
} else if (weatherId < 900) { | |
return 5; | |
} else { | |
return 0; | |
} | |
} | |
function translateYWeather(code){ | |
if ( code < 5){ | |
return 7; | |
} else if ( code < 13){ | |
return 6; | |
} else if ( code < 19){ | |
return 8; | |
} else if ( code < 23){ | |
return 10; | |
} else if ( code < 25){ | |
return 2; | |
} else if ( code < 26){ | |
return 9; | |
} else if ( code < 27){ | |
return 5; | |
} else if ( code < 28){ | |
return 4; | |
} else if ( code < 29){ | |
return 2; | |
} else if ( code < 30){ | |
return 4; | |
} else if ( code < 31){ | |
return 2; | |
} else if ( code < 32){ | |
return 3; | |
} else if ( code < 33){ | |
return 1; | |
} else if ( code < 34){ | |
return 3; | |
} else if ( code < 35){ | |
return 1; | |
} else if ( code < 36){ | |
return 6; | |
} else if ( code < 37){ | |
return 1; | |
} else if ( code < 40){ | |
return 7; | |
} else if ( code < 41){ | |
return 6; | |
} else if ( code < 44){ | |
return 8; | |
} else if ( code < 45){ | |
return 5; | |
} else if ( code < 46){ | |
return 7; | |
} else if ( code < 47){ | |
return 8; | |
} else if ( code < 48){ | |
return 7; | |
} else { | |
return 0; | |
} | |
} | |
function fetchWeather(latitude, longitude) { | |
fetchOWeather(latitude, longitude); | |
} | |
function fetchOWeather(latitude, longitude) { | |
if(!latitude||!longitude||latitude=="undefined"||longitude=="undefined"){ | |
console.log("Pebble JS: Location not set"); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" SET LOC."}); | |
return; | |
} | |
var response; | |
var req = new XMLHttpRequest(); | |
var imperial = ""; | |
var degrees = "C"; | |
var kelvins = 273.15; | |
if(settings.substring(10,11)=='1'){ | |
imperial = "&units=imperial"; | |
degrees = "F"; | |
kelvins = 0.0; | |
} | |
req.open('GET', "http://api.openweathermap.org/data/2.5/weather?" + | |
"lat=" + latitude + "&lon=" + longitude + imperial + "&APPID=" + apikey, true); | |
req.onload = function(e) { | |
if (req.readyState == 4) { | |
if(req.status == 200) { | |
//console.log("Pebble JS: open weather api response: " + req.responseText); | |
console.log("Pebble JS: Got weather from openweather."); | |
response = JSON.parse(req.responseText); | |
var temperature, icon, city, description, icon_n; | |
temperature = Math.round(response.main.temp - kelvins); | |
icon = iconFromWeatherId(response.weather[0].id); | |
icon_n = response.weather[0].icon; | |
if(icon_n == "01n")icon = 3; | |
if(icon_n == "02n")icon = 4; | |
console.log("Pebble JS: temp = " + temperature + ", icon_n = " + icon_n + ", icon = " + icon); | |
Pebble.sendAppMessage({ | |
"icon":icon, | |
"temperature":" " + temperature + degrees}); | |
} else { | |
console.log("Pebble JS: Error processing weather:" + req.readyState + ", HTTP code: " + req.status); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" WEB " + req.status}); | |
} | |
} | |
} | |
req.onerror = function(e) { | |
console.log("Pebble JS: Error downloading weather: " + req.status); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" DATA "+req.status}); //0 means timeout | |
} | |
req.send(null); | |
} | |
function fetchYWeather() { | |
var response; | |
var req = new XMLHttpRequest(); | |
var degrees = "C"; | |
if(settings.substring(10,11)=='1'){ | |
degrees = "F"; | |
} | |
if(!manuallocation||manuallocation==""){ | |
console.log("Pebble JS: Location not set"); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" SET LOC."}); | |
return; | |
} | |
var locationQuery = escape("select item from weather.forecast where woeid in (select woeid from geo.places where text='" + manuallocation + "') and u='" + degrees.toLowerCase() + "'"), | |
locationUrl = "http://query.yahooapis.com/v1/public/yql?q=" + locationQuery + "&format=json"; | |
req.open('GET', locationUrl, true); | |
req.onload = function(e) { | |
if(req.readyState == 4){ | |
if(req.status == 200){ | |
//console.log("Pebble JS: req.responseText=" + req.responseText); | |
console.log("Pebble JS: Got weather from yahoo."); | |
response = JSON.parse(req.responseText); | |
var temperature, code, icon; | |
try{ | |
temperature = Math.round(response.query.results.channel[0].item.condition.temp); | |
code = response.query.results.channel[0].item.condition.code; | |
}catch(err){ | |
try{ | |
temperature = Math.round(response.query.results.channel.item.condition.temp); | |
code = response.query.results.channel.item.condition.code; | |
}catch(err){ | |
console.log("Pebble JS: Can't fetch weather for location: " + manuallocation); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" 404"}); | |
return; | |
} | |
} | |
icon = translateYWeather(code); | |
console.log("Pebble JS: temp = " + temperature + ", code = " + code + ", icon = " + icon); | |
Pebble.sendAppMessage({ | |
"icon":icon, | |
"temperature":" " + temperature + degrees}); | |
}else{ | |
console.log("Pebble JS: req.status=" + req.status); | |
console.log("Pebble JS: req.responseText=" + req.responseText); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" WEB " + req.status}); | |
} | |
}else{ | |
console.log("Pebble JS: req.readystate=" + req.readystate); | |
console.log("Pebble JS: locationUrl=" + locationUrl); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" WEB " + req.status}); | |
} | |
} | |
req.onerror = function(e) { | |
console.log("Pebble JS: Error downloading weather: " + req.status); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" DATA "+req.status}); //0 means timeout | |
} | |
req.send(null); | |
} | |
function locationSuccess(pos) { | |
var coordinates = pos.coords; | |
console.log('Pebble JS: location success!'); | |
fetchWeather(coordinates.latitude, coordinates.longitude); | |
} | |
function locationError(err) { | |
console.warn('location error (' + err.code + '): ' + err.message); | |
Pebble.sendAppMessage({ | |
"icon":11, | |
"temperature":" GPS" | |
}); | |
} | |
var locationOptions = { "timeout": 15000, "maximumAge": 60000 }; | |
function getLocationForWeather(){ | |
if(settings.substring(13,14)=='0')return;//weather off | |
if(settings.substring(14,15)=='1'){ | |
//yahoo | |
fetchYWeather(); | |
}else if(settings.substring(11,12)=='1'){ | |
//location automatic | |
console.log("Pebble JS: fetching weather for automatic location..."); | |
window.navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions); | |
}else{ | |
//location manual | |
console.log("Pebble JS: fetching weather for manual location: lat " + manuallatitude + ", lng " + manuallongitude); | |
fetchWeather(manuallatitude, manuallongitude); | |
} | |
} | |
Pebble.addEventListener("ready", | |
function(e) { | |
console.log("Pebble JS reading settings..."); | |
settings = localStorage.getItem("modernsettings"); | |
if (!settings||settings==""||settings.length<19) { | |
settings = "0100008220010100001"; | |
} | |
console.log("Pebble JS: settings are: " + settings + ", sending settings."); | |
manuallongitude = localStorage.getItem("modernlongitude"); | |
manuallatitude = localStorage.getItem("modernlatitude"); | |
manuallocation = localStorage.getItem("modernlocation"); | |
fetchtime = localStorage.getItem("modernfetchtime"); | |
if (!manuallocation||manuallocation=="") { | |
manuallocation = ""; | |
} | |
Pebble.sendAppMessage({"settings":translateForPebble()}, | |
function(e) { | |
console.log("Pebble JS: settings delivered."); | |
getLocationForWeather(); | |
}, | |
function(e) { | |
console.log("Peble JS: unable to deliver settings, " +e.error.message); | |
getLocationForWeather(); //because, why not? | |
} | |
); | |
console.log("Pebble JS: ready and up."); | |
ready = true; | |
if (!fetchtime||fetchtime=="undefined"||fetchtime<=0||fetchtime>180) { | |
//undefined from settings website will crash pebble | |
fetchtime = 60; //minutes | |
} | |
console.log("Pebble JS: Fetch time: " + fetchtime); | |
window.setInterval(function(){ | |
if(settings.substring(13,14)=='0')return; | |
if(isActiveHour()){ | |
console.log("Pebble JS: Active hour, refreshing weather"); | |
weathersleep = false; | |
getLocationForWeather(); | |
}else if(weathersleep==false){ | |
console.log("Pebble JS: Inactive hour, putting watch to sleep"); | |
weathersleep = true; | |
Pebble.sendAppMessage({ | |
"icon":12, | |
"temperature":" --"}); | |
}else{ | |
console.log("Pebble JS: Inactive hour, watch sleeping"); | |
} | |
}, 60000*fetchtime); | |
//getLocationForWeather(); | |
}); | |
Pebble.addEventListener("appmessage", | |
function(e) { | |
console.log("Pebble JS: got message!"); | |
}); | |
Pebble.addEventListener("showConfiguration", function() { | |
console.log("Pebble JS: showing configuration"); | |
Pebble.openURL(encodeURI("http://zalew.net.pl/pebble/modern311.php?&settings=" + settings + "&longitude=" + manuallongitude + "&latitude=" + manuallatitude + "&location=" + manuallocation + "&fetchtime=" + fetchtime)); | |
}); | |
Pebble.addEventListener("webviewclosed", function(e) { | |
console.log("Pebble JS: configuration closed"); | |
var configuration = JSON.parse(e.response); | |
//Pebble.sendAppMessage(configuration); | |
settings = configuration["settings"]; | |
Pebble.sendAppMessage({"settings":translateForPebble()}); | |
manuallongitude = configuration["longitude"]; | |
manuallatitude = configuration["latitude"]; | |
manuallocation = configuration["location"]; | |
fetchtime = configuration["fetchtime"]; | |
localStorage.setItem("modernsettings", settings); | |
localStorage.setItem("modernlongitude", manuallongitude); | |
localStorage.setItem("modernlatitude", manuallatitude); | |
localStorage.setItem("modernlocation", manuallocation); | |
localStorage.setItem("modernfetchtime", fetchtime); | |
console.log("Pebble JS: new configuration is: " + settings); | |
console.log("Pebble JS: new location is: " + manuallongitude + "," + manuallatitude + ", " + manuallocation); | |
}); | |
function translateForPebble(){ | |
var result = 0; | |
if(settings.substring(0,1)=='1'){ | |
result += Math.pow(2,31); | |
} | |
if(settings.substring(1,2)=='1'){ | |
result += Math.pow(2,30); | |
} | |
var tmp = parseInt(settings.substring(2,4), 10).toString(2); | |
//console.log("Pebble JS: " + parseInt(settings.substring(2,4), 10) + " tobits: " + tmp); | |
for(var i = tmp.length-1; i>=0; i--){ | |
if(tmp[i]==1){ | |
result += Math.pow(2,25+(5-tmp.length)+i); | |
} | |
} | |
if(settings.substring(4,5)=='1'){ | |
result += Math.pow(2,24); | |
} | |
tmp = parseInt(settings.substring(5,7), 10).toString(2); | |
//console.log("Pebble JS: " + parseInt(settings.substring(5,7), 10) + " tobits: " + tmp); | |
for(var i = tmp.length-1; i>=0; i--){ | |
if(tmp[i]==1){ | |
result += Math.pow(2,19+(5-tmp.length)+i); | |
} | |
} | |
tmp = parseInt(settings.substring(7,9), 10).toString(2); | |
//console.log("Pebble JS: " + parseInt(settings.substring(7,9), 10) + " tobits: " + tmp); | |
for(var i = tmp.length-1; i>=0; i--){ | |
if(tmp[i]==1){ | |
result += Math.pow(2,14+(5-tmp.length)+i); | |
} | |
} | |
tmp = parseInt(settings.substring(9,10), 10).toString(2); | |
//console.log("Pebble JS: " + parseInt(settings.substring(9,10), 10) + " tobits: " + tmp); | |
for(var i = tmp.length-1; i>=0; i--){ | |
if(tmp[i]==1){ | |
result += Math.pow(2,11+(3-tmp.length)+i); | |
} | |
} | |
if(settings.substring(10,11)=='1'){ | |
result += Math.pow(2,10); | |
} | |
if(settings.substring(11,12)=='1'){ | |
result += Math.pow(2,9); | |
} | |
tmp = parseInt(settings.substring(12,13), 10).toString(2); | |
//console.log("Pebble JS: " + parseInt(settings.substring(12,13), 10) + " tobits: " + tmp); | |
for(var i = tmp.length-1; i>=0; i--){ | |
if(tmp[i]==1){ | |
result += Math.pow(2,6+(3-tmp.length)+i); | |
} | |
} | |
if(settings.substring(13,14)=='1'){ | |
result += Math.pow(2,5); | |
} | |
if(settings.substring(14,15)=='1'){ | |
result += Math.pow(2,4); | |
} | |
if(settings.substring(15,16)=='1'){ | |
result += Math.pow(2,3); | |
} | |
if(settings.substring(16,17)=='1'){ | |
result += Math.pow(2,2); | |
} | |
if(settings.substring(17,18)=='1'){ | |
result += Math.pow(2,1); | |
} | |
if(settings.substring(18,19)=='1'){ | |
result += Math.pow(2,0); | |
} | |
console.log("Pebble JS: translated settings(" + settings + "): " + result); | |
return result; | |
} | |
function isActiveHour() { | |
var currentdate = new Date(); | |
var hour = currentdate.getHours(); | |
var activestart = parseInt(settings.substring(5,7), 10); | |
var activeend = parseInt(settings.substring(7,9), 10); | |
if(activestart==activeend){ | |
//console.log(activestart + "=="+ activeend); | |
//24h active | |
return true; | |
} | |
if(activestart>activeend){ | |
if(hour>=activestart-1||hour<=activeend-1){ | |
//console.log(hour + ">=" + activestart+ "-1||" + hour + "<=" + activeend + "-1"); | |
return true; | |
} | |
}else if(hour>=activestart-1&&hour<=activeend-1){ | |
//console.log(hour + ">=" + activestart+ "-1&&" + hour + "<=" + activeend + "-1"); | |
return true; | |
} | |
return false; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment