0
0
mirror of https://github.com/Doodle3D/doodle3d-connect.git synced 2024-12-26 02:23:48 +01:00

Merge branch 'master' into develop

This commit is contained in:
Rick Companje 2017-08-14 17:49:14 +02:00
commit 4d21b3db9d
29 changed files with 1517 additions and 47 deletions

View File

@ -99,7 +99,9 @@ module.exports = function(grunt) {
NetworkAPI: true, NetworkAPI: true,
InfoAPI: true, InfoAPI: true,
ConfigAPI: true, ConfigAPI: true,
PrinterAPI: true,
UpdateAPI:true, UpdateAPI:true,
ServerAPI:true,
addToHomescreen: true addToHomescreen: true
}, },
browser: true, browser: true,

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# doodle3d-connect
The Doodle3D connect system allows users / applications to find their Doolde3D WiFi-Box(es) on the same WiFi network. The benefit over other systems is that this doesn't require an application with Bonjour-like support, it can be used by a website using Javascript. Visit http://connect.doodle3d.com to scan your local network for Doodle3D WiFi-Boxes.
The following image shows a typical doodle3d-connect page. The most common way to get here is:
1. with an active internet connection visit http://connect.doodle3d.com
2. connect to a Doodle3D-123456 WiFi accesspoint.
3. wait a couple of seconds. Your WiFi-Box should appear in the list.
![connect.doodle3d.com](https://cloud.githubusercontent.com/assets/156066/15451030/645fd5ae-1fb0-11e6-9521-e2271c1d2bc5.png)
#How does it work?
![Diagram of doodle3d-connect](https://cloud.githubusercontent.com/assets/156066/15450961/519baea0-1fad-11e6-9b58-9ca597db0a55.png)
##Server
The Doodle3D connect server has an api with 2 methods:
###list
Retrieve a list of connected WiFi-Boxes that are on the same remote IP and that signed-in less than an hour ago. The remote IP is the IP adres you're behind on the internet. Usually when you're on a network all devices on that network have the same remote IP. It returns the following information per WiFi-Box:
id: The unique identifier per box, which is a combination of it's remote IP and local IP.
remoteip: The remote IP of the box.
localip: The local IP of the box. (Web)App's can access WiFi-Boxes behind this IP.
wifiboxid: The human readable identifier, that is usually displayed to the user.
hidden: This is planned feature. When a box is hidden the connect interface can hide the box and have users enter the wifiboxid before it releases the information.
data: Sign-in date.
Current url: http://connect.doodle3d.com/api/list.php
Example url: http://connect.doodle3d.com/api/list.example
###signin
Used to sign-in into the connect system. Requires:
localip: The local IP of the WiFi-Box on the local network.
wifiboxid: A custom human readable name to identify the WiFi-Box.
From the request it will determine the remote IP and the date. This request will also remove sign-ins from more than an hour ago.
##WiFi-Box
The WiFi-Box will perform a scan for WiFi networks, when a known network is available it will join this network. When no known network is found it will become a access point. This means a fresh WiFi-Box will always become a access point.
When a WiFi network is joined the WiFi-Box will attempt to Sign-in, when this fails it will retry a couple of times. From then on it will attempt a sign-in every 15 minutes. It also attempt a sign-in when the wifibox id is changed.
The WiFi-Box has a couple of API methods required for the connect system:
network/alive. A very simple method that doesn't contain any logic or info. It's just something (Web)App's can query to check whether there is something behind a local IP adres. Similar to a ping.
##(Web)App
(Web)Apps can use the connect system to find WiFi-Boxes on the same network.
They continuely query the list api method to retrieve local WiFi-Boxes information. Because the server can't know their current status the (Wep)App should query the alive api method of the WiFi-Boxes. When it get's a valid response the WiFi-Box can be shown to the user. Besides querying the boxes it retrieves through the list api The Web(App) should also continuesly query the alive method of boxes that are already shown. To make this easier for (Wep)App developers we created a JavaScript library that handles this; ConnectAPI.js.
#Future & Alternatives
* [Network Service Discovery API - doodle3d-client/issues/248](https://github.com/Doodle3D/doodle3d-client/issues/248)
* [Scanning local network - doodle3d-client/issues/250](https://github.com/Doodle3D/doodle3d-client/issues/250)

View File

@ -13,7 +13,9 @@
var _intro; var _intro;
var _drawItem; var _drawItem;
var _updateItem; var _updateItem;
var _settingsItem;
var _joinNetworkItem; var _joinNetworkItem;
var _printItem;
var _defaultItems; var _defaultItems;
var _networkStatus; var _networkStatus;
@ -36,12 +38,15 @@
_defaultItems = _list.children(); _defaultItems = _list.children();
_drawItem = _list.find("#drawItem"); _drawItem = _list.find("#drawItem");
_updateItem = _list.find("#updateItem"); _updateItem = _list.find("#updateItem");
_settingsItem = _list.find("#settingsItem");
_joinNetworkItem = _list.find("#joinNetworkItem"); _joinNetworkItem = _list.find("#joinNetworkItem");
_printItem = _list.find("#printItem");
// make sure draw link is opened in same WebApp (added to homescreen) // make sure draw link is opened in same WebApp (added to homescreen)
// and it doesn't start a browser // and it doesn't start a browser
$.stayInWebApp("#box #drawItem a",true); $.stayInWebApp("#box #drawItem a",true);
}); });
$.mobile.document.on( "pagebeforeshow", PAGE_ID, function( event, data ) { $.mobile.document.on( "pagebeforeshow", PAGE_ID, function( event, data ) {
console.log("Box page pagebeforeshow"); console.log("Box page pagebeforeshow");
_boxData = d3d.util.getPageParams(PAGE_ID); _boxData = d3d.util.getPageParams(PAGE_ID);
@ -52,6 +57,8 @@
var boxURL = "http://"+_boxData.localip; var boxURL = "http://"+_boxData.localip;
//console.log(" _boxData: ",_boxData); //console.log(" _boxData: ",_boxData);
_printItem.hide();
_title.text(_boxData.wifiboxid); _title.text(_boxData.wifiboxid);
var drawLink = (_boxData.link)? _boxData.link : boxURL; var drawLink = (_boxData.link)? _boxData.link : boxURL;
@ -80,14 +87,16 @@
function setNetworkStatus(status) { function setNetworkStatus(status) {
console.log(PAGE_ID+":setNetworkStatus: ",status); console.log(PAGE_ID+":setNetworkStatus: ",status);
var introText = ""; var introText = "";
if(status === NetworkAPI.STATUS.CONNECTED) { // online if(status === NetworkAPI.STATUS.CONNECTED) { // online
//console.log("online"); //console.log("online");
_drawItem.find("a").text("Draw"); _drawItem.find("a").text("Draw / Sketch");
// display the right buttons // display the right buttons
_defaultItems.toggleClass("ui-screen-hidden",false); _defaultItems.toggleClass("ui-screen-hidden",false);
_joinNetworkItem.toggleClass("ui-screen-hidden",true); _joinNetworkItem.toggleClass("ui-screen-hidden",true);
//update link
var updateLink = _updateItem.find("a").attr("href"); var updateLink = _updateItem.find("a").attr("href");
updateLink = d3d.util.replaceURLParameters(updateLink,_boxData); updateLink = d3d.util.replaceURLParameters(updateLink,_boxData);
_updateItem.find("a").attr("href",updateLink); _updateItem.find("a").attr("href",updateLink);
@ -98,13 +107,14 @@
//console.log("offline"); //console.log("offline");
introText = "Please connect your WiFi-Box to the internet. You can also use it offline, but then you won't be able to update."; introText = "Please connect your WiFi-Box to the internet. You can also use it offline, but then you won't be able to update.";
_drawItem.find("a").text("Draw (offline)"); _drawItem.find("a").text("Draw / Sketch (local)");
// display the right buttons // display the right buttons
_defaultItems.toggleClass("ui-screen-hidden",true); _defaultItems.toggleClass("ui-screen-hidden",true);
_drawItem.toggleClass("ui-screen-hidden",false); _drawItem.toggleClass("ui-screen-hidden",false);
_joinNetworkItem.toggleClass("ui-screen-hidden",false); _joinNetworkItem.toggleClass("ui-screen-hidden",false);
//joinLink
var joinLink = _joinNetworkItem.find("a").attr("href"); var joinLink = _joinNetworkItem.find("a").attr("href");
joinLink = d3d.util.replaceURLParameters(joinLink,_boxData); joinLink = d3d.util.replaceURLParameters(joinLink,_boxData);
_joinNetworkItem.find("a").attr("href",joinLink); _joinNetworkItem.find("a").attr("href",joinLink);
@ -113,6 +123,25 @@
_intro.text(introText); _intro.text(introText);
_intro.toggleClass("ui-screen-hidden",(introText === "")); _intro.toggleClass("ui-screen-hidden",(introText === ""));
//printLink
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);
// ToDo: update footer with network info // ToDo: update footer with network info
_list.listview('refresh'); // jQuery mobile enhance content _list.listview('refresh'); // jQuery mobile enhance content

View File

@ -103,7 +103,7 @@
var actionText = ""; var actionText = "";
switch(data.status) { switch(data.status) {
case NetworkAPI.STATUS.CONNECTING: case NetworkAPI.STATUS.CONNECTING:
statusText = "Connecting to "+_pageData.ssid+"..."; statusText = "WiFi-Box is now trying to connect to "+_pageData.ssid+"...";
//actionText = "Please reconnect yourself to <b>"+_pageData.ssid+"</b>. Once you are connected return to this page."; //actionText = "Please reconnect yourself to <b>"+_pageData.ssid+"</b>. Once you are connected return to this page.";
actionText = "Please reconnect yourself to <b>"+_pageData.ssid+"</b>. Once you are connected return to this page."; actionText = "Please reconnect yourself to <b>"+_pageData.ssid+"</b>. Once you are connected return to this page.";
_actionField.attr("class","notice"); _actionField.attr("class","notice");

296
js/ControlPage.js Normal file
View File

@ -0,0 +1,296 @@
/*
* 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 _page;
var _form;
var _statusField;
var _infoField;
var _noRetainCheckbox;
var _includeBetasCheckbox;
var _submitButton;
var _settings;
var _updateAPI = new UpdateAPI();
var _configAPI = new ConfigAPI();
var _printerAPI = new PrinterAPI();
var _serverAPI = new ServerAPI();
var _infoAPI = new InfoAPI();
var _pageData = {};
var _updateStatus = {};
var _title;
var endCode;
var PAGE_ID = "#control";
var timerObject = {
interval_id : null
};
var _self = this;
$.mobile.document.on( "pageinit", PAGE_ID, function( event, data ) {
console.log(PAGE_ID+":pageinit");
_page = $(this);
_title = _page.find(".ui-title");
d3d.util.showLoader();
$("#grpStatusAndControl").hide();
$("#btnStop").hide();
$("#btnNewPrint").hide();
$("#infoDisconnected").hide();
$("#infoConnecting").hide();
//$("#btnSend").on("click", function(data) {
// // console.log("test",$("#gcode").val());
// _configAPI.loadAll(function(successData) {
// _settings = successData;
// var gcode = _configAPI.subsituteVariables($("#gcode").val(),_settings);
// console.log("btnPrint subsituteVariables: ",gcode);
// $(this).hide();
// _printerAPI.print({
// gcode: gcode,
// start: true,
// first: true
// },function(successData) {
// console.log("btnSend success");
// },function(failData) {
// console.log("btnSend fail");
// });
// });
//});
_pageData = d3d.util.getPageParams(PAGE_ID);
// console.log(_pageData);
if(_pageData === undefined) {
console.log("ERROR",PAGE_ID,"_pageData undefined");
$.mobile.changePage("#boxes");
return;
}
var backUrl = d3d.util.replaceURLParameters("#print",_pageData);
$("#btnControlBack").attr("href",backUrl);
/*
$("#btnCooldown").button().on("click", function(data) {
_printerAPI.print({
gcode: "M104 S20",
start: true,
first: true
});
});
$("#btnHeatup").button().on("click", function(data) {
_printerAPI.print({
gcode: "M104 S180",
start: true,
first: true
});
});
$("#btnHome").button().on("click", function(data) {
_printerAPI.print({
gcode: "G28",
start: true,
first: true
});
});
*/
$("#btnStop").on("click", function(data) {
if (!window.confirm("Are you sure you want to stop the current print?")) {
return;
}
$(this).hide();
if (!_settings) {
console.log("Error: _settings undefined");
return;
}
var endcode = _configAPI.subsituteVariables(_settings["printer.endcode"],_settings);
_printerAPI.stop({gcode:endcode}, function(successData) {
console.log("btnStop success",successData);
refreshStatus();
},function(failData) {
console.log("btnStop fail",failData);
window.alert("Problem: " + failData.msg);
});
});
});
function refreshStatus() {
d3d.util.showLoader();
_infoAPI.getStatus(function(successData) {
$("#grpStatusAndControl").show();
var state = successData.state;
if (state==="idle") {
state="ready";
}
if (state==="disconnected" || state==="connecting") {
$("#infoState").show();
$("#infoState").text("Printer " + state + "...");
$("#grpStatusAndControl").hide();
if (state==="connecting") {
$("#infoConnecting").show();
$("#infoDisconnected").hide();
//update firmware link
var url = d3d.util.replaceURLParameters("#update",_pageData);
$("#linkConnectingFirmware").attr("href",url);
} else if (state==="disconnected") {
$("#infoConnecting").hide();
$("#infoDisconnected").show();
}
} else {
$("#infoDisconnected").hide();
$("#infoConnecting").hide();
$("#infoState").hide();
$("#grpStatusAndControl").show();
$("#infoNozzleTemperature").html(successData.hotend + " / " + successData.hotend_target + " &deg;C");
$("#infoPrinterStatus").text(state);
if (_settings && _settings["printer.heatedbed"]) {
$("#liBedTemperature").show();
$("#infoBedTemperature").html(successData.bed + " / " + successData.bed_target + " &deg;C");
} else {
$("#liBedTemperature").hide();
}
}
if (successData.state==="printing") {
$("#liPrintingProgress").show();
// console.log('printing',d3d.util.formatPercentage(successData.current_line,successData.total_lines));
$("#infoPrintingProgress").text(d3d.util.formatPercentage(successData.current_line,successData.total_lines));
var uuid = successData.current_print;
//request filename only once
if ($("#infoPrintingFile").text()==="") {
_serverAPI.fetchHeader(uuid,function(successData) {
console.log("infoPrintingFile fetchHeader",successData);
$("#liPrintingFile").show();
$("#liPrinterType").show();
$("#infoPrintingFile").text(successData.name);
$("#infoPrinterType").text(successData.printer.title);
},function(failData) {
$("#liPrintingFile").hide();
});
}
$("#btnStop").show();
// console.log('printing');
} else {
// console.log('not printing');
$("#btnStop").hide();
$("#liPrintingProgress").hide();
$("#liPrintingFile").hide();
}
if (state==="ready") {
//if (d3d && d3d.pageParams && d3d.pageParams.uuid) {
//console.log("show button btnNewPrint");
//var url = d3d.util.replaceURLParameters("#print",_pageData);
//$("#btnNewPrint").attr("href",url);
//$("#btnNewPrint").show();
//}
} else {
// $("#grpCustomGCODE").hide();
}
// console.log("getStatus success",successData);
d3d.util.hideLoader();
},function(failData) {
console.log("getStatus fail",failData);
$("#grpStatusAndControl").hide();
d3d.util.hideLoader();
});
}
$.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;
// _title.text("Control 3D-printer on " + _pageData.wifiboxid);
_configAPI.init(boxURL);
_printerAPI.init(boxURL);
_infoAPI.init(boxURL);
_serverAPI.init("https://gcodeserver.doodle3d.com");
_configAPI.loadAll(function(successData) {
_settings = successData;
console.log("_configAPI.loadAll success",_settings);
$("span#infoPrinterType").text(successData["printer.type"]);
// $("#infoWiFiBox").text(_settings.)
},function(failData) {
console.log("_configAPI.loadAll failed");
});
_infoAPI.getInfo(function(successData) {
$("span#infoWiFiBox").text(successData.wifiboxid);
},function(failData) {
});
// refreshSettings();
refreshStatus();
timerObject.interval_id = setInterval(function() {refreshStatus(); }, 3000);
});
$.mobile.document.on('pagehide', PAGE_ID, function(){
clearInterval(timerObject.interval_id);
});
$.mobile.document.on( "pagebeforehide", PAGE_ID, function( event, data ) {
console.log("pagebeforehide");
});
})(window);

279
js/PrintPage.js Normal file
View File

@ -0,0 +1,279 @@
/*
* 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;
}
if (!d3d || !d3d.pageParams || !d3d.pageParams.uuid) {
console.log("ERROR",PAGE_ID,"d3d.pageParams no uuid");
$.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($("<option></option>"));
var selectedItem;
for (var i in successData) {
var box = successData[i];
var selected = (box.localip===_pageData.localip) ? "selected " : "";
if (selected) {
selectedItem = _pageData.localip;
}
$("#lstBoxes").append($("<option "+selected+" value="+box.localip+">"+box.wifiboxid+"</option>"));
}
$("#lstBoxes").append($("<option value='other'>Other...</option>"));
$("#lstBoxes").selectmenu("refresh", true);
if (selectedItem) {
onSelectWiFiBox(selectedItem);
}
}, function(failData) {
console.log("_connectAPI.list failData",failData);
$("#infoWiFiBox").html("<span class='error'>failed to retrieve list with local WiFi-Box'es</span>");
});
$("#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);
var localip = localStorage.setItem("localip",ip);
_networkAPI.status(function(successData) {
console.log("network status",successData);
// $("#lstPrint li.boxItem p").text(
var netInfo = successData.statusMessage + " (" + successData.ssid + " @ <a href='http://" + successData.localip + "'>"+successData.localip+"</a>)";
_infoAPI.getStatus(function(successData) {
console.log(successData);
var state = successData.state;
if (state==="idle") {
state="ready";
$("#btnPrint").button('enable');
}
_pageData.localip = ip; //update pageData to reflect the selected WiFi-Box without reloading the page
var url = d3d.util.replaceURLParameters("#control",_pageData);
var info = netInfo + " - Printer status: ";
info += "<a href='"+url+"'><span class='"+state+"'>"+state+"</span></a>";
$("#infoWiFiBox").html(info);
}, function(failData) {
console.log(failData);
$("#infoWiFiBox").html("<span class='error'>failed to retrieve <em>printer status</em> from WiFi-Box</span>");
});
}, function(failData) {
console.log("_networkAPI status failed",failData);
$("#infoWiFiBox").html("<span class='error'>failed to retrieve <em>network status</em> from WiFi-Box</span>");
});
}
}
function checkPrinterTypeMatch(completeHandler, failedHandler) {
_configAPI.loadAll(function(successData) {
_wifiboxSettings = successData;
var data = {
slicerPrinterType: _slicerSettings.printer.type,
wifiboxPrinterType: _wifiboxSettings["printer.type"]
};
if (data.slicerPrinterType === data.wifiboxPrinterType) {
if (completeHandler) {
completeHandler(data);
}
} else {
if (failedHandler) {
failedHandler(data);
}
}
});
}
function forcePrinterTypeMatch(completeHandler, failedHandler) {
checkPrinterTypeMatch(function(successData) {
completeHandler({msg:"slicerPrinterType matches wifiboxPrinterType"});
}, function(failData) {
var override = window.confirm("The GCODE file was sliced for '"+failData.slicerPrinterType+"'.\n"+
"Your WiFi-Box is currently configured for '"+failData.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(failData.slicerPrinterType, function(successData) {
//reload settings from WiFi-Box with new printerType to get the right start & end gcode
_configAPI.loadAll(function(successData) {
_wifiboxSettings = successData;
completeHandler({msg:"printer.type successfully updated and _wifiboxSettings successfully reloaded"});
}, function(failData) {
failedHandler({msg:"reload config failed"});
});
}, function(failData) {
failedHandler({msg:"saving failed printer.type failed",details:failData});
});
} else {
failedHandler({msg:""});
}
});
}
function print() {
console.log("print");
forcePrinterTypeMatch(function(successData) {
console.log("successfully made sure printerType and config is up to date",successData);
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
};
$("#btnPrint").button('disable');
d3d.util.showLoader();
//console.log("fetchPrint",d3d.pageParams.uuid,data);
_printerAPI.fetch(data,function(successData) {
console.log("fetchPrint success",successData);
setTimeout(function() {
var url = d3d.util.replaceURLParameters("#control",_pageData);
$.mobile.changePage(url);
},3000);
},function(failData) {
console.log("fetchPrint fail",failData);
window.alert("Problem: " + failData.msg);
});
},function(failData) {
window.alert("Sorry, the print can not be started because the settings don't match between the Slicer and the WiFi-Box.\n\nDetails: " + 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.printer.type;
var printerTitle = header.printer.title;
$("#infoFile").text(header.name + " (" + filesize + ")");
$("#infoPrinter").text(printerTitle);
$("#infoMaterial").html(header.filamentThickness + "mm @ " + header.temperature + "&deg;C");
$("#iconPrinter").attr('src','img/icons/printers/'+printerId+'.png');
}, function(failData) {
console.log("_serverAPI.fetchHeader fail",failData);
clearInfo();
});
},function(failData) {
clearInfo();
console.log("_serverAPI.getInfo fail",failData);
setTimeout(function() {
console.log("_serverAPI.getInfo: now try again",uuid);
loadGCodeInfoFromServer(uuid);
},3000);
});
}
})(window);

182
js/SettingsPage.js Normal file
View File

@ -0,0 +1,182 @@
/*
* 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 _page;
var _form;
var _statusField;
var _infoField;
var _noRetainCheckbox;
var _includeBetasCheckbox;
var _submitButton;
var _updateAPI = new UpdateAPI();
var _configAPI = new ConfigAPI();
var _printerAPI = new PrinterAPI();
var _pageData = {};
var _updateStatus = {};
var _title;
var PAGE_ID = "#settings";
var _self = this;
function showOrHideFields() {
if ($("#chkBed").prop("checked")) {
$("#grpBedTemp").show();
} else {
$("#grpBedTemp").hide();
}
}
$.mobile.document.on( "pageinit", PAGE_ID, function( event, data ) {
console.log(PAGE_ID+":pageinit");
_page = $(this);
_title = _page.find(".ui-title");
$("#divSettings").hide();
d3d.util.showLoader();
$("#lstPrinters").on("change", function(data) {
var printerType = $(this).val();
d3d.util.showLoader();
_configAPI.savePrinterType(printerType,function(successData) {
refreshSettings();
},function(failData) {
console.log("savePrinterType fail",failData);
});
});
$("#nozzleTemperature").on('slidestop', function( event ) {
_configAPI.save({"printer.temperature":$(this).val()});
});
$("#nozzleTemperature").on('focusout', function( event ) {
_configAPI.save({"printer.temperature":$(this).val()});
});
$("#bedTemperature").on('slidestop', function( event ) {
_configAPI.save({"printer.bed.temperature":$(this).val()});
});
$("#bedTemperature").on('focusout', function( event ) {
_configAPI.save({"printer.bed.temperature":$(this).val()});
});
$("#filamentThickness").on("change", function(data) {
_configAPI.save({"printer.filamentThickness":$(this).val()});
});
$("#dimensionsX").on("change", function(data) {
_configAPI.save({"printer.dimensions.x":$(this).val()});
});
$("#dimensionsY").on("change", function(data) {
_configAPI.save({"printer.dimensions.y":$(this).val()});
});
$("#dimensionsZ").on("change", function(data) {
_configAPI.save({"printer.dimensions.z":$(this).val()});
});
$('#startgcode').on("change", function(data) {
_configAPI.save({"printer.startcode":$(this).val()});
});
$('#endgcode').on("change", function(data) {
_configAPI.save({"printer.end":$(this).val()});
});
$("#chkBed").on("change", function(data) {
showOrHideFields();
});
});
$.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;
_title.text("Settings for " + _pageData.wifiboxid);
_configAPI.init(boxURL);
_printerAPI.init(boxURL);
refreshSettings();
});
$.mobile.document.on( "pagebeforehide", PAGE_ID, function( event, data ) {
});
function refreshSettings() {
_configAPI.loadAll(function(successData) {
var printerType = successData["printer.type"];
var printerStartGCode = successData["printer.startcode"];
var printerEndGCode = successData["printer.endcode"];
var heatedBedEnabled = successData["printer.heatedbed"];
var bedTemperature = successData["printer.bed.temperature"];
var dimensionsX = successData["printer.dimensions.x"];
var dimensionsY = successData["printer.dimensions.y"];
var dimensionsZ = successData["printer.dimensions.z"];
var filamentThickness = successData["printer.filamentThickness"];
var nozzleTemperature = successData["printer.temperature"];
$('#chkBed').prop('checked', heatedBedEnabled);
$('#chkBed').val('on').flipswitch('refresh');
$('#bedTemperature').val(bedTemperature);
$('#dimensionsX').val(dimensionsX);
$('#dimensionsY').val(dimensionsY);
$('#dimensionsZ').val(dimensionsZ);
$('#filamentThickness').val(filamentThickness);
$('#startgcode').val(printerStartGCode);
$('#endgcode').val(printerEndGCode);
$('#nozzleTemperature').val(nozzleTemperature);
_printerAPI.listAll(function(printers) {
$("#lstPrinters").empty();
for (var id in printers) {
var selected = (id===printerType) ? "selected " : "";
$("#lstPrinters").append("<option "+selected+" value='"+id+"'>"+printers[id]+"</option>");
}
$("#lstPrinters").selectmenu("refresh", true);
$("#divSettings").show();
d3d.util.hideLoader();
showOrHideFields();
$("#bedTemperature").slider("refresh");
$("#nozzleTemperature").slider("refresh");
},function(failData) {
console.log(PAGE_ID,'FAIL _printerAPI.listAll');
$.mobile.changePage("#boxes");
return;
});
},function(failData) {
console.log("FAIL loadPrinterType",failData);
$.mobile.changePage("#boxes");
return;
});
}
})(window);

View File

@ -61,6 +61,17 @@ function ConfigAPI() {
if(failedHandler) failedHandler(); if(failedHandler) failedHandler();
}); });
}; };
this.loadSetting = function(settingName,completeHandler,failedHandler) {
this.load(settingName+"=",function(successData) {
completeHandler(successData[settingName]);
},failedHandler);
}
this.loadPrinterType = function(completeHandler,failedHandler) {
this.loadSetting("printer.type",completeHandler,failedHandler);
}
this.save = function(newSettings,completeHandler,failedHandler) { this.save = function(newSettings,completeHandler,failedHandler) {
//console.log("ConfigAPI:save"); //console.log("ConfigAPI:save");
$.ajax({ $.ajax({
@ -74,13 +85,28 @@ function ConfigAPI() {
if(response.status == "error" || response.status == "fail") { if(response.status == "error" || response.status == "fail") {
if (failedHandler) failedHandler(response); if (failedHandler) failedHandler(response);
} else { } else {
completeHandler(response.data); console.log("ConfigAPI.save",newSettings,response.data);
if (completeHandler) completeHandler(response.data);
} }
} }
}).fail(function() { }).fail(function() {
if(failedHandler) failedHandler(); if(failedHandler) failedHandler();
}); });
}; };
this.savePrinterType = function(printerType,completeHandler,failedHandler) {
var settings = {"printer.type": printerType};
this.save(settings,function(successData) {
if (successData.validation["printer.type"]==="ok") {
if (completeHandler) completeHandler(successData);
} else {
if (failedHandler) failedHandler(successData); //passing successData because it contains valiation error
}
},function(failData) {
if (failedHandler) failedHandler(failData);
});
};
this.resetAll = function(completeHandler,failedHandler) { this.resetAll = function(completeHandler,failedHandler) {
//console.log("ConfigAPI:resetAll"); //console.log("ConfigAPI:resetAll");
$.ajax({ $.ajax({
@ -99,4 +125,33 @@ function ConfigAPI() {
if(failedHandler) failedHandler(); if(failedHandler) failedHandler();
}); });
}; };
this.subsituteVariables = function(gcode,settings) {
//,temperature,bedTemperature,preheatTemperature,preheatBedTemperature
var temperature = settings["printer.temperature"];
var bedTemperature = settings["printer.bed.temperature"];
var preheatTemperature = settings["printer.heatup.temperature"];
var preheatBedTemperature = settings["printer.heatup.bed.temperature"];
var printerType = settings["printer.type"];
var heatedbed = settings["printer.heatedbed"];
switch (printerType) {
case "makerbot_replicator2": printerType = "r2"; break;
case "makerbot_replicator2x": printerType = "r2x"; break;
case "makerbot_thingomatic": printerType = "t6"; break;
case "makerbot_generic": printerType = "r2"; break;
case "wanhao_duplicator4": printerType = "r2x"; break;
case "_3Dison_plus": printerType = "r2"; break;
}
var heatedBedReplacement = (heatedbed)? "" : ";";
gcode = gcode.replace(/{printingTemp}/gi ,temperature);
gcode = gcode.replace(/{printingBedTemp}/gi ,bedTemperature);
gcode = gcode.replace(/{preheatTemp}/gi ,preheatTemperature);
gcode = gcode.replace(/{preheatBedTemp}/gi ,preheatBedTemperature);
gcode = gcode.replace(/{printerType}/gi ,printerType);
gcode = gcode.replace(/{if heatedBed}/gi ,heatedBedReplacement);
return gcode;
}
} }

View File

@ -56,9 +56,9 @@ function ConnectAPI() {
completeHandler(response.data); completeHandler(response.data);
} }
} }
}).fail(function() { }).fail(function(failData) {
//console.log("ConnectAPI:list failed"); //console.log("ConnectAPI:list failed");
if(failedHandler) failedHandler(); if(failedHandler) failedHandler(failData);
if(_self.listFailed) {_self.listFailed(); } if(_self.listFailed) {_self.listFailed(); }
}); });
}; };

View File

@ -58,4 +58,22 @@ function InfoAPI() {
if(failedHandler) failedHandler(); 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();
});
};
} }

116
js/api/PrinterAPI.js Normal file
View File

@ -0,0 +1,116 @@
/*
* 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 PrinterAPI() {
var _apiPath = "/d3dapi";
var _apiCGIPath = "/cgi-bin"+_apiPath;
var _wifiboxURL;
var _wifiboxCGIBinURL;
var _timeoutTime = 3000;
var _configAPI = new ConfigAPI(); // needed for wifiboxid workaround
var _self = this;
this.init = function(wifiboxURL) {
console.log("InfoAPI:init");
_wifiboxURL = wifiboxURL+_apiPath;
_wifiboxCGIBinURL = wifiboxURL+_apiCGIPath;
_configAPI.init(wifiboxURL);
}
this.listAll = function(completeHandler,failedHandler) {
console.log("listAll",_wifiboxURL);
$.ajax({
url: _wifiboxURL + "/printer/listall",
type: "GET",
dataType: 'json',
timeout: _timeoutTime,
success: function(response){
if(response.status == "error" || response.status == "fail") {
if(failedHandler) failedHandler(response);
} else {
completeHandler(response.data.printers);
}
}
}).fail(function() {
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();
});
};
}

82
js/api/ServerAPI.js Normal file
View File

@ -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);
});
};
}

View File

@ -98,7 +98,28 @@ d3d.util = {
var target = form.find("input[autofocus]:visible"); var target = form.find("input[autofocus]:visible");
target.focus(); 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) { (function (w) {
@ -106,6 +127,9 @@ d3d.util = {
// only pagecontainer events contain url's // only pagecontainer events contain url's
// we parse the parameters and store them in a global object // we parse the parameters and store them in a global object
d3d.pageParams = {}; d3d.pageParams = {};
d3d.pageParams.uuid = d3d.util.getQueryParam("uuid");
console.log(d3d.pageParams.uuid);
$.mobile.document.on( "pagebeforechange", function( event, data ) { $.mobile.document.on( "pagebeforechange", function( event, data ) {
if (typeof data.toPage !== "string") { return; } if (typeof data.toPage !== "string") { return; }
var url = d3d.util.parseURL(data.toPage); 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 // make sure that the parameters are not removed from the visible url
event.preventDefault(); 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); })(window);

View File

@ -1,6 +1,7 @@
body.ui-mobile-viewport { body.ui-mobile-viewport {
margin: 0 auto; margin: 0 auto;
max-width: 1024px; max-width: 1024px;
/*font-family: 'Abel', sans-serif;*/
} }
#logo { #logo {
@ -210,3 +211,19 @@ html head + body .ui-body-a.ui-focus {
color: #F18DB1; color: #F18DB1;
} }
} }
#infoWiFiBox a {
font-weight: normal;
}
#infoWiFiBox .idle, #infoWiFiBox .ready {
color: #5fba7d;
}
#infoWiFiBox .disconnected, #infoWiFiBox .connecting, #infoWiFiBox .stopping, #infoWiFiBox .error {
color: red;
}
#infoWiFiBox .printing {
/*color: #93CAF4;*/
}

