01-23-2019 22:23
01-23-2019 22:23
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
Answered! Go to the Best Answer.
01-24-2019 02:53
01-24-2019 02:53
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
01-24-2019 02:53
01-24-2019 02:53
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
01-24-2019 09:07
01-24-2019 09:07
Thanks, @JonFitbit! This looks very exciting. I'll try it out and let you know how it goes...
01-24-2019 13:38
01-24-2019 13:38
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);
01-24-2019 13:59
01-24-2019 13:59
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!
01-24-2019 14:06
01-24-2019 14:06
is it case sensitive? newfile ?
01-24-2019 16:11
01-24-2019 16:11
You called it. It's working so smoothly now! Much better than any of my solutions involving caching and peer messaging. Thanks again!
04-29-2019 11:32
04-29-2019 11:32