diff --git a/config.js b/config.js
index 2b7cc77..3a6c6fc 100644
--- a/config.js
+++ b/config.js
@@ -5,7 +5,8 @@ System.config({
"babelOptions": {
"optional": [
"runtime"
- ]
+ ],
+ "stage": 0
},
"paths": {
"github:*": "jspm_packages/github/*",
diff --git a/example/app.js b/example/app.js
index a784ce4..0177d52 100644
--- a/example/app.js
+++ b/example/app.js
@@ -1,21 +1,88 @@
import Doodle3DManager from 'src/doodle3dmanager.js';
-var list = document.getElementById('list');
+let list = document.getElementById('list');
-var doodle3DManager = new Doodle3DManager();
+let doodle3DManager = new Doodle3DManager();
-doodle3DManager.addEventListener('boxappeared', (event) => {
- var box = event.box;
+doodle3DManager.addEventListener('boxappeared', async (event) => {
+ let box = event.box;
- var node = document.createElement('li');
- node.innerHTML = box.boxData.wifiboxid;
- list.appendChild(node);
+ var row = document.createElement('tr');
+ row.style.color = 'black';
+
+ var id = document.createElement('td');
+ var state = document.createElement('td');
+ var localIP = document.createElement('td');
+ var bed = document.createElement('td');
+ var bedTarget = document.createElement('td');
+ var bufferedLines = document.createElement('td');
+ var currentLine = document.createElement('td');
+ var hasControl = document.createElement('td');
+ var hotend = document.createElement('td');
+ var hotendTarget = document.createElement('td');
+ var totalLines = document.createElement('td');
+
+ row.appendChild(id);
+ row.appendChild(localIP);
+ row.appendChild(state);
+ row.appendChild(currentLine);
+ row.appendChild(bufferedLines);
+ row.appendChild(totalLines);
+ row.appendChild(hotend);
+ row.appendChild(hotendTarget);
+ row.appendChild(bed);
+ row.appendChild(bedTarget);
+ row.appendChild(hasControl);
+
+ id.innerHTML = box.boxData.wifiboxid;
+ localIP.innerHTML = box.boxData.localip;
+
+ document.getElementById('table').appendChild(row);
+
+ function update (event) {
+ let data = event.state;
+ state.innerHTML = data.state;
+
+ if (data.state !== 'disconnected' && data.state !== 'connecting' && data.state !== 'unknown') {
+ bed.innerHTML = data.bed;
+ bedTarget.innerHTML = data.bed_target;
+ bufferedLines.innerHTML = data.buffered_lines;
+ currentLine.innerHTML = data.current_line;
+ hasControl.innerHTML = data.has_control;
+ hotend.innerHTML = data.hotend;
+ hotendTarget.innerHTML = data.hotend_target;
+ state.innerHTML = data.state;
+ totalLines.innerHTML = data.total_lines;
+ }
+ else {
+ bed.innerHTML = '';
+ bedTarget.innerHTML = '';
+ bufferedLines.innerHTML = '';
+ currentLine.innerHTML = '';
+ hasControl.innerHTML = '';
+ hotend.innerHTML = '';
+ hotendTarget.innerHTML = '';
+ totalLines.innerHTML = '';
+ }
+ };
+
+ box.setAutoUpdate(true, 1000);
+
+ function update (event) {
+ console.log(event);
+ }
+
+ box.addEventListener('update', update);
+
+ box.addEventListener('disconnect', (event) => {
+ box.removeEventListener('update', update);
+ });
});
doodle3DManager.addEventListener('boxdisappeared', (event) => {
- var box = event.box;
+ let box = event.box;
- for (var node of list.children) {
+ for (let node of list.children) {
if (node.innerHTML === box.boxData.wifiboxid) {
list.removeChild(node);
break;
@@ -23,4 +90,4 @@ doodle3DManager.addEventListener('boxdisappeared', (event) => {
}
});
-doodle3DManager.setAutoUpdate(true);
+doodle3DManager.setAutoUpdate(true, 1000);
diff --git a/example/index.html b/example/index.html
index 90d6884..c89c8a2 100644
--- a/example/index.html
+++ b/example/index.html
@@ -1,22 +1,45 @@
-
+
- Doodle3D Box
+Doodle3D Box
-
-
+
-
+
+
-
-
+
- Doodle3D WiFi-Boxes
+
-
+
+
+
+ ID |
+ Local IP |
+ State |
+ Current Line |
+ Buffered Lines |
+ Total Lines |
+ Hotend |
+ Hotend Target |
+ Bed |
+ Bed Target |
+ Has Control |
+
+
+
-
+
+
\ No newline at end of file
diff --git a/src/configapi.js b/src/configapi.js
index 6090b73..a7b5071 100644
--- a/src/configapi.js
+++ b/src/configapi.js
@@ -5,17 +5,17 @@ export default class {
this.api = api;
}
- get (keys) {
- return rest.get(this.api + 'config/?' + keys.join('=&') + '=');
+ get (...keys) {
+ return rest.get(`${this.api}config/?${keys.join('=&')}=`);
}
getAll () {
- return rest.get(this.api + 'config/all');
+ return rest.get(`${this.api}config/all`);
}
set (data) {
var scope = this;
- return rest.post(this.api + 'config', data);
+ return rest.post(`${this.api}config`, data);
}
}
diff --git a/src/doodle3dapi.js b/src/doodle3dapi.js
index 8466aad..343e24f 100644
--- a/src/doodle3dapi.js
+++ b/src/doodle3dapi.js
@@ -7,6 +7,7 @@ import PrinterAPI from './printerapi.js';
import SketchAPI from './sketchapi.js';
import SystemAPI from './systemapi.js';
import UpdateAPI from './updateapi.js';
+import {sleep} from './utils.js';
export default class extends EventDispatcher {
constructor (boxData) {
@@ -26,12 +27,14 @@ export default class extends EventDispatcher {
this.alive = false;
this.autoUpdate = false;
-
this.state = {};
+
+ this.maxBatchSize = 10*1024;
+ this.maxBufferSize = 1024*1024;
+ this.fullBufferTimeout = 10000;
}
setAutoUpdate (autoUpdate = true, updateInterval = 1000) {
-
this.updateInterval = updateInterval;
if (this.autoUpdate === autoUpdate) {
@@ -41,67 +44,115 @@ export default class extends EventDispatcher {
this.autoUpdate = autoUpdate;
if (autoUpdate) {
- this._initLoop();
+ this._update();
}
return this;
}
- _initLoop () {
-
- var request = this.network.alive();
-
- request.then(() => {
-
- this.alive = true;
-
- this.dispatchEvent({
- type: 'connect'
- });
-
- this._updateStateLoop();
-
- });
-
- request.catch((error) => {
-
- if (this.alive) {
-
- this.alive = false;
+ checkAlive () {
+ return new Promise(async (resolve, reject) => {
+ let alive;
+ try {
+ await this.network.alive();
+ alive = true;
+ }
+ catch (error) {
+ alive = false;
+ }
+ if (alive !== this.alive) {
this.dispatchEvent({
- type: 'disconnect'
+ type: alive ? 'connect' : 'disconnect'
});
}
-
- setTimeout(() => {
- this._initLoop();
- }, this.updateInterval);
+
+ this.alive = alive;
+ resolve(alive);
});
}
- _updateStateLoop () {
-
- this.info.status().then((state) => {
- this.state = state;
-
- this.dispatchEvent({
- type: 'update',
- state
- });
-
- if (this.autoUpdate) {
- setTimeout(() => {
- this._updateStateLoop();
- }, this.updateInterval);
+ sendGCode (gcode) {
+ return new Promise(async (resolve, reject) => {
+ let printerState = await this.printer.state();
+ if (printerState.state !== 'idle') {
+ reject(`Cannot print, print state is ${printerState.state}`);
+ return;
}
- }).catch((error) => {
- if (this.autoUpdate) {
- setTimeout(() => {
- this._initLoop();
- }, this.updateInterval);
+ if (!gcode.endsWith('\n')) {
+ gcode += '\n';
}
+
+ this._currentBatch = 0;
+
+ let lastIndex = 0;
+ let start = true;
+ while (lastIndex !== gcode.length) {
+ let index = gcode.lastIndexOf('\n', lastIndex + this.maxBatchSize);
+ let batch = gcode.substring(lastIndex, index);
+
+ let progress = await this.printer.progress();
+
+ if (progress['buffered_lines'] + batch.length < this.maxBufferSize) {
+ lastIndex = index + 1; //skip next \n
+
+ await this._sendBatch(batch, start);
+
+ start = false;
+ }
+ else {
+ await sleep(this.fullBufferTimeout);
+ }
+ }
+
+ resolve();
});
}
-}
\ No newline at end of file
+
+ async _update () {
+ let alive = await this.checkAlive();
+ if (alive) {
+ while (this.autoUpdate) {
+ try {
+ this.state = await this.info.status();
+
+ this.dispatchEvent({
+ type: 'update',
+ state: this.state
+ });
+
+ await sleep(this.updateInterval);
+ }
+ catch (error) {
+ this._update();
+ break;
+ }
+ }
+ }
+ else {
+ await sleep(this.updateInterval);
+
+ this._update();
+ }
+ }
+
+ _sendBatch (gcode, index) {
+ return new Promise (async (resolve, reject) => {
+ try {
+ let start = index === 0;
+ let first = start;
+ let printRequest = await this.printer.print(gcode, first, start);
+
+ console.log(`batch sent: ${index}`, printRequest);
+ }
+ catch (error) {
+ await sleep(1000);
+
+ await this._sendBatch(gcode, index);
+ }
+
+ resolve();
+ });
+ }
+}
diff --git a/src/doodle3dmanager.js b/src/doodle3dmanager.js
index 51fc774..5d8fe1b 100644
--- a/src/doodle3dmanager.js
+++ b/src/doodle3dmanager.js
@@ -1,43 +1,97 @@
import * as rest from './restapi.js';
import Doodle3DAPI from './doodle3dapi.js';
import EventDispatcher from 'casperlamboo/EventDispatcher';
+import {sleep} from './utils.js';
export default class extends EventDispatcher {
constructor () {
super();
+ this.api = 'http://connect.doodle3d.com/api/';
+
this.boxes = [];
+
this.nonServerBoxes = [{
wifiboxid: 'Wired Printer',
localip: '192.168.5.1'
- }, {
+ }/*, {
wifiboxid: 'Node JS Server',
- localip: '127.0.0.1:2000'
- }];
+ localip: '127.0.0.1:3000'
+ }*/];
this.checkNonServerBoxes = true;
- this.api = 'http://connect.doodle3d.com/api/';
+
+ this.autoUpdate = false;
}
- setAutoUpdate (autoUpdate = true, rate = 5000) {
+ setAutoUpdate (autoUpdate = true, updateInterval = 1000) {
+ this.updateInterval = updateInterval;
+
+ if (this.autoUpdate === autoUpdate) {
+ return;
+ }
+
+ this.autoUpdate = autoUpdate;
+
if (autoUpdate) {
this._update();
-
- if (this.interval !== undefined) {
- clearInterval(this.interval);
- }
-
- this.interval = setInterval(() => {
- this._update();
- }, rate);
- }
- else if (this.interval !== undefined) {
- clearInterval(this.interval);
- delete this.interval;
}
return this;
}
+ async _update () {
+ while (this.autoUpdate) {
+ await this._checkAlive();
+ await this._checkNew();
+
+ await sleep(this.updateInterval);
+ }
+ }
+
+ _checkAlive () {
+ return new Promise(async (resolve, reject) => {
+ for (let box of this.boxes) {
+ let alive = await box.checkAlive();
+
+ if (!alive) {
+ this._removeBox(box);
+ }
+ }
+ resolve();
+ });
+ }
+
+ _checkNew () {
+ return new Promise(async (resolve, reject) => {
+ try {
+ let boxes = await rest.get(`${this.api}list.php`);
+
+ if (this.checkNonServerBoxes) {
+ boxes = boxes.concat(this.nonServerBoxes);
+ }
+
+ let knownIPs = this.boxes.map((box) => box.boxData.localip);
+
+ for (let boxData of boxes) {
+ if (knownIPs.indexOf(boxData.localip) === -1) {
+ let box = new Doodle3DAPI(boxData);
+
+ let alive = await box.checkAlive();
+
+ if (alive) {
+ this._addBox(box);
+ }
+ }
+ }
+
+ resolve();
+ }
+ catch (error) {
+ console.warn('fail connecting to Doodle3D server');
+ }
+ });
+ }
+
_addBox (box) {
this.boxes.push(box);
@@ -48,7 +102,7 @@ export default class extends EventDispatcher {
}
_removeBox (box) {
- var index = this.boxes.indexOf(box);
+ let index = this.boxes.indexOf(box);
if (index !== -1) {
this.boxes.splice(index, 1);
this.dispatchEvent({
@@ -57,52 +111,4 @@ export default class extends EventDispatcher {
});
}
}
-
- _update () {
- this._checkAlive();
- this._checkNew();
- }
-
- _checkAlive () {
- for (var box of this.boxes) {
- ((box) => {
- var request = box.network.alive();
- request.catch(() => {
- this._removeBox(box);
- });
- })(box);
- }
- }
-
- _checkNew () {
-
- var request = rest.get(this.api + 'list.php');
- request.then((boxes) => {
-
- if (this.checkNonServerBoxes) {
- boxes = boxes.concat(this.nonServerBoxes);
- }
-
- var knownIPs = this.boxes.map((box) => box.boxData.localip);
-
- for (var boxData of boxes) {
- if (knownIPs.indexOf(boxData.localip) === -1) {
- var box = new Doodle3DAPI(boxData);
- ((box) => {
- var request = box.network.alive();
- request.then((data, msg) => {
- this._addBox(box);
- });
- request.catch(() => {
- console.log(`failed to connect with ${box.boxData.wifiboxid}`);
- });
-
- })(box);
- }
- }
- });
- request.catch(() => {
- console.warn('fail connecting to Doodle3D server');
- });
- }
-}
\ No newline at end of file
+}
diff --git a/src/infoapi.js b/src/infoapi.js
index 99b17d9..8193845 100644
--- a/src/infoapi.js
+++ b/src/infoapi.js
@@ -6,18 +6,18 @@ export default class {
}
get () {
- return rest.get(this.api + 'info');
+ return rest.get(`${this.api}info`);
}
status () {
- return rest.get(this.api + 'info/status');
+ return rest.get(`${this.api}info/status`);
}
downloadLogFiles () {
- window.location = this.api + 'info/logfiles';
+ window.location = `${this.api}info/logfiles`;
}
acces () {
- return rest.get(this.api + 'info/access');
+ return rest.get(`${this.api}info/access`);
}
-}
\ No newline at end of file
+}
diff --git a/src/networkapi.js b/src/networkapi.js
index d75b368..1f3bd59 100644
--- a/src/networkapi.js
+++ b/src/networkapi.js
@@ -6,47 +6,50 @@ export default class {
}
scan () {
- return rest.get(this.api + 'network/scan');
+ return rest.get(`${this.api}network/scan`);
}
known () {
- return rest.get(this.api + 'network/known');
+ return rest.get(`${this.api}network/known`);
}
status () {
- return rest.get(this.api + 'network/status');
+ return rest.get(`${this.api}network/status`);
}
- assosiate (ssid, phrase = null, recreate = false) {
- var data = {ssid, recreate};
- if (phrase) data.phrase = phrase;
+ assosiate (ssid, phrase, recreate = false) {
+ var data = {
+ ssid,
+ recreate,
+ phrase
+ };
- return rest.post(this.api + 'network/associate', data);
+ return rest.post(`${this.api}network/associate`, data);
}
disassosiate () {
//not tested
- return rest.post(this.api + 'network/disassociate', {});
+ return rest.post(`${this.api}network/disassociate`, {});
}
openAccesPoint () {
//not tested
- return rest.post(this.api + 'network/openap', {});
+ return rest.post(`${this.api}network/openap`, {});
}
remove (ssid) {
- return rest.post(this.api + 'network/remove', {
+ return rest.post(`${this.api}network/remove`, {
'ssid': ssid
});
}
signin () {
- return rest.get(this.api + 'network/signin');
+ return rest.get(`${this.api}network/signin`);
}
alive () {
- return rest.get(this.api + 'network/alive');
+ return rest.get(`${this.api}network/alive`);
}
-}
\ No newline at end of file
+}
diff --git a/src/printerapi.js b/src/printerapi.js
index cad58e1..ef649a8 100644
--- a/src/printerapi.js
+++ b/src/printerapi.js
@@ -3,106 +3,43 @@ import * as rest from './restapi.js';
export default class {
constructor (api) {
this.api = api;
-
- this._printBatches = [];
- this._currentBatch = 0;
-
- this.maxBatchSize = 10*1024;
- this.maxBufferedLines = 1024*1024;
- this.fullBufferTimeout = 10000;
}
temperature () {
- return rest.get(this.api + 'printer/temperature');
+ return rest.get(`${this.api}printer/temperature`);
}
progress () {
- return rest.get(this.api + 'printer/progress');
+ return rest.get(`${this.api}printer/progress`);
}
state () {
- return rest.get(this.api + 'printer/state');
+ return rest.get(`${this.api}printer/state`);
}
listAll () {
- return rest.get(this.api + 'printer/listall');
+ return rest.get(`${this.api}printer/listall`);
}
heatup () {
- return rest.post(this.api + 'printer/heatup', {});
+ return rest.post(`${this.api}printer/heatup`, {});
}
- sendGCode (gcode) {
- if (!gcode.endsWith('\n')) {
- gcode += '\n';
- }
+ print (gcode = '', first = false, start = false, last) {
+ let data = {
+ gcode,
+ first,
+ start,
+ last
+ };
- this._currentBatch = 0;
-
- var lastIndex = 0;
- while (lastIndex !== gcode.length) {
- var index = gcode.lastIndexOf('\n', lastIndex + this.maxBatchSize);
- var batch = gcode.substring(lastIndex, index);
- lastIndex = index + 1; //skip next return
-
- this._printBatches.push(batch);
- }
-
- this._sendBatch();
- }
-
- _sendBatch () {
- var gcode = this._printBatches.shift();
- var start = (this._currentBatch === 0) ? true : false;
- var first = (this._currentBatch === 0) ? true : false;
- var last = (this._printBatches.length === 0) ? true : false; //only for the node js server
-
- var printRequest = this.print(gcode, start, first, last);
- printRequest.then((data) => {
-
- console.log('batch sent: ' + this._currentBatch, data);
-
- var progressRequest = this.progress()
- progressRequest.then((progress) => {
-
- if (this._printBatches.length > 0) {
- if (progress['buffered_lines'] + this.maxBatchSize < this.maxBufferedLines) {
- this._currentBatch ++;
- this._sendBatch();
- }
- else {
- setTimeout(() => {
- this._sendBatch();
- }, this.fullBufferTimeout);
- }
-
- }
- else {
- console.log('Finish sending gcode to printer');
- }
-
- });
- });
- printRequest.catch((error) => {
- this._printBatches.unshift(gcode);
-
- setTimeout(() => {
- this._sendBatch();
- }, 1000);
- });
- }
-
- print (gcode = '', first = false, start = false, last = false) {
- var data = {gcode, first, start}
- if (last) data.last = last;
-
- return rest.post(this.api + 'printer/print', data);
+ return rest.post(`${this.api}printer/print`, data);
}
stop (gcode = '') {
this._currentBatch = 0;
this._printBatches = [];
- return rest.post(this.api + 'printer/stop', {gcode});
+ return rest.post(`${this.api}printer/stop`, {gcode});
}
-}
\ No newline at end of file
+}
diff --git a/src/restapi.js b/src/restapi.js
index 0f00c52..32371f7 100644
--- a/src/restapi.js
+++ b/src/restapi.js
@@ -1,15 +1,12 @@
import $ from 'jquery';
export function get (url) {
-
return new Promise((resolve, reject) => {
-
$.ajax({
url: url,
dataType: 'json',
timeout: 5000,
success: (response) => {
-
if (response.status === 'success') {
resolve(response.data, response.msg);
}
@@ -17,15 +14,12 @@ export function get (url) {
reject(response.msg);
}
}
- }).fail(reject);
-
+ }).fail(reject);
});
}
export function post (url, data) {
-
return new Promise((resolve, reject) => {
-
$.ajax({
url: url,
type: 'POST',
@@ -33,14 +27,12 @@ export function post (url, data) {
dataType: 'json',
timeout: 10000,
success: (response) => {
-
if (response.status === 'success') {
resolve(response.data);
}
else {
reject(response.msg);
}
-
}
}).fail(reject);
});
diff --git a/src/sketchapi.js b/src/sketchapi.js
index c8b8e94..c22d46c 100644
--- a/src/sketchapi.js
+++ b/src/sketchapi.js
@@ -6,20 +6,20 @@ export default class {
}
getSketch (id) {
- return rest.get(this.api + 'sketch/?id=' + id);
+ return rest.get(`${this.api}sketch/?id=${id}`);
}
set (data = '') {
- return rest.post(this.api + 'sketch', {
+ return rest.post(`${this.api}sketch`, {
data
});
}
status () {
- return rest.get(this.api + 'sketch/status');
+ return rest.get(`${this.api}sketch/status`);
}
clear () {
- return rest.post(this.api + 'sketch/clear');
+ return rest.post(`${this.api}sketch/clear`);
}
-}
\ No newline at end of file
+}
diff --git a/src/systemapi.js b/src/systemapi.js
index 15c4eda..b2b4e37 100644
--- a/src/systemapi.js
+++ b/src/systemapi.js
@@ -6,6 +6,6 @@ export default class {
}
versions () {
- return rest.get(this.api + 'system/fwversions');
+ return rest.get(`${this.api}system/fwversions`);
}
-}
\ No newline at end of file
+}
diff --git a/src/updateapi.js b/src/updateapi.js
index 9dbdd93..88f980c 100644
--- a/src/updateapi.js
+++ b/src/updateapi.js
@@ -6,24 +6,24 @@ export default class {
}
status () {
- return rest.get(this.api + 'update/status');
+ return rest.get(`${this.api}update/status`);
}
download () {
//not tested
- return rest.post(this.api + 'update/download', {});
+ return rest.post(`${this.api}update/download`, {});
}
install () {
//not tested
- return rest.post(this.api + 'update/install', {});
+ return rest.post(`${this.api}update/install`, {});
}
clear () {
//not tested
- return rest.post(this.api + 'update/clear', {});
+ return rest.post(`${this.api}update/clear`, {});
}
-}
\ No newline at end of file
+}
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..1489a75
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,7 @@
+export function sleep (time) {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolve();
+ }, time);
+ });
+}