2
upload.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
rsync -av www/ doodle3d.com:/domains/doodle3d.com/connect

BIN
www/img/icons/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
www/img/icons/gcode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,52 @@
_3Dison_plus
bigbuilder3d
builder3d
bukobot
cartesio
colido_2_0_plus
colido_compact
colido_diy
colido_m2020
colido_x3045
craftbot_plus
cyrus
delta_rostockmax
deltamaker
doodle_dream
eventorbot
felix
gigabot
kossel
leapfrog_creatr
lulzbot_aO_101
lulzbot_taz_4
makerbot_generic
makerbot_replicator2
makerbot_replicator2x
makerbot_thingomatic
makergear_m2
makergear_prusa
makibox
mamba3d
marlin_generic
minifactory
orca_0_3
ord_bot_hadron
printrbot
printxel_3d
prusa_i3
prusa_iteration_2
rapman
renkforce_rf100
reprappro_huxley
reprappro_mendel
rigidbot
robo_3d_printer
shapercube
tantillus
ultimaker
ultimaker2
ultimaker2go
ultimaker_original_plus
vision_3d_printer
wanhao_duplicator4

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
www/img/icons/white.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
www/img/icons/wifibox.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -3,6 +3,7 @@
<head> <head>
<title>Doodle3D Connect</title> <title>Doodle3D Connect</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
@ -13,15 +14,21 @@
<link rel="shortcut" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png"> <link rel="shortcut" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png">
<link rel="icon" type="image/ico" href="./img/favicon.ico"> <link rel="icon" type="image/ico" href="./img/favicon.ico">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" /> <!-- scripts -->
<!-- <link rel="stylesheet" href="js/libs/jquery.mobile/jquery.mobile-1.4.2.min.css" /> --> <!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
<link rel="stylesheet" href="css/doodle3d-server.min.css"/> <!-- <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> -->
<!-- <script src="http://code.jquery.com/mobile/1.1.2/jquery.mobile-1.1.2.min.js"></script> -->
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script> <script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
<!-- <script src="jquery/jquery-1.11.0.min.js"></script>-->
<!-- <script src="jquery.mobile/jquery.mobile-1.4.2.min.js"></script>-->
<script src="js/doodle3d-server.min.js" type="text/javascript"></script> <script src="js/doodle3d-server.min.js" type="text/javascript"></script>
<!-- <script src="js/doodle3d-server.js" type="text/javascript"></script> -->
<!-- stylesheets -->
<!-- <link href="https://fonts.googleapis.com/css?family=Abel" rel="stylesheet"> -->
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<!-- <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.2/jquery.mobile-1.1.2.min.css" /> -->
<link rel="stylesheet" href="css/doodle3d-server.min.css"/>
</head> </head>
@ -29,16 +36,24 @@
<div data-role="page" id="boxes" data-title="Doodle3D Connect"> <div data-role="page" id="boxes" data-title="Doodle3D Connect">
<a href="#boxes" id="logo"><img src="img/logo_full.png"></a> <a href="#boxes" id="logo"><img src="img/logo_full.png"></a>
<p id="slogan">makes 3D printing very easy</p>
<div role="main" class="ui-content">
<h3>Let's connect to your Doodle3D WiFi-Box</h3>
<p>This webpage helps you to find your Doodle3D WiFi-Box on your local network.</p>
<p>1) If your WiFi-Box is already connected to your home network it should be listed below.</p>
<p>2) If not it might be running its own WiFi network (for example Doodle3D-123456). You can connect to it by changing your WiFi-settings.</p>
</div>
<div data-role="header"> <div data-role="header">
<h1>WiFi-Boxes</h1> <h1>WiFi-Boxes</h1>
</div><!-- /header --> </div>
<!-- <p>Please select your Doodle3D WiFi-Box to connect or press search to add your box to this list.</p> -->
<div role="main" class="ui-content"> <div role="main" class="ui-content">
<ul data-role="listview" id="boxeslist"> <ul data-role="listview" id="boxeslist">
<li id="findItem"><a href="#find">Find...</a></li> <li id="findItem"><a href="#find">Help me find my WiFi-Box...</a></li>
</ul> </ul>
</div><!-- /content --> </div>
</div><!-- /page --> </div><!-- /page -->
@ -52,13 +67,123 @@
<p class="intro"></p> <p class="intro"></p>
<ul data-role="listview"> <ul data-role="listview">
<li id="drawItem"><a href="#draw">Draw</a></li> <li id="drawItem"><a href="#draw">Draw</a></li>
<li id="updateItem"><a href="#update">Update<span class="ui-li-count"></span></a></li> <li id="printItem"><a href="#print">Print</a></li>
<!-- <li id="transformItem"><a href="http://transform.doodle3d.com">Doodle3D Transform</a></li> -->
<!-- <li id="settingsItem" data-icon="gear"><a href="#settings">Settings</a></li> -->
<li id="updateItem"><a href="#update">Firmware Update<span class="ui-li-count"></span></a></li>
<li id="joinNetworkItem"><a href="#join_network">Join network </a></li> <li id="joinNetworkItem"><a href="#join_network">Join network </a></li>
<li><a href="#yourapp">Your app here?</a></li> <!-- <li><a href="#yourapp">Your app here?</a></li> -->
</ul> </ul>
</div><!-- /content --> </div><!-- /content -->
</div><!-- /page --> </div><!-- /page -->
<div data-role="page" id="print">
<a href="#boxes" id="logo"><img src="img/logo_full.png"></a>
<div data-role="header">
<a href="#boxes" data-rel="back"
class="ui-btn ui-btn-left ui-nodisc-icon ui-corner-all ui-btn-icon-notext ui-icon-carat-l">Back</a>
<h1>Print</h1>
</div><!-- /header -->
<div id="divPrint" role="main" class="ui-content">
<p class="intro">Let's 3D-print your model by sending it to your printer over WiFi. Please check the settings below and press Print.</p>
<label for="name">The following GCODE file is ready for printing:</label>
<ul id="lstPrint" data-role="listview" data-inset="true">
<li>
<img src="img/icons/gcode.png" width="80" height="80">
<h2>File to print</h2>
<p id="infoFile">...</p>
</li>
<li>
<img id="iconPrinter" src="img/icons/blank.png" width="80" height="80">
<h2>3D-Printer</h2>
<p id="infoPrinter">...</p>
</li>
<li>
<img src="img/icons/white.jpg" width="80" height="80">
<h2>Material</h2>
<p id="infoMaterial">...</p>
</li>
</ul>
Please select your Doodle3D WiFi-Box:
<ul data-role="listview" data-inset="true">
<li>
<img src="img/icons/wifibox.jpg" width="80" height="80">
<select id="lstBoxes"></select>
<p style="white-space: normal;" id="infoWiFiBox"></p>
</li>
</ul>
<input type="button" id="btnPrint" class="ui-shadow ui-btn ui-corner-all" value="Print">
</div>
</div>
<div data-role="page" id="control">
<a href="#boxes" id="logo"><img src="img/logo_full.png"></a>
<div data-role="header">
<a id="btnControlBack" href="#boxes"
class="ui-btn ui-btn-left ui-nodisc-icon ui-corner-all ui-btn-icon-notext ui-icon-carat-l">Back</a>
<h1>Status</h1>
</div><!-- /header -->
<div id="divControl" role="main" class="ui-content">
<!-- <p class="intro">...</p> -->
<div id="infoState">loading...</div>
<div id="infoDisconnected">
<p>Please make sure the WiFi-Box is connected to your 3D-printer using a USB cable.</p>
</div>
<div id="infoConnecting">
<p>This can take a while, 20 seconds or so...</p>
<!-- <p>Hmm... this takes longer than usual...</p> -->
<p>If it takes too long please try to restart your WiFi-Box. Also make sure the WiFi-Box is running the latest <a id="linkConnectingFirmware" href="#update">firmware</a>.</p>
<p>If you think you're really stuck, please <a href="javascript:talkus('open')">chat</a> with us to see if we can help.</p>
</div>
<div id="grpStatusAndControl">
<ul data-role="listview" data-inset="true">
<li id="liPrinterId" data-icon="false">
WiFi-Box
<span id="infoWiFiBox" class="ui-li-count"></span>
</li>
<li id="liPrinterType" data-icon="false">
Printer
<span id="infoPrinterType" class="ui-li-count"></span>
</li>
<li id="liPrinterStatus" data-icon="false">
Status
<span id="infoPrinterStatus" class="ui-li-count"></span>
</li>
<li id="liPrintingFile" data-icon="false">
File
<span id="infoPrintingFile" class="ui-li-count"></span>
</li>
<li id="liPrintingProgress" data-icon="false">
Progress
<span id="infoPrintingProgress" class="ui-li-count">...</span>
</li>
<li data-icon="false">
Nozzle Temperature
<span id="infoNozzleTemperature" class="ui-li-count"></span>
</li>
<li id="liBedTemperature" data-icon="false">
Bed temperature
<span id="infoBedTemperature" class="ui-li-count"></span>
</li>
</ul>
</div>
<button id="btnStop" data-role="button">Stop print</button>
<button id="btnNewPrint" data-role="button">Start a new print</button>
</div>
</div>
<div data-role="page" id="find"> <div data-role="page" id="find">
<a href="#boxes" id="logo"><img src="img/logo_full.png"></a> <a href="#boxes" id="logo"><img src="img/logo_full.png"></a>
@ -67,18 +192,40 @@
<h1>Find WiFi-Box</h1> <h1>Find WiFi-Box</h1>
</div><!-- /header --> </div><!-- /header -->
<div role="main" class="ui-content"> <div role="main" class="ui-content">
<h3>Find your box's WiFi network</h3> <h3>Connect to your WiFi-Box for the first time...</h3>
<p>The Doodle3D WiFi-Box you're looking for is probably running it's own WiFi network. Please open your network settings and connect to a network like <strong>Doodle3D-...</strong> and return to the <a href="#boxes">WiFi-boxes</a> page (<a href="#help_connect_ap">More info</a>).</p> <p>This video shows you how to connect to your Doodle3D WiFi-Box step by step.</p>
<h3>Connect to the same WiFi network</h3> <iframe width="500" height="281" src="https://www.youtube.com/embed/8p2QGWlhR4E" frameborder="0" allowfullscreen></iframe>
<p>Please make sure that you're connected to the same WiFi network the WiFi-Box is connected to.</p>
<h3>Can't find your WiFi-Box?</h3> <h3>How does it work?</h3>
<p>Please make sure that:</p> <p>The WiFi-Box can run in two different modes:<br>
<ul> <ol><li> It can connect to an existing WiFi network, that's called <u>Client mode</u>.</li>
<li>The box gets power (the big green light should be on).</li> <li>It can also create it's own network which is called <u>AccessPoint mode</u>.</li>
<li>The box has fully started (the big green light stopped blinking)</li> </ol>
</ul> A new WiFi-Box always starts in AccessPoint mode because it doesn't know your network yet, right?<br>
<p>You can always connect to it using an ethernet cable (<a href="#help_connect_cable">more info</a>).</p> Also when the WiFi-Box can't find or can't connect to your home network it should fall back to AccessPoint mode.<br>
<p>If the problems remains, please E-mail us at <a href="mailto:help@doodle3d.com">help@doodle3d.com</a></p> If the WiFi-Box is in AccessPoint mode you should be able to see it's WiFi network in your computer/tablet's WiFi-settings.</p>
<h3>How to let the WiFi-Box join your local network?</h3>
Once you are connected to the WiFi-Box in AccessPoint mode you can help your WiFi-Box join your local network as a 'Client'. This has two advantages:
<ol>
<li>The WiFi-Box can download updates and security updates from doodle3d.com</li>
<li>You don't have to switch between your home network and the AccessPoint all the time.</li>
</ol>
<p>This movie shows how to have the WiFi-Box join your home network and download an update.</p>
<iframe width="500" height="281" src="https://www.youtube.com/embed/dT6PmWDnUxM" frameborder="0" allowfullscreen></iframe>
<h3>What's the network cable for?</h3>
<p>If you really can't or don't want to connect to the WiFi-Box using WiFi you can use the network cable. Connect the WiFi-Box directly to your computer (not to your router) and go back to the connect.doodle3d.com page.</p>
<h3>Need more help?</h3>
<p>Please read our <a href="http://faq.doodle3d.com/">FAQ</a> for more frequently asked questions. <br>If you're really stuck feel free to contact us at <a href="mailto:help@doodle3d.com">help@doodle3d.com</a>. <br>You can also live <a href="javascript:talkus('open')">chat</a> with us during European office hours.</p>
<p><a href="#boxes">Go back to connect.doodle3d.com</a></p>
<!-- <p><br></p> -->
</div>
</div><!-- /content --> </div><!-- /content -->
</div><!-- /page --> </div><!-- /page -->
@ -232,11 +379,117 @@
</div><!-- /content --> </div><!-- /content -->
</div><!-- /page --> </div><!-- /page -->
<div data-role="page" id="settings">
<a href="#boxes" id="logo"><img src="img/logo_full.png"></a>
<div data-role="header">
<a href="../toolbar/" data-rel="back"
class="ui-btn ui-btn-left ui-nodisc-icon ui-corner-all ui-btn-icon-notext ui-icon-carat-l">Back</a>
<h1>Settings</h1>
</div><!-- /header -->
<div id="divSettings" role="main" class="ui-content">
<p class="intro">Use this page to select which 3D-printer is connected to your Doodle3D WiFi-Box. You can change settings per printer. Your settings are saved automatically.</p>
<label for="name">3D-printer model:</label>
<select id="lstPrinters"></select>
<div data-role="collapsible">
<h3>Printer settings</h3>
<div data-role="fieldcontain">
<!-- <label for="name"></label>
<label>
<input type="checkbox" name="checkbox-0 ">Enable heated bed
</label> -->
<label for="chkBed">Heated bed:</label>
<input type="checkbox" data-role="flipswitch" name="chkBed" id="chkBed">
</div>
<div id="grpBedTemp" data-role="fieldcontain">
<label for="bedTemperature">Bed temperature (&deg;C):</label>
<input type="range" name="bedTemperature" id="bedTemperature" value="70" min="20" max="120" data-highlight="true" />
</div>
<div id="grpDimensions" data-role="fieldcontain">
<label for="name">Dimensions XYZ (mm):</label>
<div class="ui-grid-b">
<div class="ui-block-a"><input placeholder="x" name="dimensionsX" id="dimensionsX" type="number" data-mini="true"/></div>
<div class="ui-block-b"><input placeholder="y" name="dimensionsY" id="dimensionsY" type="number" data-mini="true"/></div>
<div class="ui-block-c"><input placeholder="z" name="dimensionsZ" id="dimensionsZ" type="number" data-mini="true"/></div>
</div>
</div>
<div data-role="collapsible">
<h3>GCODE settings</h3>
<div data-role="fieldcontain">
<label for="startgcode">Start gcode:</label>
<textarea name="startgcode" id="startgcode"></textarea>
</div>
<div data-role="fieldcontain">
<label for="endgcode">End gcode:</label>
<textarea name="endgcode" id="endgcode"></textarea>
</div>
<div data-role="collapsible" data-mini="true">
<h3>Help</h3>
<small>
The following texts are replaced:
<dl>
<dt>{printingTemp}</dt><dd>Printing temperature</dd>
<dt>{printingBedTemp}</dt><dd>Printing bed temperature</dd>
<dt>{preheatTemp}</dt><dd>Preheat temperature</dd>
<dt>{preheatBedTemp}</dt><dd>Preheat bed temperature</dd>
<dt>{printerType}</dt><dd>Printer type</dd>
<dt>{if heatedBed}</dt><dd>Enable line if printer has heated bed</dd>
</dl>
</small>
</div>
</div>
</div>
<div data-role="collapsible">
<h3>Material settings</h3>
<div data-role="fieldcontain">
<label for="name">Filament thickness (mm):</label>
<input type="number" id="filamentThickness" name="filamentThickness" data-mini="true" step=".01" min="1.75" max="3.3"/>
</div>
<div data-role="fieldcontain">
<label for="nozzleTemperature">Nozzle temperature (&deg;C):</label>
<input type="range" name="nozzleTemperature" id="nozzleTemperature" value="200" min="20" max="260" data-highlight="true" />
</div>
</div>
</div>
</div>
<script> <script>
$(function(){ $(function(){
$( "[data-role='header'], [data-role='footer']" ).toolbar(); $( "[data-role='header'], [data-role='footer']" ).toolbar();
}); });
</script> </script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-2176425-7', 'auto');
ga('send', 'pageview');
</script>
<script>
(function(t,a,l,k,u,s,e){if(!t[u]){t[u]=function(){(t[u].q=t[u].q||[]).push(arguments)},t[u].l=1*new Date();s=a.createElement(l),e=a.getElementsByTagName(l)[0];s.async=1;s.src=k;e.parentNode.insertBefore(s,e)}})(window,document,'script','//www.talkus.io/plugin.beta.js','talkus');
talkus('init', 'bCwR4NgCDFFcYtgg8');
</script>
</body> </body>
</html> </html>