- Split render into FieldTable/Fields/Icons/Layout/Settings modules - Add Fenix8V3Background, Owm (weather), Solar modules - Add tools/ generators (gen_fields/gen_icons/gen_themes/gen_preview_svg) - Tune README/manifest/strings/settings
69 lines
3.0 KiB
MonkeyC
69 lines
3.0 KiB
MonkeyC
import Toybox.Lang;
|
||
import Toybox.Application;
|
||
import Toybox.Math;
|
||
import Toybox.Time;
|
||
import Toybox.Time.Gregorian;
|
||
import Settings;
|
||
|
||
// ============================================================================
|
||
// OpenWeatherMap —— 读取端
|
||
// ----------------------------------------------------------------------------
|
||
// 本模块**不联网**,只负责把后台服务上次存下来的数据读出来。
|
||
// 真正的网络请求在 Fenix8V3Background.mc 里,由系统按定时器唤醒执行。
|
||
//
|
||
// 为什么要拆成两半:表盘进程绝大多数时间根本没在运行,onUpdate 又必须够快,
|
||
// 不可能在绘制路径里发 HTTP 请求。Connect IQ 给的方案就是后台服务 —— 定时唤醒、
|
||
// 请求、把结果通过 Background.exit() 交回前台,前台再写进 Application.Storage。
|
||
//
|
||
// API key 由用户自己在设置里填(免费档就够)。没填 key 时:
|
||
// - enabled() 返回 false,后台定时器根本不会注册,一次网络都不会发
|
||
// - 25 个 OWM 字段全部显示 "--"
|
||
//
|
||
// 后台服务会把两个接口的响应**压平成一个扁平字典**再存,这样表盘侧永远不用在
|
||
// 内存里扛一棵解析好的 JSON 树(手表内存很紧张)。
|
||
// ============================================================================
|
||
module Owm {
|
||
|
||
const STORE = "owm"; // 在 Application.Storage 里的键名
|
||
const MAX_AGE = 7200; // 超过两小时的数据视为过期(秒)
|
||
|
||
// 用户填的 API key;没填返回空串。
|
||
function key() as String {
|
||
return Settings.text("OwmKey");
|
||
}
|
||
|
||
// 只有填了 key 才算启用。这个判断同时决定了后台定时器要不要注册,
|
||
// 见 Fenix8V3App.scheduleWeather()。
|
||
function enabled() as Boolean {
|
||
return key().length() > 0;
|
||
}
|
||
|
||
// 取出后台存的整个扁平字典;从没成功拉取过则为 null。
|
||
function data() as Dictionary? {
|
||
var d = Application.Storage.getValue(STORE);
|
||
return (d == null) ? null : (d as Dictionary);
|
||
}
|
||
|
||
// 取单个字段。键名是后台服务定义的短名("temp"/"feels"/"hi1"…),
|
||
// 与 Fenix8V3Background.mc 里的 put() 调用一一对应。
|
||
function get(field as String) {
|
||
var d = data();
|
||
if (d == null) { return null; }
|
||
return d.get(field);
|
||
}
|
||
|
||
// 数据是否还新鲜。目前 Fields 里没有强制用它 —— 手表离线一段时间后
|
||
// 显示稍旧的天气,比直接显示 "--" 更有用;留着给需要的地方调用。
|
||
function fresh() as Boolean {
|
||
var t = get("dt");
|
||
if (t == null) { return false; }
|
||
return (Time.now().value() - (t as Number)) < MAX_AGE;
|
||
}
|
||
|
||
// 该字段编号是否属于 OWM 分类。500–537 这一段全是 OWM 的编号,
|
||
// 与 Garmin 原生天气(300–315)完全分开。
|
||
function owns(id as Number) as Boolean {
|
||
return (id >= 500 && id <= 537) || id == 502 || id == 503;
|
||
}
|
||
}
|