Initial commit
BIN
app/.DS_Store
vendored
Normal file
3
app/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
# Ignore build generated files
|
||||
build
|
||||
8
app/.lock-waf_darwin_build
Normal file
@@ -0,0 +1,8 @@
|
||||
argv = ['/Users/dan/pebble-dev/PebbleSDK-2.0.2/Pebble/waf', 'configure', 'build']
|
||||
environ = {'TERM_SESSION_ID': '0E771BB8-6D47-41B3-A896-1B67A6BC492D', 'SSH_AUTH_SOCK': '/tmp/launch-mBweRR/Listeners', 'PYTHONPATH': '/Users/dan/pebble-dev/PebbleSDK-current/bin/../.env/lib/python2.7/site-packages', 'VERSIONER_PYTHON_PREFER_32_BIT': 'no', 'TERM_PROGRAM_VERSION': '326', 'SHELL': '/bin/bash', 'LOGNAME': 'dan', 'USER': 'dan', 'HOME': '/Users/dan', 'PATH': '/Users/dan/pebble-dev/PebbleSDK-2.0.2/arm-cs-tools/bin:/Users/dan/pebble-dev/PebbleSDK-current/bin:/Applications/Android Studio.app/sdk/tools/:/Applications/Android Studio.app/sdk/platform-tools/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin', 'DISPLAY': '/tmp/launch-FHtlTI/org.macosforge.xquartz:0', 'TMPDIR': '/var/folders/5l/h8wjt5t52cs2n6h7zcd3kw040000gn/T/', 'TERM_PROGRAM': 'Apple_Terminal', 'LANG': 'en_GB.UTF-8', 'TERM': 'xterm-256color', 'Apple_PubSub_Socket_Render': '/tmp/launch-BrNYWU/Render', 'VERSIONER_PYTHON_VERSION': '2.7', 'SHLVL': '2', '__CF_USER_TEXT_ENCODING': '0x1F5:0:0', 'PWD': '/Users/dan/Workspace/minewatch/app', '_': '/Users/dan/pebble-dev/PebbleSDK-2.0.2/Pebble/waf', '__CHECKFIX1436934': '1'}
|
||||
files = ['/Users/dan/Workspace/minewatch/app/wscript']
|
||||
hash = 4672844372416070989
|
||||
options = {'files': '', 'jobs': 4, 'verbose': 0, 'nocache': False, 'progress_bar': 0, 'timestamp': None, 'distcheck_args': None, 'top': '', 'destdir': '', 'keep': 0, 'zones': '', 'debug': False, 'prefix': '/usr/local/', 'download': False, 'force': False, 'targets': '', 'out': ''}
|
||||
out_dir = '/Users/dan/Workspace/minewatch/app/build'
|
||||
run_dir = '/Users/dan/Workspace/minewatch/app'
|
||||
top_dir = '/Users/dan/Workspace/minewatch/app'
|
||||
8
app/.lock-waf_linux2_build
Normal file
@@ -0,0 +1,8 @@
|
||||
argv = ['/home/dan/.pebble/PebbleSDK-2.0.2/Pebble/waf', 'configure', 'build']
|
||||
environ = {'WINDOWID': '14691935', 'QT4_IM_MODULE': 'xim', 'UPSTART_EVENTS': 'started starting', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'LOGNAME': 'dan', 'USER': 'dan', 'GNOME_KEYRING_CONTROL': '/run/user/1000/keyring-W8rHM4', 'XDG_VTNR': '7', 'HOME': '/home/dan', 'DISPLAY': ':0', 'SSH_AGENT_PID': '2017', 'LANG': 'en_GB.UTF-8', 'TERM': 'xterm', 'SHELL': '/bin/bash', 'XAUTHORITY': '/var/run/gdm/auth-for-dan-YjzkAu/database', 'LANGUAGE': 'en_GB:en', 'UPSTART_INSTANCE': '', 'SHLVL': '2', 'MANDATORY_PATH': '/usr/share/gconf/gnome.mandatory.path', 'JOB': 'gnome-session', 'TEXTDOMAIN': 'im-config', 'CLUTTER_IM_MODULE': 'xim', 'WINDOWPATH': '7', 'SESSIONTYPE': 'gnome-session', 'IM_CONFIG_PHASE': '1', 'GPG_AGENT_INFO': '/run/user/1000/keyring-W8rHM4/gpg:0:1', 'SELINUX_INIT': 'YES', 'USERNAME': 'dan', 'XDG_RUNTIME_DIR': '/run/user/1000', 'GTK_IM_MODULE': 'ibus', 'PYTHONPATH': '/home/dan/.pebble/PebbleSDK-latest/bin/../.env/lib/python2.7/site-packages', 'SSH_AUTH_SOCK': '/run/user/1000/keyring-W8rHM4/ssh', 'VTE_VERSION': '3409', 'PATH': '/home/dan/.pebble/PebbleSDK-2.0.2/arm-cs-tools/bin:~/.pebble/PebbleSDK-latest/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games', 'XMODIFIERS': '@im=ibus', 'UPSTART_JOB': 'gnome-settings-daemon', 'TEXTDOMAINDIR': '/usr/share/locale/', 'XDG_DATA_DIRS': '/usr/share/gnome:/usr/local/share/:/usr/share/', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-gnome:/usr/share/upstart/xdg:/etc/xdg', 'XDG_CURRENT_DESKTOP': 'GNOME', 'XDG_SESSION_ID': 'c2', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-CFMqNkTPMx', '_': '/home/dan/.pebble/PebbleSDK-latest/bin/pebble', 'DEFAULTS_PATH': '/usr/share/gconf/gnome.default.path', 'GDMSESSION': 'gnome', 'DESKTOP_SESSION': 'gnome', 'UPSTART_SESSION': 'unix:abstract=/com/ubuntu/upstart-session/1000/1934', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'GNOME_KEYRING_PID': '1928', 'GDM_LANG': 'en_GB', 'NODE_PATH': '/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript', 'INSTANCE': 'GNOME', 'PWD': '/home/dan/Workspace/minewatch/app', 'SSH_AGENT_LAUNCHER': 'upstart', 'COLORTERM': 'gnome-terminal', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'XDG_SEAT': 'seat0'}
|
||||
files = ['/home/dan/Workspace/minewatch/app/wscript']
|
||||
hash = 4672844372416070989
|
||||
options = {'files': '', 'jobs': 4, 'verbose': 0, 'nocache': False, 'progress_bar': 0, 'timestamp': None, 'distcheck_args': None, 'top': '', 'destdir': '', 'keep': 0, 'zones': '', 'debug': False, 'prefix': '/usr/local/', 'download': False, 'force': False, 'targets': '', 'out': ''}
|
||||
out_dir = '/home/dan/Workspace/minewatch/app/build'
|
||||
run_dir = '/home/dan/Workspace/minewatch/app'
|
||||
top_dir = '/home/dan/Workspace/minewatch/app'
|
||||
98
app/appinfo.json
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"uuid": "f49639f7-0d74-4501-b629-bea307bdf4e9",
|
||||
"shortName": "MineWatch",
|
||||
"longName": "MineWatch",
|
||||
"companyName": "Daniel Head",
|
||||
"versionCode": 1,
|
||||
"versionLabel": "1.0.0",
|
||||
"watchapp": {
|
||||
"watchface": true
|
||||
},
|
||||
"capabilities": [ "configurable" ],
|
||||
"appKeys": {
|
||||
"response":1,
|
||||
"update":2,
|
||||
"dark":3,
|
||||
"notify":4,
|
||||
"flick":5,
|
||||
"workers": 10,
|
||||
"hashrate": 11,
|
||||
"lastshare": 12,
|
||||
"reward": 13,
|
||||
"sendprogress": 14
|
||||
},
|
||||
"resources": {
|
||||
"media": [
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_WORKER",
|
||||
"file":"icons/worker.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_GRAPH",
|
||||
"file":"icons/graph.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_CLOCK",
|
||||
"file":"icons/clock.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BTC",
|
||||
"file":"icons/btc.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BLUETOOTH",
|
||||
"file":"icons/bluetooth.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_0",
|
||||
"file":"icons/battery_0.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_20",
|
||||
"file":"icons/battery_20.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_40",
|
||||
"file":"icons/battery_40.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_60",
|
||||
"file":"icons/battery_60.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_80",
|
||||
"file":"icons/battery_80.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_100",
|
||||
"file":"icons/battery_100.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_BATTERY_CHARGING",
|
||||
"file":"icons/battery_charging.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_REFRESH",
|
||||
"file":"icons/refresh.png"
|
||||
},
|
||||
{
|
||||
"type":"png",
|
||||
"name":"ICON_REFRESH_FAIL",
|
||||
"file":"icons/refresh_fail.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
2
app/conf
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
rsync -a -e ssh config colony.danielhead.com:/var/www/minewatch/ --progress
|
||||
BIN
app/resources/.DS_Store
vendored
Normal file
BIN
app/resources/icons/battery.xcf
Normal file
BIN
app/resources/icons/battery_0.png
Normal file
|
After Width: | Height: | Size: 206 B |
BIN
app/resources/icons/battery_100.png
Normal file
|
After Width: | Height: | Size: 219 B |
BIN
app/resources/icons/battery_20.png
Normal file
|
After Width: | Height: | Size: 215 B |
BIN
app/resources/icons/battery_40.png
Normal file
|
After Width: | Height: | Size: 218 B |
BIN
app/resources/icons/battery_60.png
Normal file
|
After Width: | Height: | Size: 219 B |
BIN
app/resources/icons/battery_80.png
Normal file
|
After Width: | Height: | Size: 221 B |
BIN
app/resources/icons/battery_charging.png
Normal file
|
After Width: | Height: | Size: 237 B |
BIN
app/resources/icons/bluetooth.png
Normal file
|
After Width: | Height: | Size: 197 B |
BIN
app/resources/icons/btc.png
Normal file
|
After Width: | Height: | Size: 189 B |
BIN
app/resources/icons/clock.png
Normal file
|
After Width: | Height: | Size: 196 B |
BIN
app/resources/icons/graph.png
Normal file
|
After Width: | Height: | Size: 213 B |
BIN
app/resources/icons/refresh.png
Normal file
|
After Width: | Height: | Size: 217 B |
BIN
app/resources/icons/refresh_fail.png
Normal file
|
After Width: | Height: | Size: 231 B |
BIN
app/resources/icons/worker.png
Normal file
|
After Width: | Height: | Size: 204 B |
BIN
app/resources/promo.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
app/resources/promo.xcf
Normal file
BIN
app/resources/red_pebble.xcf
Normal file
154
app/src/js/pebble-js-app.js
Normal file
@@ -0,0 +1,154 @@
|
||||
var config = {
|
||||
"dark":((localStorage.getItem("dark") == "true")?true:false),
|
||||
"notify":((localStorage.getItem("notify") == "true")?true:false),
|
||||
"flick":((localStorage.getItem("flick") == "true")?true:false),
|
||||
"apikey":(localStorage.getItem("apikey") || ""),
|
||||
"update":(localStorage.getItem("update") || "15")
|
||||
};
|
||||
|
||||
var formatHashrate = function(a) {
|
||||
var val = Math.abs(a).toFixed(0);
|
||||
var suffix = "MH/s";
|
||||
if(val>9999) {
|
||||
val = (val/1000).toFixed(0);
|
||||
suffix = "GH/s";
|
||||
}
|
||||
return val+suffix;
|
||||
}
|
||||
|
||||
var formatLastShare = function(a) {
|
||||
|
||||
var date = new Date(a*1000);
|
||||
var h = date.getHours(), m = date.getMinutes(), s = date.getSeconds();
|
||||
return (h<10?"0"+h:h) + ":" + (m<10?"0"+m:m) + ":" + (s<10?"0"+s:s);
|
||||
/*
|
||||
var result, suffix;
|
||||
if(a<60) {
|
||||
result = a;
|
||||
suffix = "sec";
|
||||
} else if((a/60)<60) {
|
||||
result = (a/60).toFixed(0);
|
||||
suffix = "minute";
|
||||
} else if((a/60/60)<24) {
|
||||
result = (a/60/60).toFixed(0);
|
||||
suffix = "hour";
|
||||
} else {
|
||||
result = (a/60/60/24).toFixed(0);
|
||||
suffix = "day";
|
||||
}
|
||||
if(result>1) suffix+="s";
|
||||
return result + " " + suffix;
|
||||
*/
|
||||
}
|
||||
|
||||
var calcSendProgress = function(amount,send) {
|
||||
return Math.ceil(144*(amount/send));
|
||||
}
|
||||
|
||||
var sendResponseWithUpdate = function(obj) {
|
||||
if(config.apikey == "") {
|
||||
Pebble.sendAppMessage({
|
||||
"response":"NoAPI"
|
||||
});
|
||||
return;
|
||||
}
|
||||
var req = new XMLHttpRequest();
|
||||
req.timeout = 30000;
|
||||
req.ontimeout = function() {
|
||||
if(!obj) obj = {};
|
||||
obj["response"] = "TIMEOUT";
|
||||
Pebble.sendAppMessage(obj);
|
||||
}
|
||||
req.onload = function(e) {
|
||||
if (req.readyState == 4) {
|
||||
if(req.status == 200) {
|
||||
var response = JSON.parse(req.responseText);
|
||||
if(response) {
|
||||
var workers = 0, total = 0, lastshare = 0;
|
||||
for(var i in response.workers) {
|
||||
total++;
|
||||
if(response.workers[i].alive) workers++;
|
||||
if(response.workers[i].last_share > lastshare) lastshare = response.workers[i].last_share;
|
||||
}
|
||||
|
||||
if(lastshare>0) lastshare = formatLastShare(lastshare);//((new Date().getTime()/1000).toFixed(0) - lastshare);
|
||||
else lastshare = "Unknown";
|
||||
|
||||
var reward = Math.abs(response.confirmed_reward).toFixed(4);
|
||||
var res = {
|
||||
"response":"OK",
|
||||
"workers":workers.toString(),
|
||||
"hashrate":formatHashrate(response.hashrate),
|
||||
"reward":reward.toString()+" BTC",
|
||||
"lastshare":lastshare,
|
||||
"sendprogress":calcSendProgress(reward,response.nmc_send_threshold).toString(),
|
||||
"update":config.update.toString()
|
||||
};
|
||||
if(obj) {
|
||||
for(var i in obj) {
|
||||
res[i] = obj[i];
|
||||
}
|
||||
}
|
||||
Pebble.sendAppMessage(res);
|
||||
}
|
||||
} else if(req.status == 401) {
|
||||
if(!obj) obj = {};
|
||||
obj["response"] = "InvAPI";
|
||||
Pebble.sendAppMessage(obj);
|
||||
}
|
||||
} else {
|
||||
if(!obj) obj = {};
|
||||
obj["response"] = "TIMEOUT";
|
||||
Pebble.sendAppMessage(obj);
|
||||
}
|
||||
}
|
||||
req.open('GET', "https://mining.bitcoin.cz/accounts/profile/json/" + config.apikey, true);
|
||||
req.send(null);
|
||||
}
|
||||
var getSettings = function() {
|
||||
return {
|
||||
"dark":((config.dark)?"true":"false"),
|
||||
"notify":((config.notify)?"true":"false"),
|
||||
"flick":((config.flick)?"true":"false")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Pebble.addEventListener("ready", function(e) {
|
||||
sendResponseWithUpdate(getSettings());
|
||||
});
|
||||
|
||||
Pebble.addEventListener("appmessage", function(e) {
|
||||
sendResponseWithUpdate();
|
||||
});
|
||||
Pebble.addEventListener("showConfiguration", function(e) {
|
||||
var str = "?";
|
||||
for(var i in config) {
|
||||
if(config[i] != "error") str += i + "=" + config[i] + "&";
|
||||
}
|
||||
str = str.substring(0, str.length - 1);
|
||||
Pebble.openURL("http://danielhead.com/minewatch/config" + str);
|
||||
});
|
||||
|
||||
Pebble.addEventListener("webviewclosed", function(e) {
|
||||
var c = JSON.parse(decodeURIComponent(e.response));
|
||||
if(c.reset) {
|
||||
localStorage.removeItem("apikey");
|
||||
localStorage.removeItem("update");
|
||||
localStorage.removeItem("dark");
|
||||
localStorage.removeItem("notify");
|
||||
localStorage.removeItem("flick");
|
||||
} else {
|
||||
config.apikey = c.apikey;
|
||||
localStorage.setItem("apikey",config.apikey);
|
||||
config.update = c.update;
|
||||
localStorage.setItem("update",config.update);
|
||||
config.dark = c.dark;
|
||||
localStorage.setItem("dark",config.dark);
|
||||
config.notify = c.notify;
|
||||
localStorage.setItem("notify",config.notify);
|
||||
config.flick = c.flick;
|
||||
localStorage.setItem("flick",config.flick);
|
||||
}
|
||||
sendResponseWithUpdate(getSettings());
|
||||
});
|
||||
527
app/src/minewatch.c
Normal file
@@ -0,0 +1,527 @@
|
||||
#include <pebble.h>
|
||||
|
||||
//COMMON
|
||||
static Window *window;
|
||||
static GFont font_xs, font_s, font_m, font_l;
|
||||
static InverterLayer *inverter_layer;
|
||||
|
||||
//TIME/DATE
|
||||
static TextLayer *time_layer;
|
||||
static TextLayer *date_layer;
|
||||
static char time_text[] = "--:--";
|
||||
static char date_text[] = "00 Xxxxxxxxx";
|
||||
|
||||
//REFRESH ICON
|
||||
static AppTimer *timeout_timer;
|
||||
static int timeout_length = 15000; //ms
|
||||
static BitmapLayer *refresh_layer;
|
||||
static GBitmap *refresh_icon;
|
||||
|
||||
//BLUETOOTH ICON
|
||||
static BitmapLayer *bluetooth_layer;
|
||||
static GBitmap *bluetooth_icon;
|
||||
|
||||
//BATTERY ICON
|
||||
static BitmapLayer *battery_layer;
|
||||
static GBitmap *battery_icon;
|
||||
static uint8_t battery_percentage = 110;
|
||||
|
||||
//INFO SPACE
|
||||
static TextLayer *info_layer;
|
||||
|
||||
|
||||
//BTC DATA
|
||||
static Layer *btc_parent_layer;
|
||||
static TextLayer *worker_text_layer;
|
||||
static TextLayer *hashrate_text_layer;
|
||||
static TextLayer *lastshare_text_layer;
|
||||
static TextLayer *reward_text_layer;
|
||||
static int current_workers = 0;
|
||||
|
||||
//BTC ICONS
|
||||
static BitmapLayer *worker_icon_layer;
|
||||
static GBitmap *worker_icon;
|
||||
static BitmapLayer *hashrate_icon_layer;
|
||||
static GBitmap *hashrate_icon;
|
||||
static BitmapLayer *lastshare_icon_layer;
|
||||
static GBitmap *lastshare_icon;
|
||||
static BitmapLayer *reward_icon_layer;
|
||||
static GBitmap *reward_icon;
|
||||
|
||||
//LAST UPDATE
|
||||
static TextLayer *last_update_layer;
|
||||
static char last_update_text[] = "--:--";
|
||||
|
||||
|
||||
//BTC PROGRESS BAR
|
||||
static InverterLayer *progress_layer;
|
||||
static int progress_width = 0;
|
||||
|
||||
//KEYS
|
||||
enum {
|
||||
RESPONSE = 0x1,
|
||||
UPDATE = 0x2,
|
||||
DARK = 0x3,
|
||||
NOTIFY = 0x4,
|
||||
FLICK = 0x5,
|
||||
WORKERS = 0xA,
|
||||
HASHRATE = 0xB,
|
||||
LASTSHARE = 0xC,
|
||||
REWARD = 0xD,
|
||||
SENDPROGRESS = 0xE,
|
||||
UPDATE_KEY,
|
||||
DARK_KEY,
|
||||
NOTIFY_KEY,
|
||||
FLICK_KEY
|
||||
};
|
||||
|
||||
//COMMON SETTINGS
|
||||
static bool dark = false;
|
||||
static bool notify = false;
|
||||
static bool flick = false;
|
||||
static bool flick_enabled = false;
|
||||
static int update_rate = 1;
|
||||
static int current_min;
|
||||
static int last_update_min;
|
||||
|
||||
/*
|
||||
char *translate_error(AppMessageResult result) {
|
||||
switch (result) {
|
||||
case APP_MSG_OK: return "APP_MSG_OK";
|
||||
case APP_MSG_SEND_TIMEOUT: return "APP_MSG_SEND_TIMEOUT";
|
||||
case APP_MSG_SEND_REJECTED: return "APP_MSG_SEND_REJECTED";
|
||||
case APP_MSG_NOT_CONNECTED: return "APP_MSG_NOT_CONNECTED";
|
||||
case APP_MSG_APP_NOT_RUNNING: return "APP_MSG_APP_NOT_RUNNING";
|
||||
case APP_MSG_INVALID_ARGS: return "APP_MSG_INVALID_ARGS";
|
||||
case APP_MSG_BUSY: return "APP_MSG_BUSY";
|
||||
case APP_MSG_BUFFER_OVERFLOW: return "APP_MSG_BUFFER_OVERFLOW";
|
||||
case APP_MSG_ALREADY_RELEASED: return "APP_MSG_ALREADY_RELEASED";
|
||||
case APP_MSG_CALLBACK_ALREADY_REGISTERED: return "APP_MSG_CALLBACK_ALREADY_REGISTERED";
|
||||
case APP_MSG_CALLBACK_NOT_REGISTERED: return "APP_MSG_CALLBACK_NOT_REGISTERED";
|
||||
case APP_MSG_OUT_OF_MEMORY: return "APP_MSG_OUT_OF_MEMORY";
|
||||
case APP_MSG_CLOSED: return "APP_MSG_CLOSED";
|
||||
case APP_MSG_INTERNAL_ERROR: return "APP_MSG_INTERNAL_ERROR";
|
||||
default: return "UNKNOWN ERROR";
|
||||
}
|
||||
}*/
|
||||
static void show_refresh(bool refreshing) {
|
||||
gbitmap_destroy(refresh_icon);
|
||||
if(refreshing) refresh_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_REFRESH);
|
||||
else refresh_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_REFRESH_FAIL);
|
||||
bitmap_layer_set_bitmap(refresh_layer,refresh_icon);
|
||||
layer_mark_dirty(bitmap_layer_get_layer(refresh_layer));
|
||||
layer_set_hidden(bitmap_layer_get_layer(refresh_layer),false);
|
||||
}
|
||||
static void timeout_callback(void * data) {
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG,"timout called");
|
||||
show_refresh(false);
|
||||
}
|
||||
static void fetch_msg(void) {
|
||||
|
||||
//APP_LOG(APP_LOG_LEVEL_DEBUG,"Update int: %u", update_rate);
|
||||
//Make sure we don't request more than once per min (be nice to Mr Slush)
|
||||
if(current_min == last_update_min) return;
|
||||
last_update_min = current_min;
|
||||
Tuplet fetch_tuple = TupletInteger(0x0, 1);
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG,"requesting");
|
||||
timeout_timer = app_timer_register(timeout_length,timeout_callback, NULL);
|
||||
show_refresh(true);
|
||||
DictionaryIterator *iter;
|
||||
app_message_outbox_begin(&iter);
|
||||
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dict_write_tuplet(iter, &fetch_tuple);
|
||||
dict_write_end(iter);
|
||||
|
||||
app_message_outbox_send();
|
||||
}
|
||||
|
||||
static void handle_flick(AccelAxisType axis, int32_t direction) {
|
||||
fetch_msg();
|
||||
}
|
||||
|
||||
static void enable_flick(bool enable) {
|
||||
if(enable && !flick_enabled) {
|
||||
accel_tap_service_subscribe(&handle_flick);
|
||||
flick_enabled = true;
|
||||
}
|
||||
else if(!enable && flick_enabled) {
|
||||
accel_tap_service_unsubscribe();
|
||||
flick_enabled = false;
|
||||
}
|
||||
}
|
||||
static void handle_bluetooth(bool connected) {
|
||||
/**
|
||||
* Show/hide bluetooth icon
|
||||
*/
|
||||
if(connected) layer_set_hidden(bitmap_layer_get_layer(bluetooth_layer),false);
|
||||
else layer_set_hidden(bitmap_layer_get_layer(bluetooth_layer),true);
|
||||
}
|
||||
|
||||
static void handle_battery(BatteryChargeState charge_state) {
|
||||
/**
|
||||
* Update battery icon
|
||||
*/
|
||||
if(battery_percentage != 110) gbitmap_destroy(battery_icon);
|
||||
if (charge_state.is_charging) battery_percentage = 101;
|
||||
else battery_percentage = charge_state.charge_percent;
|
||||
uint32_t res_id;
|
||||
switch(battery_percentage) {
|
||||
case 101: res_id = RESOURCE_ID_ICON_BATTERY_CHARGING; break;
|
||||
case 10: res_id = RESOURCE_ID_ICON_BATTERY_20; break;
|
||||
case 20: res_id = RESOURCE_ID_ICON_BATTERY_20; break;
|
||||
case 30: res_id = RESOURCE_ID_ICON_BATTERY_40; break;
|
||||
case 40: res_id = RESOURCE_ID_ICON_BATTERY_40; break;
|
||||
case 50: res_id = RESOURCE_ID_ICON_BATTERY_60; break;
|
||||
case 60: res_id = RESOURCE_ID_ICON_BATTERY_60; break;
|
||||
case 70: res_id = RESOURCE_ID_ICON_BATTERY_80; break;
|
||||
case 80: res_id = RESOURCE_ID_ICON_BATTERY_80; break;
|
||||
case 90: res_id = RESOURCE_ID_ICON_BATTERY_100; break;
|
||||
case 100: res_id = RESOURCE_ID_ICON_BATTERY_100; break;
|
||||
default: res_id = RESOURCE_ID_ICON_BATTERY_0; break;
|
||||
}
|
||||
battery_icon = gbitmap_create_with_resource(res_id);
|
||||
bitmap_layer_set_bitmap(battery_layer,battery_icon);
|
||||
layer_mark_dirty(bitmap_layer_get_layer(battery_layer));
|
||||
|
||||
}
|
||||
|
||||
static void in_received_handler(DictionaryIterator *iter, void *context) {
|
||||
/**
|
||||
* Update layers based on app message response
|
||||
*/
|
||||
|
||||
//UPDATE SETTINGS
|
||||
Tuple *dark_tuple = dict_find(iter, DARK);
|
||||
if(dark_tuple) {
|
||||
if(strcmp(dark_tuple->value->cstring,"true")==0) {
|
||||
persist_write_bool(DARK_KEY,true);
|
||||
dark = true;
|
||||
layer_set_hidden(inverter_layer_get_layer(inverter_layer),false);
|
||||
} else {
|
||||
persist_write_bool(DARK_KEY,false);
|
||||
dark = false;
|
||||
layer_set_hidden(inverter_layer_get_layer(inverter_layer),true);
|
||||
}
|
||||
}
|
||||
Tuple *notify_tuple = dict_find(iter, NOTIFY);
|
||||
if(notify_tuple) {
|
||||
if(strcmp(notify_tuple->value->cstring,"true")==0) {
|
||||
persist_write_bool(NOTIFY_KEY,true);
|
||||
notify = true;
|
||||
}
|
||||
else {
|
||||
persist_write_bool(NOTIFY_KEY,false);
|
||||
notify = false;
|
||||
}
|
||||
}
|
||||
Tuple *flick_tuple = dict_find(iter, FLICK);
|
||||
if(flick_tuple) {
|
||||
if(strcmp(flick_tuple->value->cstring,"true")==0) {
|
||||
persist_write_bool(FLICK_KEY,true);
|
||||
flick = true;
|
||||
enable_flick(true);
|
||||
}
|
||||
else {
|
||||
persist_write_bool(FLICK_KEY,false);
|
||||
flick = false;
|
||||
enable_flick(false);
|
||||
}
|
||||
}
|
||||
Tuple *update_tuple = dict_find(iter, UPDATE);
|
||||
if(update_tuple) {
|
||||
int update = atoi(update_tuple->value->cstring);
|
||||
if(update > 0 && update < 61) {
|
||||
persist_write_int(UPDATE_KEY,update);
|
||||
update_rate = update;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//UPDATE BTC VALUES
|
||||
Tuple *workers_tuple = dict_find(iter, WORKERS);
|
||||
Tuple *hashrate_tuple = dict_find(iter, HASHRATE);
|
||||
Tuple *reward_tuple = dict_find(iter, REWARD);
|
||||
Tuple *lastshare_tuple = dict_find(iter, LASTSHARE);
|
||||
Tuple *progress_tuple = dict_find(iter, SENDPROGRESS);
|
||||
if(workers_tuple) {
|
||||
int n = atoi(workers_tuple->value->cstring);
|
||||
if(n<current_workers && notify) vibes_long_pulse();
|
||||
current_workers = n;
|
||||
text_layer_set_text(worker_text_layer, workers_tuple->value->cstring);
|
||||
}
|
||||
if(hashrate_tuple) text_layer_set_text(hashrate_text_layer, hashrate_tuple->value->cstring);
|
||||
if(reward_tuple) text_layer_set_text(reward_text_layer, reward_tuple->value->cstring);
|
||||
if(lastshare_tuple) text_layer_set_text(lastshare_text_layer, lastshare_tuple->value->cstring);
|
||||
if(progress_tuple) {
|
||||
int n = atoi(progress_tuple->value->cstring);
|
||||
if(n!=progress_width) {
|
||||
progress_width = n;
|
||||
layer_set_frame(inverter_layer_get_layer(progress_layer),(GRect) { .origin = { 0, 164 }, .size = { n, 4 } });
|
||||
}
|
||||
}
|
||||
//SHOW BTC VALUES or ERROR
|
||||
Tuple *response_tuple = dict_find(iter, RESPONSE);
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG,response_tuple->value->cstring);
|
||||
if(response_tuple) {
|
||||
if(strcmp(response_tuple->value->cstring,"NoAPI")==0) {
|
||||
layer_set_hidden(btc_parent_layer,true);
|
||||
text_layer_set_text(info_layer,"Please enter your Slush's Pool API Key into the MineWatch settings on your phone.");
|
||||
layer_set_hidden(text_layer_get_layer(info_layer),false);
|
||||
} else if (strcmp(response_tuple->value->cstring,"TIMEOUT")==0) {
|
||||
show_refresh(false);
|
||||
} else if (strcmp(response_tuple->value->cstring,"InvAPI")==0) {
|
||||
layer_set_hidden(btc_parent_layer,true);
|
||||
text_layer_set_text(info_layer,"Your API Key is invalid.");
|
||||
layer_set_hidden(text_layer_get_layer(info_layer), false);
|
||||
} else if(strcmp(response_tuple->value->cstring,"OK")==0) {
|
||||
layer_set_hidden(text_layer_get_layer(info_layer), true);
|
||||
layer_set_hidden(btc_parent_layer,false);
|
||||
strcpy(last_update_text,time_text);
|
||||
}
|
||||
app_timer_cancel(timeout_timer);
|
||||
if(strcmp(response_tuple->value->cstring,"TIMEOUT")!=0) layer_set_hidden(bitmap_layer_get_layer(refresh_layer),true);
|
||||
}
|
||||
}
|
||||
|
||||
static void in_dropped_handler(AppMessageResult reason, void *context) {
|
||||
//APP_LOG(APP_LOG_LEVEL_DEBUG,"in dropped %i - %s",reason,translate_error(reason));
|
||||
show_refresh(false);
|
||||
}
|
||||
|
||||
static void out_failed_handler(DictionaryIterator *failed, AppMessageResult reason, void *context) {
|
||||
//app_log(APP_LOG_LEVEL_DEBUG,"out failed %i - %s",reason,translate_error(reason));
|
||||
show_refresh(false);
|
||||
}
|
||||
|
||||
static void app_message_init(void) {
|
||||
/**
|
||||
* Register message handlers
|
||||
*/
|
||||
app_message_register_inbox_received(in_received_handler);
|
||||
app_message_register_inbox_dropped(in_dropped_handler);
|
||||
app_message_register_outbox_failed(out_failed_handler);
|
||||
// Init buffers
|
||||
app_message_open(128, 128);
|
||||
}
|
||||
|
||||
void handle_minute_tick(struct tm *tick_time, TimeUnits units_changed) {
|
||||
/**
|
||||
* Update time and date (if applicable)
|
||||
*/
|
||||
|
||||
//Check if we should get an update
|
||||
current_min= tick_time->tm_min;
|
||||
if(current_min%update_rate == 0) fetch_msg();
|
||||
|
||||
char *time_format;
|
||||
|
||||
char current_date[] = "00 Xxxxxxxxx";
|
||||
strcpy(current_date,date_text);
|
||||
strftime(date_text, sizeof(date_text), "%e %B", tick_time);
|
||||
if(strcmp(current_date,date_text)!=0) text_layer_set_text(date_layer, date_text);
|
||||
|
||||
if (clock_is_24h_style()) {
|
||||
time_format = "%R";
|
||||
} else {
|
||||
time_format = "%I:%M";
|
||||
}
|
||||
|
||||
strftime(time_text, sizeof(time_text), time_format, tick_time);
|
||||
|
||||
// Kludge to handle lack of non-padded hour format string
|
||||
// for twelve hour clock.
|
||||
if (!clock_is_24h_style() && (time_text[0] == '0')) {
|
||||
memmove(time_text, &time_text[1], sizeof(time_text) - 1);
|
||||
}
|
||||
|
||||
text_layer_set_text(time_layer, time_text);
|
||||
}
|
||||
|
||||
static void window_load(Window *window) {
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
|
||||
/**
|
||||
* TIME LAYER
|
||||
*/
|
||||
time_layer = text_layer_create((GRect) { .origin = { 9, 10 }, .size = { 134, 50 } });
|
||||
text_layer_set_font(time_layer, font_l);
|
||||
layer_add_child(window_layer, text_layer_get_layer(time_layer));
|
||||
|
||||
/**
|
||||
* DATE LAYER
|
||||
*/
|
||||
date_layer = text_layer_create((GRect) { .origin = { 0, 0 }, .size = { 80, 25 } });
|
||||
text_layer_set_font(date_layer, font_m);
|
||||
layer_add_child(window_layer, text_layer_get_layer(date_layer));
|
||||
|
||||
/**
|
||||
* REFRESH LAYER
|
||||
*/
|
||||
refresh_layer = bitmap_layer_create((GRect) { .origin = { 85, 7 }, .size = { 20, 12 } });
|
||||
refresh_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_REFRESH);
|
||||
bitmap_layer_set_bitmap(refresh_layer,refresh_icon);
|
||||
//layer_set_hidden(bitmap_layer_get_layer(refresh_layer),true);
|
||||
layer_add_child(window_layer,bitmap_layer_get_layer(refresh_layer));
|
||||
|
||||
/**
|
||||
* BLUETOOTH LAYER
|
||||
*/
|
||||
bluetooth_layer = bitmap_layer_create((GRect) { .origin = { 110, 7 }, .size = { 6, 12 } });
|
||||
bluetooth_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_BLUETOOTH);
|
||||
bitmap_layer_set_bitmap(bluetooth_layer,bluetooth_icon);
|
||||
if(!bluetooth_connection_service_peek()) layer_set_hidden(bitmap_layer_get_layer(bluetooth_layer),true);
|
||||
layer_add_child(window_layer,bitmap_layer_get_layer(bluetooth_layer));
|
||||
|
||||
/**
|
||||
* BATTERY LAYER
|
||||
*/
|
||||
battery_layer = bitmap_layer_create((GRect) { .origin = { 120, 7 }, .size = { 19, 12 } });
|
||||
layer_add_child(window_layer, bitmap_layer_get_layer(battery_layer));
|
||||
handle_battery(battery_state_service_peek());
|
||||
|
||||
/**
|
||||
* INFO LAYER
|
||||
*/
|
||||
info_layer = text_layer_create((GRect) { .origin = { 5, 70 }, .size = { 134, 90 } });
|
||||
text_layer_set_font(info_layer,font_s);
|
||||
layer_set_hidden(text_layer_get_layer(info_layer),true);
|
||||
layer_add_child(window_layer,text_layer_get_layer(info_layer));
|
||||
|
||||
/**
|
||||
* BTC PARENT LAYER
|
||||
*/
|
||||
btc_parent_layer = layer_create((GRect) { .origin = { 5, 62 }, .size = { 134, 90 } });
|
||||
layer_set_hidden(btc_parent_layer,true);
|
||||
layer_add_child(window_layer, btc_parent_layer);
|
||||
|
||||
/**
|
||||
* BTC ICONS LAYERS
|
||||
*/
|
||||
worker_icon_layer = bitmap_layer_create((GRect) { .origin = { 0, 3 }, .size = { 15, 15 } });
|
||||
worker_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_WORKER);
|
||||
bitmap_layer_set_bitmap(worker_icon_layer,worker_icon);
|
||||
layer_add_child(btc_parent_layer,bitmap_layer_get_layer(worker_icon_layer));
|
||||
hashrate_icon_layer = bitmap_layer_create((GRect) { .origin = { 0, 26 }, .size = { 15, 15 } });
|
||||
hashrate_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_GRAPH);
|
||||
bitmap_layer_set_bitmap(hashrate_icon_layer,hashrate_icon);
|
||||
layer_add_child(btc_parent_layer,bitmap_layer_get_layer(hashrate_icon_layer));
|
||||
lastshare_icon_layer = bitmap_layer_create((GRect) { .origin = { 0, 50 }, .size = { 15, 15 } });
|
||||
lastshare_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_CLOCK);
|
||||
bitmap_layer_set_bitmap(lastshare_icon_layer,lastshare_icon);
|
||||
layer_add_child(btc_parent_layer,bitmap_layer_get_layer(lastshare_icon_layer));
|
||||
reward_icon_layer = bitmap_layer_create((GRect) { .origin = { 0, 75 }, .size = { 15, 15 } });
|
||||
reward_icon = gbitmap_create_with_resource(RESOURCE_ID_ICON_BTC);
|
||||
bitmap_layer_set_bitmap(reward_icon_layer,reward_icon);
|
||||
layer_add_child(btc_parent_layer,bitmap_layer_get_layer(reward_icon_layer));
|
||||
|
||||
/**
|
||||
* BTC TEXT LAYERS
|
||||
*/
|
||||
worker_text_layer = text_layer_create((GRect) { .origin = { 20, 0 }, .size = { 114, 20 } });
|
||||
text_layer_set_font(worker_text_layer,font_m);
|
||||
layer_add_child(btc_parent_layer,text_layer_get_layer(worker_text_layer));
|
||||
hashrate_text_layer = text_layer_create((GRect) { .origin = { 20, 23 }, .size = { 114, 20 } });
|
||||
text_layer_set_font(hashrate_text_layer,font_m);
|
||||
layer_add_child(btc_parent_layer,text_layer_get_layer(hashrate_text_layer));
|
||||
lastshare_text_layer = text_layer_create((GRect) { .origin = { 20, 47 }, .size = { 114, 20 } });
|
||||
text_layer_set_font(lastshare_text_layer,font_m);
|
||||
layer_add_child(btc_parent_layer,text_layer_get_layer(lastshare_text_layer));
|
||||
reward_text_layer = text_layer_create((GRect) { .origin = { 20, 70 }, .size = { 114, 20 } });
|
||||
text_layer_set_font(reward_text_layer,font_m);
|
||||
layer_add_child(btc_parent_layer,text_layer_get_layer(reward_text_layer));
|
||||
|
||||
/**
|
||||
* PROGRESS LAYER
|
||||
*/
|
||||
progress_layer = inverter_layer_create((GRect) { .origin = { 0, 164 }, .size = { 0, 4 } });
|
||||
layer_add_child(window_layer,inverter_layer_get_layer(progress_layer));
|
||||
|
||||
|
||||
/**
|
||||
* LAST UPDATE LAYER
|
||||
*/
|
||||
last_update_layer = text_layer_create((GRect) { .origin = { 114, 149 }, .size = { 28, 14 } });
|
||||
text_layer_set_font(last_update_layer,font_xs);
|
||||
text_layer_set_text(last_update_layer,last_update_text);
|
||||
layer_add_child(window_layer,text_layer_get_layer(last_update_layer));
|
||||
|
||||
/**
|
||||
* INVERTER LAYER
|
||||
*/
|
||||
inverter_layer = inverter_layer_create((GRect) { .origin = { 0, 0 }, .size = { 144, 168 } });
|
||||
if(!dark) layer_set_hidden(inverter_layer_get_layer(inverter_layer), true);
|
||||
layer_add_child(window_layer,inverter_layer_get_layer(inverter_layer));
|
||||
}
|
||||
|
||||
static void window_unload(Window *window) {
|
||||
inverter_layer_destroy(inverter_layer);
|
||||
text_layer_destroy(time_layer);
|
||||
text_layer_destroy(date_layer);
|
||||
bitmap_layer_destroy(refresh_layer);
|
||||
gbitmap_destroy(refresh_icon);
|
||||
bitmap_layer_destroy(battery_layer);
|
||||
if(battery_icon) gbitmap_destroy(battery_icon);
|
||||
bitmap_layer_destroy(bluetooth_layer);
|
||||
gbitmap_destroy(bluetooth_icon);
|
||||
text_layer_destroy(info_layer);
|
||||
layer_destroy(btc_parent_layer);
|
||||
text_layer_destroy(worker_text_layer);
|
||||
text_layer_destroy(hashrate_text_layer);
|
||||
text_layer_destroy(lastshare_text_layer);
|
||||
text_layer_destroy(reward_text_layer);
|
||||
bitmap_layer_destroy(worker_icon_layer);
|
||||
gbitmap_destroy(worker_icon);
|
||||
bitmap_layer_destroy(hashrate_icon_layer);
|
||||
gbitmap_destroy(hashrate_icon);
|
||||
bitmap_layer_destroy(lastshare_icon_layer);
|
||||
gbitmap_destroy(lastshare_icon);
|
||||
bitmap_layer_destroy(reward_icon_layer);
|
||||
gbitmap_destroy(reward_icon);
|
||||
text_layer_destroy(last_update_layer);
|
||||
inverter_layer_destroy(progress_layer);
|
||||
|
||||
}
|
||||
|
||||
static void init(void) {
|
||||
font_xs = fonts_get_system_font(FONT_KEY_FONT_FALLBACK);
|
||||
font_s = fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD);
|
||||
font_m = fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD);
|
||||
font_l = fonts_get_system_font(FONT_KEY_ROBOTO_BOLD_SUBSET_49);
|
||||
dark = (persist_exists(DARK_KEY)) ? persist_read_bool(DARK_KEY) : dark;
|
||||
notify = (persist_exists(NOTIFY_KEY)) ? persist_read_bool(NOTIFY_KEY) : notify;
|
||||
flick = (persist_exists(FLICK_KEY)) ? persist_read_bool(FLICK_KEY) : flick;
|
||||
update_rate = (persist_exists(UPDATE_KEY)) ? persist_read_int(UPDATE_KEY) : update_rate;
|
||||
|
||||
|
||||
window = window_create();
|
||||
window_set_window_handlers(window, (WindowHandlers) {
|
||||
.load = window_load,
|
||||
.unload = window_unload,
|
||||
});
|
||||
const bool animated = true;
|
||||
window_stack_push(window, animated);
|
||||
app_message_init();
|
||||
battery_state_service_subscribe(&handle_battery);
|
||||
bluetooth_connection_service_subscribe(handle_bluetooth);
|
||||
tick_timer_service_subscribe(MINUTE_UNIT, handle_minute_tick);
|
||||
if(flick) enable_flick(true);
|
||||
timeout_timer = app_timer_register(timeout_length,timeout_callback, NULL);
|
||||
}
|
||||
|
||||
static void deinit(void) {
|
||||
window_destroy(window);
|
||||
battery_state_service_unsubscribe();
|
||||
bluetooth_connection_service_unsubscribe();
|
||||
tick_timer_service_unsubscribe();
|
||||
accel_tap_service_unsubscribe();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init();
|
||||
app_event_loop();
|
||||
deinit();
|
||||
}
|
||||
24
app/wscript
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#
|
||||
# This file is the default set of rules to compile a Pebble project.
|
||||
#
|
||||
# Feel free to customize this to your needs.
|
||||
#
|
||||
|
||||
top = '.'
|
||||
out = 'build'
|
||||
|
||||
def options(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
def configure(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
def build(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'),
|
||||
target='pebble-app.elf')
|
||||
|
||||
ctx.pbl_bundle(elf='pebble-app.elf',
|
||||
js=ctx.path.ant_glob('src/js/**/*.js'))
|
||||