weather: redraw clock_info on update and provide color field
parent
705a5d7a1b
commit
0cc4e318f8
|
|
@ -20,3 +20,4 @@
|
||||||
0.21: Updated clkinfo icon.
|
0.21: Updated clkinfo icon.
|
||||||
0.22: Automatic translation of strings, some left untranslated.
|
0.22: Automatic translation of strings, some left untranslated.
|
||||||
0.23: Update clock_info to avoid a redraw
|
0.23: Update clock_info to avoid a redraw
|
||||||
|
0.24: Redraw clock_info on update and provide color field for condition
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,36 @@
|
||||||
(function() {
|
(function() {
|
||||||
var weather = {
|
var weather;
|
||||||
temp: "?",
|
var weatherLib = require("weather");
|
||||||
hum: "?",
|
|
||||||
wind: "?",
|
|
||||||
txt: "?",
|
|
||||||
};
|
|
||||||
|
|
||||||
var weatherJson = require("Storage").readJSON('weather.json');
|
function updateWeather() {
|
||||||
if(weatherJson !== undefined && weatherJson.weather !== undefined){
|
weather = weatherLib.get();
|
||||||
weather = weatherJson.weather;
|
if(weather){
|
||||||
weather.temp = require("locale").temp(weather.temp-273.15);
|
weather.temp = require("locale").temp(weather.temp-273.15);
|
||||||
weather.hum = weather.hum + "%";
|
weather.hum = weather.hum + "%";
|
||||||
weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/);
|
weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/);
|
||||||
weather.wind = Math.round(weather.wind[1]) + "kph";
|
weather.wind = Math.round(weather.wind[1]) + "kph";
|
||||||
|
} else {
|
||||||
|
weather = {
|
||||||
|
temp: "?",
|
||||||
|
hum: "?",
|
||||||
|
wind: "?",
|
||||||
|
txt: "?",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
updateWeather();
|
||||||
|
|
||||||
function weatherIcon(code) {
|
function weatherIcon(code) {
|
||||||
var ovr = Graphics.createArrayBuffer(24,24,1,{msb:true});
|
var ovr = Graphics.createArrayBuffer(24,24,1,{msb:true});
|
||||||
require("weather").drawIcon({code:code},12,12,12,ovr);
|
weatherLib.drawIcon({code:code},12,12,12,ovr);
|
||||||
var img = ovr.asImage();
|
var img = ovr.asImage();
|
||||||
img.transparent = 0;
|
img.transparent = 0;
|
||||||
//for (var i=0;i<img.buffer.length;i++) img.buffer[i]^=255;
|
|
||||||
return img;
|
return img;
|
||||||
//g.setColor("#0ff").drawImage(img, 42, 42);
|
}
|
||||||
|
|
||||||
|
function _updater() {
|
||||||
|
updateWeather();
|
||||||
|
this.emit("redraw");
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME ranges are somehow arbitrary
|
//FIXME ranges are somehow arbitrary
|
||||||
|
|
@ -31,42 +39,61 @@
|
||||||
img: atob("GBiBAABAAARGAAYEAADgACP4wDf8gAf+AA/+AE/4AG/jwA/v4A8P8AR/8DH/8AH//AP//g///g///g///gf//AAAAABkwABMgABMgA=="),
|
img: atob("GBiBAABAAARGAAYEAADgACP4wDf8gAf+AA/+AE/4AG/jwA/v4A8P8AR/8DH/8AH//AP//g///g///g///gf//AAAAABkwABMgABMgA=="),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
name: "conditionWithTemperature",
|
//TODO get this configurable
|
||||||
|
name: "conditionWithData",
|
||||||
|
hasRange : true,
|
||||||
get: () => ({ text: weather.temp, img: weatherIcon(weather.code),
|
get: () => ({ text: weather.temp, img: weatherIcon(weather.code),
|
||||||
|
color: weatherLib.getColor(weather.code),
|
||||||
v: parseInt(weather.temp), min: -30, max: 55}),
|
v: parseInt(weather.temp), min: -30, max: 55}),
|
||||||
show: function() {},
|
show: function() {
|
||||||
hide: function () {}
|
this.updater = _updater.bind(this);
|
||||||
|
weatherLib.on("update", this.updater);
|
||||||
|
},
|
||||||
|
hide: function () { weatherLib.removeListener("update", this.updater); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "condition",
|
name: "condition",
|
||||||
get: () => ({ text: weather.txt, img: weatherIcon(weather.code),
|
get: () => ({ text: weather.txt, img: weatherIcon(weather.code),
|
||||||
|
color: weatherLib.getColor(weather.code),
|
||||||
v: weather.code}),
|
v: weather.code}),
|
||||||
show: function() {},
|
show: function() {
|
||||||
hide: function () {}
|
this.updater = _updater.bind(this);
|
||||||
|
weatherLib.on("update", this.updater);
|
||||||
|
},
|
||||||
|
hide: function () { weatherLib.removeListener("update", this.updater); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "temperature",
|
name: "temperature",
|
||||||
hasRange : true,
|
hasRange : true,
|
||||||
get: () => ({ text: weather.temp, img: atob("GBiBAAA8AAB+AADnAADDAADDAADDAADDAADDAADbAADbAADbAADbAADbAADbAAHbgAGZgAM8wAN+wAN+wAM8wAGZgAHDgAD/AAA8AA=="),
|
get: () => ({ text: weather.temp, img: atob("GBiBAAA8AAB+AADnAADDAADDAADDAADDAADDAADbAADbAADbAADbAADbAADbAAHbgAGZgAM8wAN+wAN+wAM8wAGZgAHDgAD/AAA8AA=="),
|
||||||
v: parseInt(weather.temp), min: -30, max: 55}),
|
v: parseInt(weather.temp), min: -30, max: 55}),
|
||||||
show: function() {},
|
show: function() {
|
||||||
hide: function () {}
|
this.updater = _updater.bind(this);
|
||||||
|
weatherLib.on("update", this.updater);
|
||||||
|
},
|
||||||
|
hide: function () { weatherLib.removeListener("update", this.updater); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "humidity",
|
name: "humidity",
|
||||||
hasRange : true,
|
hasRange : true,
|
||||||
get: () => ({ text: weather.hum, img: atob("GBiBAAAEAAAMAAAOAAAfAAAfAAA/gAA/gAI/gAY/AAcfAA+AQA+A4B/A4D/B8D/h+D/j+H/n/D/n/D/n/B/H/A+H/AAH/AAD+AAA8A=="),
|
get: () => ({ text: weather.hum, img: atob("GBiBAAAEAAAMAAAOAAAfAAAfAAA/gAA/gAI/gAY/AAcfAA+AQA+A4B/A4D/B8D/h+D/j+H/n/D/n/D/n/B/H/A+H/AAH/AAD+AAA8A=="),
|
||||||
v: parseInt(weather.hum), min: 0, max: 100}),
|
v: parseInt(weather.hum), min: 0, max: 100}),
|
||||||
show: function() {},
|
show: function() {
|
||||||
hide: function () {}
|
this.updater = _updater.bind(this);
|
||||||
|
weatherLib.on("update", this.updater);
|
||||||
|
},
|
||||||
|
hide: function () { weatherLib.removeListener("update", this.updater); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "wind",
|
name: "wind",
|
||||||
hasRange : true,
|
hasRange : true,
|
||||||
get: () => ({ text: weather.wind, img: atob("GBiBAAHgAAPwAAYYAAwYAAwMfAAY/gAZh3/xg//hgwAAAwAABg///g//+AAAAAAAAP//wH//4AAAMAAAMAAYMAAYMAAMcAAP4AADwA=="),
|
get: () => ({ text: weather.wind, img: atob("GBiBAAHgAAPwAAYYAAwYAAwMfAAY/gAZh3/xg//hgwAAAwAABg///g//+AAAAAAAAP//wH//4AAAMAAAMAAYMAAYMAAMcAAP4AADwA=="),
|
||||||
v: parseInt(weather.wind), min: 0, max: 118}),
|
v: parseInt(weather.wind), min: 0, max: 118}),
|
||||||
show: function() {},
|
show: function() {
|
||||||
hide: function () {}
|
this.updater = _updater.bind(this);
|
||||||
|
weatherLib.on("update", this.updater);
|
||||||
|
},
|
||||||
|
hide: function () { weatherLib.removeListener("update", this.updater); }
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,98 @@ exports.get = function() {
|
||||||
|
|
||||||
scheduleExpiry(storage.readJSON('weather.json')||{});
|
scheduleExpiry(storage.readJSON('weather.json')||{});
|
||||||
|
|
||||||
|
function getPalette(monochrome, ovr) {
|
||||||
|
var palette;
|
||||||
|
if(monochrome) {
|
||||||
|
palette = {
|
||||||
|
sun: '#FFF',
|
||||||
|
cloud: '#FFF',
|
||||||
|
bgCloud: '#FFF',
|
||||||
|
rain: '#FFF',
|
||||||
|
lightning: '#FFF',
|
||||||
|
snow: '#FFF',
|
||||||
|
mist: '#FFF',
|
||||||
|
background: '#000'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (B2) {
|
||||||
|
if (ovr.theme.dark) {
|
||||||
|
palette = {
|
||||||
|
sun: '#FF0',
|
||||||
|
cloud: '#FFF',
|
||||||
|
bgCloud: '#777', // dithers on B2, but that's ok
|
||||||
|
rain: '#0FF',
|
||||||
|
lightning: '#FF0',
|
||||||
|
snow: '#FFF',
|
||||||
|
mist: '#FFF'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
palette = {
|
||||||
|
sun: '#FF0',
|
||||||
|
cloud: '#777', // dithers on B2, but that's ok
|
||||||
|
bgCloud: '#000',
|
||||||
|
rain: '#00F',
|
||||||
|
lightning: '#FF0',
|
||||||
|
snow: '#0FF',
|
||||||
|
mist: '#0FF'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ovr.theme.dark) {
|
||||||
|
palette = {
|
||||||
|
sun: '#FE0',
|
||||||
|
cloud: '#BBB',
|
||||||
|
bgCloud: '#777',
|
||||||
|
rain: '#0CF',
|
||||||
|
lightning: '#FE0',
|
||||||
|
snow: '#FFF',
|
||||||
|
mist: '#FFF'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
palette = {
|
||||||
|
sun: '#FC0',
|
||||||
|
cloud: '#000',
|
||||||
|
bgCloud: '#777',
|
||||||
|
rain: '#07F',
|
||||||
|
lightning: '#FC0',
|
||||||
|
snow: '#CCC',
|
||||||
|
mist: '#CCC'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getColor = function(code) {
|
||||||
|
const codeGroup = Math.round(code / 100);
|
||||||
|
const palette = getPalette(0, g);
|
||||||
|
const cloud = g.blendColor(palette.cloud, palette.bgCloud, .5); //theme independent
|
||||||
|
switch (codeGroup) {
|
||||||
|
case 2: return g.blendColor(cloud, palette.lightning, .5);
|
||||||
|
case 3: return palette.rain;
|
||||||
|
case 5:
|
||||||
|
switch (code) {
|
||||||
|
case 511: return palette.snow;
|
||||||
|
case 520: return g.blendColor(palette.rain, palette.sun, .5);
|
||||||
|
case 521: return g.blendColor(palette.rain, palette.sun, .5);
|
||||||
|
case 522: return g.blendColor(palette.rain, palette.sun, .5);
|
||||||
|
case 531: return g.blendColor(palette.rain, palette.sun, .5);
|
||||||
|
default: return palette.rain;
|
||||||
|
}
|
||||||
|
case 6: return palette.snow;
|
||||||
|
case 7: return palette.mist;
|
||||||
|
case 8:
|
||||||
|
switch (code) {
|
||||||
|
case 800: return palette.sun;
|
||||||
|
case 801: return palette.sun;
|
||||||
|
case 802: return cloud;
|
||||||
|
default: return cloud;
|
||||||
|
}
|
||||||
|
default: return cloud;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param cond Weather condition, as one of:
|
* @param cond Weather condition, as one of:
|
||||||
|
|
@ -71,63 +163,8 @@ exports.drawIcon = function(cond, x, y, r, ovr) {
|
||||||
ovr = g;
|
ovr = g;
|
||||||
monochrome=0;
|
monochrome=0;
|
||||||
}
|
}
|
||||||
if(monochrome) {
|
|
||||||
palette = {
|
palette = getPalette(monochrome, ovr);
|
||||||
sun: '#FFF',
|
|
||||||
cloud: '#FFF',
|
|
||||||
bgCloud: '#FFF',
|
|
||||||
rain: '#FFF',
|
|
||||||
lightning: '#FFF',
|
|
||||||
snow: '#FFF',
|
|
||||||
mist: '#FFF',
|
|
||||||
background: '#000'
|
|
||||||
};
|
|
||||||
} else
|
|
||||||
if (B2) {
|
|
||||||
if (ovr.theme.dark) {
|
|
||||||
palette = {
|
|
||||||
sun: '#FF0',
|
|
||||||
cloud: '#FFF',
|
|
||||||
bgCloud: '#777', // dithers on B2, but that's ok
|
|
||||||
rain: '#0FF',
|
|
||||||
lightning: '#FF0',
|
|
||||||
snow: '#FFF',
|
|
||||||
mist: '#FFF'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
palette = {
|
|
||||||
sun: '#FF0',
|
|
||||||
cloud: '#777', // dithers on B2, but that's ok
|
|
||||||
bgCloud: '#000',
|
|
||||||
rain: '#00F',
|
|
||||||
lightning: '#FF0',
|
|
||||||
snow: '#0FF',
|
|
||||||
mist: '#0FF'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ovr.theme.dark) {
|
|
||||||
palette = {
|
|
||||||
sun: '#FE0',
|
|
||||||
cloud: '#BBB',
|
|
||||||
bgCloud: '#777',
|
|
||||||
rain: '#0CF',
|
|
||||||
lightning: '#FE0',
|
|
||||||
snow: '#FFF',
|
|
||||||
mist: '#FFF'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
palette = {
|
|
||||||
sun: '#FC0',
|
|
||||||
cloud: '#000',
|
|
||||||
bgCloud: '#777',
|
|
||||||
rain: '#07F',
|
|
||||||
lightning: '#FC0',
|
|
||||||
snow: '#CCC',
|
|
||||||
mist: '#CCC'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawSun(x, y, r) {
|
function drawSun(x, y, r) {
|
||||||
ovr.setColor(palette.sun);
|
ovr.setColor(palette.sun);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "weather",
|
"id": "weather",
|
||||||
"name": "Weather",
|
"name": "Weather",
|
||||||
"version": "0.23",
|
"version": "0.24",
|
||||||
"description": "Show Gadgetbridge weather report",
|
"description": "Show Gadgetbridge weather report",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,9 @@ Note that each item is an object with:
|
||||||
|
|
||||||
{
|
{
|
||||||
'text' // the text to display for this item
|
'text' // the text to display for this item
|
||||||
'short' : (optional) a shorter text to display for this item (at most 6 characters)
|
'short' // optional: a shorter text to display for this item (at most 6 characters)
|
||||||
'img' // optional: a 24x24px image to display for this item
|
'img' // optional: a 24x24px image to display for this item
|
||||||
|
'color' // optional: a color string (like "#ffffff") to color the icon in compatible clocks
|
||||||
'v' // (if hasRange==true) a numerical value
|
'v' // (if hasRange==true) a numerical value
|
||||||
'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
|
'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue