2019-10-30 17:33:58 +00:00
|
|
|
Puck.debug=3;
|
|
|
|
|
2019-11-03 11:13:21 +00:00
|
|
|
// FIXME: use UART lib so that we handle errors properly
|
2019-10-30 17:33:58 +00:00
|
|
|
var Comms = {
|
|
|
|
uploadApp : app => {
|
2019-11-10 10:22:33 +00:00
|
|
|
return AppInfo.getFiles(app, httpGet).then(fileContents => {
|
|
|
|
return new Promise((resolve,reject) => {
|
2019-12-05 14:48:56 +00:00
|
|
|
var appJSONFile = fileContents.find(f=>f.name=="+"+app.id);
|
|
|
|
var appJSON = undefined;
|
|
|
|
if (appJSONFile)
|
|
|
|
try {
|
|
|
|
appJSON=JSON.parse(appJSONFile.content);
|
|
|
|
appJSON.id = app.id;
|
|
|
|
} catch(e) {
|
|
|
|
console.log("Error decoding app JSON for",app.id,e);
|
|
|
|
}
|
2019-11-07 21:08:33 +00:00
|
|
|
fileContents = fileContents.map(storageFile=>storageFile.cmd).join("\n")+"\n";
|
2019-11-03 11:13:21 +00:00
|
|
|
console.log("uploadApp",fileContents);
|
|
|
|
// reset to ensure we have enough memory to upload what we need to
|
2019-11-06 15:53:38 +00:00
|
|
|
Puck.write("\x03reset();\n", (result) => {
|
|
|
|
if (result===null) return reject("");
|
|
|
|
setTimeout(() => { // wait for reset
|
2019-11-11 18:48:41 +00:00
|
|
|
Puck.write("\x10E.showMessage('Uploading...')\n"+fileContents+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
|
2019-11-06 15:53:38 +00:00
|
|
|
if (result===null) return reject("");
|
2019-12-05 14:48:56 +00:00
|
|
|
resolve(appJSON);
|
2019-11-03 11:13:21 +00:00
|
|
|
});
|
|
|
|
},500);
|
2019-10-30 17:33:58 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
getInstalledApps : () => {
|
|
|
|
return new Promise((resolve,reject) => {
|
2019-11-06 15:53:38 +00:00
|
|
|
Puck.write("\x03",(result) => {
|
|
|
|
if (result===null) return reject("");
|
2019-12-05 14:48:56 +00:00
|
|
|
Puck.eval('require("Storage").list().filter(f=>f[0]=="+").map(f=>{var j=require("Storage").readJSON(f)||{};j.id=f.substr(1);return j})', (appList,err) => {
|
2019-11-06 15:53:38 +00:00
|
|
|
if (appList===null) return reject(err || "");
|
2019-11-03 11:13:21 +00:00
|
|
|
console.log("getInstalledApps", appList);
|
2019-10-30 17:33:58 +00:00
|
|
|
resolve(appList);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2019-11-03 11:13:21 +00:00
|
|
|
},
|
|
|
|
removeApp : app => { // expects an app structure
|
|
|
|
var cmds = app.storage.map(file=>{
|
|
|
|
return `\x10require("Storage").erase(${toJS(file.name)});\n`;
|
|
|
|
}).join("");
|
|
|
|
console.log("removeApp", cmds);
|
|
|
|
return new Promise((resolve,reject) => {
|
2019-11-11 18:31:39 +00:00
|
|
|
Puck.write("\x03"+cmds+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
|
2019-11-06 15:53:38 +00:00
|
|
|
if (result===null) return reject("");
|
2019-11-03 11:13:21 +00:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2019-11-07 09:26:46 +00:00
|
|
|
},
|
|
|
|
removeAllApps : () => {
|
|
|
|
return new Promise((resolve,reject) => {
|
|
|
|
// Use eval here so we wait for it to finish
|
|
|
|
Puck.eval('require("Storage").eraseAll()||true', (result,err) => {
|
|
|
|
if (result===null) return reject(err || "");
|
|
|
|
Puck.write('\x03\x10reset()\n',(result) => {
|
|
|
|
if (result===null) return reject("");
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
setTime : () => {
|
|
|
|
return new Promise((resolve,reject) => {
|
2020-01-17 11:44:57 +00:00
|
|
|
var d = new Date();
|
|
|
|
var tz = d.getTimezoneOffset()/-60
|
|
|
|
var cmd = '\x03\x10setTime('+(d.getTime()/1000)+');';
|
|
|
|
// in 1v93 we have timezones too
|
|
|
|
cmd += 'E.setTimeZone('+tz+');';
|
|
|
|
cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('@setting',s);})(require('Storage').readJSON('@setting'))\n";
|
|
|
|
Puck.write(cmd, (result) => {
|
2019-11-07 09:26:46 +00:00
|
|
|
if (result===null) return reject("");
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2019-11-12 10:56:31 +00:00
|
|
|
},
|
2019-11-12 14:41:03 +00:00
|
|
|
disconnectDevice: () => {
|
|
|
|
var connection = Puck.getConnection();
|
|
|
|
|
|
|
|
if (!connection) return;
|
|
|
|
|
|
|
|
connection.close();
|
|
|
|
},
|
2019-11-12 10:56:31 +00:00
|
|
|
watchConnectionChange : cb => {
|
|
|
|
var connected = Puck.isConnected();
|
|
|
|
|
|
|
|
//TODO Switch to an event listener when Puck will support it
|
|
|
|
var interval = setInterval(() => {
|
|
|
|
if (connected === Puck.isConnected()) return;
|
|
|
|
|
|
|
|
connected = Puck.isConnected();
|
|
|
|
cb(connected);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
//stop watching
|
|
|
|
return () => {
|
|
|
|
clearInterval(interval);
|
|
|
|
};
|
2019-12-24 13:47:02 +00:00
|
|
|
},
|
|
|
|
listFiles : () => {
|
|
|
|
return new Promise((resolve,reject) => {
|
|
|
|
Puck.write("\x03",(result) => {
|
|
|
|
if (result===null) return reject("");
|
|
|
|
//use encodeURIComponent to serialize octal sequence of append files
|
|
|
|
Puck.eval('require("Storage").list().map(encodeURIComponent)', (files,err) => {
|
|
|
|
if (files===null) return reject(err || "");
|
|
|
|
files = files.map(decodeURIComponent);
|
|
|
|
console.log("listFiles", files);
|
|
|
|
resolve(files);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
readFile : (file) => {
|
|
|
|
return new Promise((resolve,reject) => {
|
|
|
|
//encode name to avoid serialization issue due to octal sequence
|
|
|
|
const name = encodeURIComponent(file);
|
|
|
|
Puck.write("\x03",(result) => {
|
|
|
|
if (result===null) return reject("");
|
2020-01-17 11:44:57 +00:00
|
|
|
//TODO: big files will not fit in RAM.
|
2019-12-24 13:47:02 +00:00
|
|
|
//we should loop and read chunks one by one.
|
|
|
|
//Use btoa for binary content
|
|
|
|
Puck.eval(`btoa(require("Storage").read(decodeURIComponent("${name}"))))`, (content,err) => {
|
|
|
|
if (content===null) return reject(err || "");
|
|
|
|
resolve(atob(content));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2019-10-30 17:33:58 +00:00
|
|
|
}
|
|
|
|
};
|