diff --git a/Gruntfile.js b/Gruntfile.js
index 5c44197..7492534 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -101,6 +101,7 @@ module.exports = function(grunt) {
ConfigAPI: true,
PrinterAPI: true,
UpdateAPI:true,
+ ServerAPI:true,
addToHomescreen: true
},
browser: true,
diff --git a/js/BoxPage.js b/js/BoxPage.js
index 1f336d6..1b4890c 100644
--- a/js/BoxPage.js
+++ b/js/BoxPage.js
@@ -118,11 +118,25 @@
_intro.text(introText);
_intro.toggleClass("ui-screen-hidden",(introText === ""));
+ //printLink
+ var _printItem = _list.find("#printItem");
+ var printLink = _printItem.find("a").attr("href");
+ printLink = d3d.util.replaceURLParameters(printLink,_boxData);
+ _printItem.find("a").attr("href",printLink);
+
+
+
+ if (d3d && d3d.pageParams && d3d.pageParams.uuid) {
+ _drawItem.hide();
+ _printItem.show();
+ }
+
+
//settingsLink
- var settingsLink = _settingsItem.find("a").attr("href");
- settingsLink = d3d.util.replaceURLParameters(settingsLink,_boxData);
- _settingsItem.find("a").attr("href",settingsLink);
- _settingsItem.toggleClass("ui-screen-hidden",false);
+ // var settingsLink = _settingsItem.find("a").attr("href");
+ // settingsLink = d3d.util.replaceURLParameters(settingsLink,_boxData);
+ // _settingsItem.find("a").attr("href",settingsLink);
+ // _settingsItem.toggleClass("ui-screen-hidden",false);
// ToDo: update footer with network info
diff --git a/js/PrintPage.js b/js/PrintPage.js
new file mode 100644
index 0000000..6108a23
--- /dev/null
+++ b/js/PrintPage.js
@@ -0,0 +1,210 @@
+/*
+ * This file is part of the Doodle3D project (http://doodle3d.com).
+ *
+ * Copyright (c) 2013-2017, Doodle3D
+ * This software is licensed under the terms of the GNU GPL v2 or later.
+ * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
+ */
+
+ (function (w) {
+
+ var _serverAPI = new ServerAPI();
+ var _connectAPI = new ConnectAPI();
+ var _infoAPI = new InfoAPI();
+ var _networkAPI = new NetworkAPI();
+ var _printerAPI = new PrinterAPI();
+ var _configAPI = new ConfigAPI();
+ var PAGE_ID = "#print";
+ var _pageData = {};
+ var _self = this;
+ var _wifiboxSettings;
+ var _slicerSettings;
+
+ $.mobile.document.on("pagebeforeshow", PAGE_ID, function( event, data ) {
+ _pageData = d3d.util.getPageParams(PAGE_ID);
+
+ if(_pageData === undefined) {
+ console.log("ERROR",PAGE_ID,"_pageData undefined");
+ $.mobile.changePage("#boxes");
+ return;
+ }
+ var boxURL = "http://"+_pageData.localip;
+
+ //disabled by default
+ $("#btnPrint").button().on("click", print);
+ $("#btnPrint").button('disable');
+
+ loadGCodeInfoFromServer(d3d.pageParams.uuid);
+
+ _connectAPI.list(function(successData) {
+ console.log("_connectAPI.list success",successData);
+ $("#lstBoxes").empty();
+ $("#lstBoxes").append($(""));
+
+ for (var i in successData) {
+ var box = successData[i];
+
+ var selected = (box.localip===_pageData.localip) ? "selected " : "";
+
+ $("#lstBoxes").append($(""));
+ }
+ $("#lstBoxes").append($(""));
+
+ $("#lstBoxes").selectmenu("refresh", true);
+
+ if (_pageData.localip) {
+ onSelectWiFiBox(_pageData.localip);
+ }
+
+ }, function(failData) {
+ console.log("_connectAPI.list failData",failData);
+ });
+
+ $("#lstBoxes").on("change", function(data) {
+ var ip = $(this).val();
+ console.log("lstBoxes change",ip);
+ onSelectWiFiBox(ip);
+ });
+
+ });
+
+ $.mobile.document.on( "pagebeforehide", PAGE_ID, function( event, data ) {
+ _connectAPI.stop();
+ });
+
+ function onSelectWiFiBox(ip) {
+ $("#infoWiFiBox").text("");
+
+ if (!ip) {
+ $("#btnPrint").button('disable');
+ return;
+ }
+ else if (ip==="other") {
+ // redirect
+ $.mobile.changePage("#boxes");
+ } else {
+ var boxURL = "http://"+ip;
+ _infoAPI.init(boxURL);
+ _networkAPI.init(boxURL);
+ _printerAPI.init(boxURL);
+ _configAPI.init(boxURL);
+
+ _networkAPI.status(function(successData) {
+ console.log("network status",successData);
+ // $("#lstPrint li.boxItem p").text(
+ var netInfo = successData.statusMessage + " (" + successData.ssid + " @ " + successData.localip + ")";
+
+ _infoAPI.getStatus(function(successData) {
+ console.log(successData);
+ var state = successData.state;
+ if (state==="idle") {
+ state="ready";
+ $("#btnPrint").button('enable');
+ }
+
+ var info = netInfo + " - Printer status: ";
+ info += ""+state+"";
+ $("#infoWiFiBox").html(info);
+ }, function(failData) {
+ console.log(failData);
+ $("#infoWiFiBox").html("failed to retrieve printer status from WiFi-Box");
+ });
+
+
+ }, function(failData) {
+ console.log("_networkAPI status failed",failData);
+ $("#infoWiFiBox").html("failed to retrieve network status from WiFi-Box");
+ });
+
+ }
+ }
+
+ function print() {
+
+ _configAPI.loadAll(function(successData) {
+ _wifiboxSettings = successData;
+ var slicerPrinterType = _slicerSettings.type;
+ var wifiboxPrinterType = _wifiboxSettings["printer.type"];
+
+ if (slicerPrinterType!==wifiboxPrinterType) {
+ var override = window.confirm("The GCODE file was sliced for '"+slicerPrinterType+"'.\n"+
+ "Your WiFi-Box is currently configured for '"+wifiboxPrinterType+"'\n\n"+
+ "Do you want to override the settings on your WiFi-Box with the new settings from the slicer?");
+
+ if (override) {
+ //
+ _configAPI.savePrinterType(slicerPrinterType,function(successData) {
+ console.log(successData);
+ window.alert(successData.validation["printer.type"] + " (printer.type)");
+ },function(failData) {
+ window.alert("Could not save printer type '",slicerPrinterType,"')' to WiFi-Box");
+ });
+ }
+ }
+ });
+
+ if (true) {
+ return;
+ }
+
+ //var startcode = _configAPI.subsituteVariables(_wifiboxSettings["printer.startcode"],_wifiboxSettings);
+ //var endcode = _configAPI.subsituteVariables(_wifiboxSettings["printer.endcode"],_wifiboxSettings);
+
+ var data = {
+ "id": d3d.pageParams.uuid,
+ // "start_code": startcode,
+ // "end_code": endcode
+ };
+
+ //console.log("fetchPrint",d3d.pageParams.uuid,data);
+ _printerAPI.fetch(data,function(successData) {
+ console.log("fetchPrint success",successData);
+
+ var url = d3d.util.replaceURLParameters("#control",_pageData);
+ $.mobile.changePage(url);
+
+ },function(failData) {
+ console.log("fetchPrint fail",failData);
+ window.alert("Problem: " + failData.msg);
+ });
+ }
+
+ function clearInfo() {
+ $("#infoFile").text("...");
+ $("#infoPrinter").text("...");
+ $("#infoMaterial").html("...");
+ $("#iconPrinter").attr('src','img/icons/blank.png');
+ }
+
+ function loadGCodeInfoFromServer(uuid) {
+ _serverAPI.init("https://gcodeserver.doodle3d.com");
+
+ _serverAPI.getInfo(uuid, function(successData) {
+ console.log("getInfo success",successData);
+ var filesize = d3d.util.formatBytes(successData["bytes"]);
+
+ _serverAPI.fetchHeader(d3d.pageParams.uuid,function(successData) {
+ console.log("_serverAPI fetchHeader success",successData);
+ var header = successData;
+ _slicerSettings = header; //copy header json data into _slicerSettings
+ var printerId = header.type;
+
+ $("#infoFile").text(header.name + " (" + filesize + ")");
+ $("#infoPrinter").text(printerId);
+ $("#infoMaterial").html(header.filamentThickness + "mm @ " + header.temperature + "°C");
+ $("#iconPrinter").attr('src','img/icons/printers/'+printerId+'.png');
+
+ }, function(failData) {
+ console.log("_serverAPI fetchHeader fail",failData);
+ clearInfo();
+ });
+
+
+ },function(failData) {
+ clearInfo();
+ });
+
+ }
+
+
+})(window);
diff --git a/js/api/InfoAPI.js b/js/api/InfoAPI.js
index 474b764..fd299e2 100644
--- a/js/api/InfoAPI.js
+++ b/js/api/InfoAPI.js
@@ -58,4 +58,22 @@ function InfoAPI() {
if(failedHandler) failedHandler();
});
};
+
+ this.getStatus = function(completeHandler,failedHandler) {
+ $.ajax({
+ url: _wifiboxURL + "/info/status",
+ type: "GET",
+ dataType: 'json',
+ timeout: _timeoutTime,
+ success: function(response){
+ if (response.status == "error" || response.status == "fail") {
+ if (failedHandler) failedHandler(response);
+ } else {
+ if (completeHandler) completeHandler(response.data);
+ }
+ }
+ }).fail(function() {
+ if (failedHandler) failedHandler();
+ });
+ };
}
\ No newline at end of file
diff --git a/js/api/PrinterAPI.js b/js/api/PrinterAPI.js
index cd044ce..8e1f6c5 100644
--- a/js/api/PrinterAPI.js
+++ b/js/api/PrinterAPI.js
@@ -46,4 +46,71 @@ function PrinterAPI() {
if(failedHandler) failedHandler();
});
};
+
+ this.fetch = function(data, completeHandler,failedHandler) {
+ console.log("fetch",_wifiboxURL,data);
+
+ $.ajax({
+ url: _wifiboxURL + "/printer/fetch",
+ type: "POST",
+ dataType: 'json',
+ data: data,
+ timeout: _timeoutTime,
+ success: function(response){
+ console.log("printerAPI.fetch response=",response);
+ if(response.status == "error" || response.status == "fail") {
+ if (failedHandler) failedHandler(response);
+ } else {
+ if (completeHandler) completeHandler(response.data);
+ }
+ }
+ }).fail(function() {
+ if(failedHandler) failedHandler();
+ });
+ };
+
+ this.print = function(data, completeHandler,failedHandler) {
+ // data = { "gcode": gcode, "first": first, "start": start },
+ console.log("print",_wifiboxURL,data);
+
+ $.ajax({
+ url: _wifiboxURL + "/printer/print",
+ type: "POST",
+ dataType: 'json',
+ data: data,
+ timeout: _timeoutTime,
+ success: function(response){
+ console.log("printerAPI.print response=",response);
+ if(response.status == "error" || response.status == "fail") {
+ if (failedHandler) failedHandler(response);
+ } else {
+ if (completeHandler) completeHandler(response.data);
+ }
+ }
+ }).fail(function() {
+ if (failedHandler) failedHandler();
+ });
+ };
+
+ this.stop = function(data, completeHandler, failedHandler) {
+ console.log("stop",_wifiboxURL,data);
+
+ $.ajax({
+ url: _wifiboxURL + "/printer/stop",
+ type: "POST",
+ dataType: 'json',
+ data: data,
+ timeout: _timeoutTime,
+ success: function(response){
+ console.log("printerAPI.stop response=",response);
+ if(response.status == "error" || response.status == "fail") {
+ if (failedHandler) failedHandler(response);
+ } else {
+ if (completeHandler) completeHandler(response.data);
+ }
+ }
+ }).fail(function() {
+ if (failedHandler) failedHandler();
+ });
+ };
}
\ No newline at end of file
diff --git a/js/api/ServerAPI.js b/js/api/ServerAPI.js
new file mode 100644
index 0000000..bc6cbe7
--- /dev/null
+++ b/js/api/ServerAPI.js
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the Doodle3D project (http://doodle3d.com).
+ *
+ * Copyright (c) 2013, Doodle3D
+ * This software is licensed under the terms of the GNU GPL v2 or later.
+ * See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
+ */
+
+function ServerAPI() {
+ var _apiURL = "";
+ var _timeoutTime = 6000;
+
+ this.init = function(url) {
+ _apiURL = url;
+ }
+
+ this.getInfo = function(uuid, completeHandler, failedHandler) {
+ console.log("ServerAPI:getInfo");
+
+ $.ajax({
+ url: _apiURL + "/info/" + uuid,
+ type: "GET",
+ dataType: 'json',
+ timeout: _timeoutTime,
+ cache: false,
+ success: function(response) {
+ if (completeHandler) completeHandler(response);
+ }
+ }).fail(function(response) {
+ if (failedHandler) failedHandler(response.responseJSON);
+ });
+ };
+
+ this.fetch = function(uuid, chunk, completeHandler, failedHandler) {
+ console.log("ServerAPI:fetch",uuid,chunk);
+
+ if (!uuid) {
+ console.log("Server.fetch failed: no uuid");
+ if (failedHandler) failedHandler();
+ return;
+ }
+
+ if (!chunk) {
+ chunk = 0;
+ }
+
+ $.ajax({
+ url: _apiURL + "/fetch/" + uuid + "/" + chunk,
+ type: "GET",
+ dataType: 'text', //no json but text
+ timeout: _timeoutTime,
+ cache: false,
+ success: function(response) {
+ if (completeHandler) completeHandler(response);
+ }
+ }).fail(function(response) {
+ console.log("ServerAPI:fetch fail response:",response);
+ if (failedHandler) failedHandler(response.responseJSON);
+ });
+ };
+
+ this.fetchHeader = function(uuid,completeHandler,failedHandler) {
+ this.fetch(uuid,0,function(successData) {
+ console.log("_serverAPI fetchHeader");
+ if (successData) {
+ var items = successData.split("\n");
+ try {
+ var headerText = items[0].substr(1);
+ var headerJSON = JSON.parse(headerText);
+ // console.log("fetchHeader",headerJSON)
+ if (completeHandler) completeHandler(headerJSON);
+ } catch (e) {
+ console.log("fetchHeader failed to parse JSON",e);
+ if (failedHandler) failedHandler();
+ }
+ }
+ }, function(failData) {
+ console.log("_serverAPI fetchHeader failed",failData);
+ });
+ };
+
+}
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
index 62b3d36..efb0b21 100644
--- a/js/main.js
+++ b/js/main.js
@@ -97,8 +97,29 @@ d3d.util = {
if (!("autofocus" in document.createElement("input"))) {
var target = form.find("input[autofocus]:visible");
target.focus();
- }
- }
+ }
+ },
+
+ getQueryParam:function(param) {
+ var result = window.location.search.match(new RegExp("(\\?|&)" + param + "(\\[\\])?=([^&]*)"));
+ return result ? result[3] : false;
+ },
+
+ formatBytes:function(a,b) {
+ if (0===a) {
+ return "0 Bytes";
+ } else {
+ var c=1e3,d=b||2,e=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"];
+ var f=Math.floor(Math.log(a)/Math.log(c));
+ return parseFloat((a/Math.pow(c,f)).toFixed(d))+" "+e[f];
+ }
+ },
+
+ formatPercentage:function(cur,total) {
+ console.log("formatPercentage",cur,total);
+ return Math.round(cur/total*100) + "%";
+ },
+
};
(function (w) {
@@ -106,6 +127,9 @@ d3d.util = {
// only pagecontainer events contain url's
// we parse the parameters and store them in a global object
d3d.pageParams = {};
+ d3d.pageParams.uuid = d3d.util.getQueryParam("uuid");
+ console.log(d3d.pageParams.uuid);
+
$.mobile.document.on( "pagebeforechange", function( event, data ) {
if (typeof data.toPage !== "string") { return; }
var url = d3d.util.parseURL(data.toPage);
@@ -119,4 +143,14 @@ d3d.util = {
// make sure that the parameters are not removed from the visible url
event.preventDefault();
});
+
+ if (d3d.pageParams.uuid) { //connect was opened with printlink
+ var localip = localStorage.getItem("localip");
+ var url = "?uuid="+d3d.pageParams.uuid+"#print";
+ if (localip) {
+ url += "?localip=" + localip;
+ }
+ location.href = url;
+ }
+
})(window);
\ No newline at end of file
diff --git a/less/styles.less b/less/styles.less
index 69d7c80..819998f 100644
--- a/less/styles.less
+++ b/less/styles.less
@@ -210,4 +210,17 @@ html head + body .ui-body-a.ui-focus {
.ath-container:before {
color: #F18DB1;
}
-}
\ No newline at end of file
+}
+
+#infoWiFiBox .idle, #infoWiFiBox .ready {
+ color: #5fba7d;
+}
+
+#infoWiFiBox .disconnected, #infoWiFiBox .connecting, #infoWiFiBox .stopping, #infoWiFiBox .error {
+ color: red;
+}
+
+#infoWiFiBox .printing {
+ color: #93CAF4;
+}
+
diff --git a/www/index.html b/www/index.html
index 5321890..ef908c6 100644
--- a/www/index.html
+++ b/www/index.html
@@ -22,6 +22,7 @@
+
@@ -66,8 +67,9 @@
- Draw
+ - Print
- - Settings
+
- Firmware Update
- Join network
@@ -75,6 +77,53 @@
+
+
+
+
+
Let's 3D-print your model by sending it to your printer over WiFi. Please check the settings below and press Print.
+
+
+
+
+ -
+
+
File to print
+ ...
+
+
+ -
+
+
3D-Printer
+ ...
+
+
+ -
+
+
Material
+ ...
+
+
+
+
+ Please select your Doodle3D WiFi-Box:
+
+ -
+
+
+
...
+
+
+
+
+
+
+
@@ -377,8 +426,8 @@