Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The selected settings for the clock face are sometimes not found

ANSWERED

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!

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

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?

Peter McLennan
Gondwana Software

View best answer in original post

Best Answer
0 Votes
4 REPLIES 4

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?

Peter McLennan
Gondwana Software
Best Answer
0 Votes

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!

Best Answer
0 Votes

I suspect the 'losing connectivity' bit is a red herring.

I hand-code my own functions for storing and loading settings on the watch. However, this and this provide examples.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

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!

Best Answer