11-08-2017 15:22 - edited 11-08-2017 15:25
11-08-2017 15:22 - edited 11-08-2017 15:25
I am trying to transfer a file that I fetch from an Internet API to the device, so I can analyze the data.
I start with the file transfer sample project, and it all works.
When I change the data to the file, it gets stuck into queue and it seems to never write.
Companion code
This one works:
fetch(ENDPOINT) .then(function (response) { response.json() .then(function(data) { console.log("Sending file..."); let data = new Uint8Array(26); for (let counter = 0; counter < data.length; counter++) {
data[counter] = "a".charCodeAt(0) + counter;
} console.log(data); outbox.enqueue("alphabits.txt", data).then(function (ft) { // Queued successfully console.log("Transfer of 'file' successfully queued."); }).catch(function (error) { // Failed to queue throw new Error("Failed to queue '" + destFilename + "'. Error: " + error); });
If I try to chage data to others, it does not work. I tried to leave it blank to pass data directly from the response.josn, and I tried all this. None works.
let data = data;
let data = JSON.stringify(data);
let data = JSON.stringify(data).slice(2,8);
App code stays the same. I changed the type of file (ascii, json, ...) but it does not seem to make a difference. I always get stuck on "file queued"
import document from "document";
import { inbox } from "file-transfer";
import fs from "fs";
console.log("App App Started");
let statusText = document.getElementById("status");
statusText.innerText = "Waiting...";
inbox.onnewfile = function () { var fileName; do { // If there is a file, move it from staging into the application folder fileName = inbox.nextFile(); if (fileName) { console.log("/private/data/" + fileName + " is now available"); console.log(`Received File: <${fileName}>`); let data = fs.readFileSync(fileName); statusText.innerText = "Received: " + data; console.log("received this: " + data) } } while (fileName); };
Can you please point me in what I am doing wrong?
Thanks!!!
Answered! Go to the Best Answer.
11-30-2017 16:48 - edited 11-30-2017 16:50
11-30-2017 16:48 - edited 11-30-2017 16:50
You were close, the JSON.stringify bit isn't needed. I missed the docs for CBOR too, found it eventually here: https://dev.fitbit.com/reference/device-api/cbor/
Your companion should have code like...
import { encode } from 'cbor'; import { outbox } from 'file-transfer'; ... const myFileInfo = encode(data); outbox.enqueue('file.txt', myFileInfo)
My inbox logic is more or less a straight copy paste of the docs here in the app code here: https://dev.fitbit.com/guides/communications/file-transfer/#receiving-a-file
The only part it is missing, is after the file is ready, you need to read it. You should be able to do that fairly simply with the File System API:
import { readFileSync } from 'fs'; ...all the inbox logic in the above link, after the file is ready... const myFileInfo = readFileSync('file.txt', 'cbor');
I have had reliable success with this method, I was really struggling with the Messaging API. Once I figured this out, I was able to rip out a lot of code and simplify. Let me know if it works or if you have any more questions!
EDIT, didn't really answer your CBOR question. As I understand it, you should be able to CBOR encode any regular JS object. If you could call JSON.stringify on it, you should be able to call encode on it instead.
11-13-2017 20:33
11-13-2017 20:33
Anyone has feedback on this?
11-23-2017 04:45
11-23-2017 04:45
Bumping this up again hoping to get some Thanksgiving help...:)
11-27-2017 05:37 - edited 11-27-2017 13:30
11-27-2017 05:37 - edited 11-27-2017 13:30
@agsurf5 I seem to be in the a very similar boat and I'm stuck on this for now. All I can suggest in your code to try to to pass "ascii" as the second parameter in readFileSync, but it sounds like you may have tried that already. Did you ever make any progress?
In my scenario, my outbox.enqueue promise resolves successfully in the companion. I can even get input.nextFile() to return with the correct filename. Unfortunately the data variable I'm setting to the return of readFileSync(fileName, 'ascii') always returns to empty quotes when I know I enqueued a populated string.
It is a shame because other than this I much prefer the File Transfer API to the Messaging API.
EDIT: I have overcome my immediate issue. I was mistaken that I could simple outbox.enqueue an object. Once I converted it into an arrayBuffer on the companion side I am able to read the file on the app side as JSON. The trick is TextEncoder which hopefully continues to work as it isn't explicitly documented.
const arrayBuffer = new TextEncoder().encode(JSON.stringify(data));
Hopefully you'd had similar luck with your issue @agsurf5
SECOND EDIT: Jon pointed out that I should probably be using CBOR.encode instead of TextEncoder, which I completely missed while scanning the documentation. Just a heads up for anyone in the same situation.
11-30-2017 13:48
11-30-2017 13:48
@kenjamin I am pretty lost now. I tried to locate info for CBOR and how to write a cbor file, and I was lost for hours. JSON I understand. CBOR seems nowhere to be found apart from the specs of it.
Should I just write a JSON and then write something like:
const myFileInfo = new CBOR.encode(JSON.stringify(data));
11-30-2017 16:48 - edited 11-30-2017 16:50
11-30-2017 16:48 - edited 11-30-2017 16:50
You were close, the JSON.stringify bit isn't needed. I missed the docs for CBOR too, found it eventually here: https://dev.fitbit.com/reference/device-api/cbor/
Your companion should have code like...
import { encode } from 'cbor'; import { outbox } from 'file-transfer'; ... const myFileInfo = encode(data); outbox.enqueue('file.txt', myFileInfo)
My inbox logic is more or less a straight copy paste of the docs here in the app code here: https://dev.fitbit.com/guides/communications/file-transfer/#receiving-a-file
The only part it is missing, is after the file is ready, you need to read it. You should be able to do that fairly simply with the File System API:
import { readFileSync } from 'fs'; ...all the inbox logic in the above link, after the file is ready... const myFileInfo = readFileSync('file.txt', 'cbor');
I have had reliable success with this method, I was really struggling with the Messaging API. Once I figured this out, I was able to rip out a lot of code and simplify. Let me know if it works or if you have any more questions!
EDIT, didn't really answer your CBOR question. As I understand it, you should be able to CBOR encode any regular JS object. If you could call JSON.stringify on it, you should be able to call encode on it instead.
12-01-2017 05:44
12-01-2017 05:44
Thanks @kenjamin!!!
It seems to be working fine now, as I can transfer file data. Working on the next part now.
I really appreciate your help.
Ps on your sample code there is a typo. It should say
const myFileInfo = fs.readFileSync('file.txt', 'cbor');