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

Preload Watch Face data

ANSWERED

Hello,

 

I am working on a watch face that displays data fetched from a web service. When clock.onTick occurs, the app sends a request to the companion (via a message). The companion then makes a call to the web service and sends the response data to the app via another message.

 

Because the data in the web service changes almost exactly once every 5 minutes, I cache the latest value in the companion for about 5 minutes.That way, when the app wakes up after less than 5 minutes, it can fetch data pretty quickly by just connecting to the companion, without the need for a web service call. However, if the app wakes up after a longer interval (20 minutes, for example), and it makes a call to the companion, the companion is forced to make the web service call. In order to minimize this occurrence, I automatically wake the companion every 5 minutes, so that the companion-cached data is almost always fresh.

 

The remaining issue is that the re-connection of the app to the companion still takes 2 - 3 seconds. That means that, even if the data is fully cached in the companion, it takes 2 - 3 seconds between the time that I flick my wrist (to turn on the display and wake up the app) and the time the companion-cached data is displayed.

 

Is there a way for the companion to "push" data to the device/app on a regular schedule, even if the device display is off, instead of the companion just caching the data locally and waiting for the app to ask for it?

 

Cheers,

~alex

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

Yes, you should do this, it's easier too:

Wake your companion every 20 minutes, download the data, send it to the device via file transfer.

On the device, just read the contents of the file and it should always be correct..

You can see it in my Alpine Snow app, it's how I handle the weather data.

 

Companion:

Fetch data every x minutes and send it via a CBOR encoded file to the device

https://github.com/orviwan/alpine-snow/blob/master/companion/index.js

 

App:

Listen for new files

https://github.com/orviwan/alpine-snow/blob/master/app/index.js#L27

Receive the file

https://github.com/orviwan/alpine-snow/blob/master/app/lib/incoming.js

Read the data from the file

https://github.com/orviwan/alpine-snow/blob/master/app/subviews/weather.js#L25

 

 

 

View best answer in original post

Best Answer
7 REPLIES 7

Yes, you should do this, it's easier too:

Wake your companion every 20 minutes, download the data, send it to the device via file transfer.

On the device, just read the contents of the file and it should always be correct..

You can see it in my Alpine Snow app, it's how I handle the weather data.

 

Companion:

Fetch data every x minutes and send it via a CBOR encoded file to the device

https://github.com/orviwan/alpine-snow/blob/master/companion/index.js

 

App:

Listen for new files

https://github.com/orviwan/alpine-snow/blob/master/app/index.js#L27

Receive the file

https://github.com/orviwan/alpine-snow/blob/master/app/lib/incoming.js

Read the data from the file

https://github.com/orviwan/alpine-snow/blob/master/app/subviews/weather.js#L25

 

 

 

Best Answer

Thanks, @JonFitbit! This looks very exciting. I'll try it out and let you know how it goes...

Best Answer
0 Votes

I tried it out in the simulator. It almost works... Specifically, the file gets transferred and can be read from the device code, but the event that notifies the device code that a new file is available never seems to fire.

 

I included below the relevant portions of my code. I get the console logs of:

app/singleFileReceiver.js:11,1[1:24:52 PM]DEVICE: SingleFileReceiver set up for file - data.cbor

and

companion/index.js:59,7[1:34:00 PM]COMPANION: Transfer of 'data.cbor' successfully queued.

, but I never get

console.log('DEVICE: SingleFileReceiver incoming file detected');

 

Anything I'm missing?

 

// File Sender Code

function sendDataToDeviceFile(data) {
  let encodedData = encode(data);
  let transferFilename = DataConstants.transferFilename;
  outbox
    .enqueue(transferFilename, encodedData)
    .then(ft => {
      console.log(`COMPANION: Transfer of '${transferFilename}' successfully queued.`);
    })
    .catch(function (error) {
      throw new Error(`Failed to enqueue '${destFilename}'. Error: ${error}`);
    });
}

 

// File Receiver Code

import * as fs from "fs";
import { inbox } from "file-transfer";

export class SingleFileReceiver {
  constructor(filename, handler) {
    this._incomingFilename = filename;
    this._handler = handler;
    inbox.addEventListener('newFile', this.processIncomingFiles);
    console.log(`DEVICE: SingleFileReceiver set up for file - ${this._incomingFilename}`);
  }
  processIncomingFiles = () => {
    let filename;

    console.log('DEVICE: SingleFileReceiver incoming file detected');
  }
}

 

// App code

let receiver = new SingleFileReceiver(DataConstants.transferFilename, newDataHandler);

 

Best Answer
0 Votes

For reference, if I call receiver.ProcessIncomingFiles directly from the app code - I tucked it away in the clock.ontick handler - everything works as expected. Given that ontick also gets called when the display turns on, regardless of whether the interval expired or not, this will work for me, as the file will already be there, ready for processing.That being said, I'm just curious why the "newFile" event handler is not working... Thanks again for the help!

Best Answer
0 Votes

is it case sensitive? newfile  ?

Best Answer
0 Votes

You called it. It's working so smoothly now! Much better than any of my solutions involving caching and peer messaging. Thanks again!

Best Answer
Thanks again for the suggestion, @JonFitbit!

I am now wondering about whether the Fitbit infrastructure provides a way for an external system to push notifications into the companion code of my app. Specifically, I would love to get a signal from one of my home sensors and change the state of my Fitbit app as a result of that notification. Is that possible? If so, what is the mechanism to do so?

Cheers,
~alex
Best Answer