01-18-2021 18:08
01-18-2021 18:08
Hi,
I'm new to developing clock faces and I don't think I'm properly writing the selected options to the watch. When you first install the clock face, the default settings that I'm applying seem to be working fine. However sometimes the selected texture (PNG with a mask) and color do not load so the background is all black. I think this is only happening with the Versa 2 but can't be certain. It's almost like it's a syncing issue and the only way to fix it is reinstall the face or reboot the phone.
Can you see below if I have done anything wrong?
app/index.gui
import * as messaging from "messaging";
import { me as appbit } from "appbit";
import { display } from "display";
import clock from "clock";
import document from "document";
import { preferences } from "user-settings";
import * as util from "../common/utils";
import { battery } from "power";
import { HeartRateSensor } from "heart-rate";
import userActivity from "user-activity";
import { gettext } from "i18n";
// Update the clock every minute
clock.granularity = "seconds";
// Get a handle on the <text> elements specified in the index.gui file
const background = document.getElementById("background");
const imageMask = document.getElementById("imageMask");
const dayHandle = document.getElementById("dayLabel");
const batteryHandle = document.getElementById("batteryLabel");
const timeHandle = document.getElementById("timeLabel");
const timeHandleShadow = document.getElementById("timeLabelShadow");
const stepsHandle = document.getElementById("stepsLabel");
const heartRateHandle = document.getElementById("heartRateLabel");
const caloriesHandle = document.getElementById("caloriesLabel");
// The following block read the heart rate from your watch
if (HeartRateSensor && appbit.permissions.granted("access_heart_rate")) {
const hrm = new HeartRateSensor();
hrm.addEventListener("reading", () => {
heartRateHandle.text = `${hrm.heartRate}`;
});
display.addEventListener("change", () => {
// Automatically stop the sensor when the screen is off to conserve battery
display.on ? hrm.start() : hrm.stop();
});
hrm.start();
}
else
{
heartRateHandle.text = `N/A`;
}
// Message is received
messaging.peerSocket.onmessage = evt => {
console.log(`App received: ${JSON.stringify(evt)}`);
if (evt.data.key === "color" && evt.data.newValue) {
let color = JSON.parse(evt.data.newValue);
background.style.fill = color;
dayHandle.style.fill = color;
}
if(evt.data.key === "texture" && evt.data.newValue){
let texture = JSON.parse(evt.data.newValue);
imageMask.href = texture.values[0].value;
}
};
// Message socket opens
messaging.peerSocket.onopen = () => {
console.log("App Socket Open");
};
// Message socket closes
messaging.peerSocket.onclose = () => {
console.log("App Socket Closed");
};
// Update the <text> element every tick with the current time
clock.ontick = (evt) => {
let today = evt.date;
let hours = today.getHours();
if (preferences.clockDisplay === "12h") {
// 12h format
hours = hours % 12 || 12;
} else {
// 24h format
hours = util.zeroPad(hours);
}
let mins = util.zeroPad(today.getMinutes());
timeHandle.text = `${hours}:${mins}`;
timeHandleShadow.text = timeHandle.text;
let batteryValue = battery.chargeLevel;
batteryHandle.text = `${batteryValue}%`;
if(batteryValue >= 20){
batteryHandle.style.fill = `white`;
} else {
batteryHandle.style.fill = `#FA4D61`;
}
let caloriesValue = util.formatNumberWithComma(userActivity.today.adjusted["calories"] || 0);
caloriesHandle.text = `${caloriesValue}`;
let stepsValue = util.formatNumberWithComma(userActivity.today.adjusted["steps"] || 0);
stepsHandle.text = `${stepsValue}`;
let days = [gettext("SUN"), gettext("MON"), gettext("TUE"), gettext("WED"), gettext("THU"), gettext("FRI"), gettext("SAT")];
let dateValue = today.getDate();
dayHandle.text = `${days[today.getDay()]} ${today.getDate()}`;
}
companion/index.js
import * as messaging from "messaging";
import { settingsStorage } from "settings";
// Message socket opens
messaging.peerSocket.onopen = () => {
console.log("Companion Socket Open");
restoreSettings();
};
// Message socket closes
messaging.peerSocket.onclose = () => {
console.log("Companion Socket Closed");
};
// A user changes settings
settingsStorage.onchange = evt => {
let data = {
key: evt.key,
newValue: evt.newValue
};
sendVal(data);
};
// Restore any previously saved settings and send to the device
function restoreSettings() {
for (let index = 0; index < settingsStorage.length; index++) {
let key = settingsStorage.key(index);
if (key) {
let data = {
key: key,
newValue: settingsStorage.getItem(key)
};
sendVal(data);
}
}
}
// Send data to device using Messaging API
function sendVal(data) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
messaging.peerSocket.send(data);
}
}
function setDefaultSetting(key, value) {
let extantValue = settingsStorage.getItem(key);
if (extantValue === null) settingsStorage.setItem(key, JSON.stringify(value));
}
setDefaultSetting("texture", {"selected":[0],"values":[{"name":"Just Black","value":"images/just-black.png"}]});
setDefaultSetting("color", "#DC143C");
Thanks!
Answered! Go to the Best Answer.
01-18-2021 18:14
01-18-2021 18:14
I only had a quick skim. Could it be that you're not saving the new settings on the watch, so they revert to defaults whenever the clockface restarts?
01-18-2021 18:14
01-18-2021 18:14
I only had a quick skim. Could it be that you're not saving the new settings on the watch, so they revert to defaults whenever the clockface restarts?
01-18-2021 18:30
01-18-2021 18:30
That's what I think I'm doing wrong but not sure how to correct it. I tried looking up other threads but couldn't find a proper example. I think that when the watch loses connectivity to the phone, the issue occurs. Then I think the condition with the setDefaultSetting function is preventing the default settings to appear.
Do you know how I can modify my code to write the settings to the watch?
Thanks!
01-18-2021 19:00
07-03-2021 09:59
07-03-2021 09:59
I was able to fix the issue by writing and reading to a JSON file so that when the watch loses connectivity, I can read the value stored in the JSON file.
Thanks for your help!