Update watch face: modular refactor + OWM/Solar/background + codegen tools
- 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
This commit is contained in:
68
source/Owm.mc
Normal file
68
source/Owm.mc
Normal file
@@ -0,0 +1,68 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user