mirror of https://github.com/espruino/BangleApps
Merge pull request #1856 from idavydov/dino
watch face with dino (t-rex from chrome) and weatherpull/1857/head^2
commit
134a480764
|
@ -0,0 +1,17 @@
|
|||
# dinoClock
|
||||
|
||||
Watchface with T-Rex Dinosaur from Chrome.
|
||||
It displays current temperature and weather.
|
||||
|
||||
**Warning**: Element position and styles can change in the future.
|
||||
|
||||
Based on the [Weather Clock](https://github.com/espruino/BangleApps/tree/master/apps/weatherClock).
|
||||
|
||||
# Requirements
|
||||
|
||||
**This clock requires Gadgetbridge and the weather app in order to get weather data!**
|
||||
|
||||
See the [Bangle.js Gadgetbridge documentation](https://www.espruino.com/Gadgetbridge) for instructions on setting up Gadgetbridge and weather.
|
||||
|
||||

|
||||
|
|
@ -0,0 +1,219 @@
|
|||
const storage = require('Storage');
|
||||
const locale = require("locale");
|
||||
|
||||
|
||||
|
||||
|
||||
// add modifiied 4x5 numeric font
|
||||
(function(graphics) {
|
||||
graphics.prototype.setFont4x5NumPretty = function() {
|
||||
this.setFontCustom(atob("IQAQDJgH4/An4QXr0Fa/BwnwdrcH63BCHwfr8Ha/"),45,atob("AwIEBAQEBAQEBAQEBA=="),5);
|
||||
};
|
||||
})(Graphics);
|
||||
|
||||
// add font for days of the week
|
||||
(function(graphics) {
|
||||
graphics.prototype.setFontDoW = function() {
|
||||
this.setFontCustom(atob("///////ADgB//////+AHAD//////gAAAH//////4D8B+A///////4AcAOAH//////4AcAOAAAAAB//////wA4AcAP//////wAAAAAAAA//////4AcAP//////wA4Af//////gAAAH//////5z85+c/OfnOAA4AcAOAH//////4AcAOAAAAAB//////wcAOAHB//////wAAAAAAAA///////ODnBzg5wc4AAAAD//////84OcH//8/+fAAAAAAAAAAAAA/z/5/8/OfnPz/5/8/wAAAD//////84OcH//////AAAAAAAAAAAAA/z/5/8/OfnPz/5/8/wAAAD//////gBwA///////AAAAAAAAAAAAA"),48,24,13);
|
||||
};
|
||||
})(Graphics);
|
||||
|
||||
|
||||
const SUN = 1;
|
||||
const PART_SUN = 2;
|
||||
const CLOUD = 3;
|
||||
const SNOW = 4;
|
||||
const RAIN = 5;
|
||||
const STORM = 6;
|
||||
const ERR = 7;
|
||||
|
||||
/**
|
||||
Choose weather icon based on weather const
|
||||
Weather icons from https://icons8.com/icon/set/weather/ios-glyphs
|
||||
Error icon from https://icons8.com/icon/set/error-cloud/ios-glyphs
|
||||
**/
|
||||
function weatherIcon(weather) {
|
||||
switch (weather) {
|
||||
case SUN:
|
||||
return atob("Hh4BAAAAAAAMAAAAMAAAAMAAAAMAABgMBgBwADgA4AHAAY/GAAB/gAAD/wAAH/4AAP/8AAP/8AfP/8+fP/8+AP/8AAP/8AAH/4AAD/wAAB/gAAY/GAA4AHABwADgBgMBgAAMAAAAMAAAAMAAAAMAAAAAAAA=");
|
||||
case PART_SUN:
|
||||
return atob("Hh4BAAAAAAAAAAAMAAAAMAAAEMIAAOAcAAGAYAAAeAAAA/AAAB/gAA5/gAA5/g+AB+D/gA4H/wAR//wGD//4OD//4EH//4AH//4Af//+Af//+A////A////A////A///+Af//+AH//4AAAAAAAAAAAAAAAA=");
|
||||
case CLOUD:
|
||||
return atob("Hh4BAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAf+AAA//AAB//gAf//gB///wB///wD///wD///wP///8f///+f///+////////////////////f///+f///+P///8D///wAAAAAAAAAAAAAAAAAAAAAAAAAA=");
|
||||
case SNOW:
|
||||
return atob("Hh4BAAAAAAAAAAAAAAAAAHwAAAf8AAA/+AAH/+AAf//AAf8/AA/8/AB/gHgH/wP4H/wP4P/gH8P/8/8P/8/8P///4H///4B///gAAAAAAMAAAAMAAAB/gGAA/AfgA/AfgB/gfgAMAfgAMAGAAAAAAAAAAAA=");
|
||||
case RAIN:
|
||||
return atob("Hh4BAAAAAAAAAAAAAAAAAHwAAAf8AAA/+AAH/+AAf//AAf//AA///AB///gH///4H///4P///8P///8P///8P///4H///4B///gAAAAAAAAAABgBgABgBgABhhhgABgBgABgBgAAAAAAAAAAAAAAAAAAAAA=");
|
||||
case STORM:
|
||||
return atob("Hh4BAAAAAAAAAAAAAAAAAHwAAAf8AAA/+AAH/+AAf//AAf//AA///AB///gH///4H/x/4P/g/8P/k/8P/E/8P/M/4H+MP4B+cHgAAfgAAA/gABg/AABgHAABgGBgAAGBgAAEBgAAEAAAAAAAAAAAAAAAAAA=");
|
||||
case ERR:
|
||||
default:
|
||||
return atob("Hh4BAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAf+AAA//AAB//gAf//gB///wB/z/wD/z/wD/z/wP/z/8f/z/+f/z/+//z//////////////z//f/z/+f///+P///8D///wAAAAAAAAAAAAAAAAAAAAAAAAAA=");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Choose weather icon to display based on condition.
|
||||
Based on function from the Bangle weather app so it should handle all of the conditions
|
||||
sent from gadget bridge.
|
||||
*/
|
||||
function chooseIcon(condition) {
|
||||
condition = condition.toLowerCase();
|
||||
if (condition.includes("thunderstorm")) return weatherIcon(STORM);
|
||||
if (condition.includes("freezing")||condition.includes("snow")||
|
||||
condition.includes("sleet")) {
|
||||
return weatherIcon(SNOW);
|
||||
}
|
||||
if (condition.includes("drizzle")||
|
||||
condition.includes("shower")) {
|
||||
return weatherIcon(RAIN);
|
||||
}
|
||||
if (condition.includes("rain")) return weatherIcon(RAIN);
|
||||
if (condition.includes("clear")) return weatherIcon(SUN);
|
||||
if (condition.includes("few clouds")) return weatherIcon(PART_SUN);
|
||||
if (condition.includes("scattered clouds")) return weatherIcon(CLOUD);
|
||||
if (condition.includes("clouds")) return weatherIcon(CLOUD);
|
||||
if (condition.includes("mist") ||
|
||||
condition.includes("smoke") ||
|
||||
condition.includes("haze") ||
|
||||
condition.includes("sand") ||
|
||||
condition.includes("dust") ||
|
||||
condition.includes("fog") ||
|
||||
condition.includes("ash") ||
|
||||
condition.includes("squalls") ||
|
||||
condition.includes("tornado")) {
|
||||
return weatherIcon(CLOUD);
|
||||
}
|
||||
return weatherIcon(CLOUD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Choose weather icon to display based on weather conditition code
|
||||
* https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2
|
||||
*/
|
||||
function chooseIconByCode(code) {
|
||||
const codeGroup = Math.round(code / 100);
|
||||
switch (codeGroup) {
|
||||
case 2: return weatherIcon(STORM);
|
||||
case 3: return weatherIcon(RAIN);
|
||||
case 5: return weatherIcon(RAIN);
|
||||
case 6: return weatherIcon(SNOW);
|
||||
case 7: return weatherIcon(CLOUD);
|
||||
case 8:
|
||||
switch (code) {
|
||||
case 800: return weatherIcon(SUN);
|
||||
case 801: return weatherIcon(PART_SUN);
|
||||
default: return weatherIcon(CLOUD);
|
||||
}
|
||||
default: return weatherIcon(CLOUD);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Get weather stored in json file by weather app.
|
||||
*/
|
||||
function getWeather() {
|
||||
let jsonWeather = storage.readJSON('weather.json');
|
||||
return jsonWeather;
|
||||
}
|
||||
|
||||
// timeout used to update every minute
|
||||
var drawTimeout;
|
||||
|
||||
// schedule a draw for the next minute
|
||||
function queueDraw() {
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = setTimeout(function() {
|
||||
drawTimeout = undefined;
|
||||
draw();
|
||||
},60000-(Date.now()%60000));
|
||||
}
|
||||
|
||||
// only draw the first time
|
||||
function drawBg() {
|
||||
var bgImg = require("heatshrink").decompress(atob("2E7wINKn///+AEaIVUgIUB//wCs/5CtRXrCvMD8AVTg4LFCv4VZ/iSLCrwWMCrMOAQMPCp7cBCojjFCo/xFgIVQgeHCopABCpcH44Vuh/AQQX/wAV7+F/Cq/nCsw/CCqyvRCvgODCqfAgEDCp4QCSIIVQgIOBDQgGDABX/NgIECCp8HCrM/CgP4CqKaCCqSfCCqq1BCqBuB54VqgYVG/gCECp0BwgCDCp8HgYCDCo/wCo0MgHAjACBj7rDABS1Bv4lBv4rPAAsPCo3+gbbPJAIVFiAXMFZ2AUQsAuAQHiOAgJeEA"));
|
||||
g.reset();
|
||||
g.drawImage(bgImg,0,101);
|
||||
}
|
||||
|
||||
function square(x,y,w,e) {
|
||||
g.setColor("#000").fillRect(x,y,x+w,y+w);
|
||||
g.setColor("#fff").fillRect(x+e,y+e,x+w-e,y+w-e);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
var d = new Date();
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
h = ("0"+h).substr(-2);
|
||||
m = ("0"+m).substr(-2);
|
||||
|
||||
var day = d.getDate(), mon = d.getMonth(), dow = d.getDay();
|
||||
day = ("0"+day).substr(-2);
|
||||
mon = ("0"+(mon+1)).substr(-2);
|
||||
dow = ((dow+6)%7).toString();
|
||||
date = day+"."+mon;
|
||||
|
||||
var weatherJson = getWeather();
|
||||
var wIcon;
|
||||
var temp;
|
||||
if(weatherJson && weatherJson.weather){
|
||||
var currentWeather = weatherJson.weather;
|
||||
temp = locale.temp(currentWeather.temp-273.15).match(/^(\D*\d*)(.*)$/);
|
||||
const code = currentWeather.code||-1;
|
||||
if (code > 0) {
|
||||
wIcon = chooseIconByCode(code);
|
||||
} else {
|
||||
wIcon = chooseIcon(currentWeather.txt);
|
||||
}
|
||||
}else{
|
||||
temp = "";
|
||||
wIcon = weatherIcon(ERR);
|
||||
}
|
||||
g.reset();
|
||||
g.clearRect(22,35,153,75);
|
||||
g.setFont("4x5NumPretty",8);
|
||||
g.fillRect(84,42,92,49);
|
||||
g.fillRect(84,60,92,67);
|
||||
g.drawString(h,22,35);
|
||||
g.drawString(m,98,35);
|
||||
|
||||
g.clearRect(22,95,22+4*2*4+2*4,95+2*5);
|
||||
g.setFont("4x5NumPretty",2);
|
||||
g.drawString(date,22,95);
|
||||
|
||||
g.clearRect(22,79,22+24,79+13);
|
||||
g.setFont("DoW");
|
||||
g.drawString(dow,22,79);
|
||||
|
||||
g.drawImage(wIcon,126,81);
|
||||
|
||||
g.clearRect(108,114,176,114+4*5);
|
||||
if (temp != "") {
|
||||
var tempWidth;
|
||||
const mid=126+15;
|
||||
if (temp[1][0]=="-") {
|
||||
// do not account for - when aligning
|
||||
const minusWidth=3*4;
|
||||
tempWidth = minusWidth+(temp[1].length-1)*4*4;
|
||||
x = mid-Math.round((tempWidth-minusWidth)/2)-minusWidth;
|
||||
} else {
|
||||
tempWidth = temp[1].length*4*4;
|
||||
x = mid-Math.round(tempWidth/2);
|
||||
}
|
||||
g.setFont("4x5NumPretty",4);
|
||||
g.drawString(temp[1],x,114);
|
||||
square(x+tempWidth,114,6,2);
|
||||
}
|
||||
|
||||
// queue draw in one minute
|
||||
queueDraw();
|
||||
}
|
||||
|
||||
g.clear();
|
||||
drawBg();
|
||||
Bangle.setUI("clock"); // Show launcher when middle button pressed
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
draw();
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwgJC/AAVh/E/hgFC/O/AoMB8EZwc8AoUYgYFBgFgjAXDAowXBAo8B/ARBn4FGAAsBmAFE2ADBhwFEj4VEn+AgPvAontgfwv+ABIMCMwIVCgf4FIWAAoN3sAFCwERoEB0MHwF3gEF0MPwFEAoW/4ALD/4tCg/hAoYhB/5ZDwF+Aok0gEIkEf/4AB8eMBoM2bkw="))
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"id": "dinoClock",
|
||||
"name": "Dino Clock",
|
||||
"description": "Clock with dino from Chrome",
|
||||
"screenshots": [{"url":"screens/screen1.png"}],
|
||||
"icon": "app.png",
|
||||
"version": "0.01",
|
||||
"type": "clock",
|
||||
"tags": "clock, weather, dino, trex, chrome",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"dinoClock.app.js","url":"app.js"},
|
||||
{"name":"dinoClock.img","url":"icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in New Issue