diff --git a/src/interface/MalyanControl.js b/src/interface/MalyanControl.js
new file mode 100644
index 0000000..fd5f6e4
--- /dev/null
+++ b/src/interface/MalyanControl.js
@@ -0,0 +1,61 @@
+import React from 'react';
+import PropTypes from 'proptypes';
+import muiThemeable from 'material-ui/styles/muiThemeable';
+import injectSheet from 'react-jss';
+import FlatButton from 'material-ui/FlatButton';
+import { sleep, getMalyanStatus } from './utils.js';
+
+const styles = {
+
+};
+
+class MalyanControl extends React.Component {
+ static propTypes = {
+ ip: PropTypes.string.isRequired
+ };
+
+ state = {
+ status: null,
+ mounted: true
+ };
+
+ componentDidMount = async () => {
+ const { ip } = this.props;
+ while (this.state.mounted) {
+ const status = await getMalyanStatus(ip).catch(() => null);
+ this.setState({ status });
+ await sleep(1000);
+ }
+ };
+
+ home = () => {
+ const { ip } = this.props;
+ fetch(`http://${ip}/set?code=G28`, { method: 'GET' });
+ };
+
+ stop = () => {
+ const { ip } = this.props;
+ fetch(`http://${ip}/set?cmd={P:X}`, { method: 'GET' });
+ };
+
+ componentWillUnmount() {
+ this.setState({ mounted: false });
+ }
+
+ render() {
+ const { status } = this.state;
+ return (
+
+ {status &&
+ Nozzle temperature: {status.nozzleTemperature}/{status.nozzleTargetTemperature}
+ Bed temperature: {status.bedTemperature}/{status.bedTargetTemperature}
+ {status.state === 'printing' && Progress: {status.progress}%
}
+ }
+
+
+
+ );
+ }
+}
+
+export default muiThemeable()(injectSheet(styles)(MalyanControl));
diff --git a/src/interface/index.js b/src/interface/index.js
index 7f8f9b2..37e4d36 100644
--- a/src/interface/index.js
+++ b/src/interface/index.js
@@ -14,6 +14,7 @@ import Menu from 'material-ui/Menu';
import MenuItem from 'material-ui/MenuItem';
import { Tabs, Tab } from 'material-ui/Tabs';
import Settings from './Settings.js';
+import MalyanControl from './MalyanControl.js';
import ReactResizeDetector from 'react-resize-detector';
import JSONToSketchData from 'doodle3d-core/shape/JSONToSketchData';
import createSceneData from 'doodle3d-core/d3/createSceneData.js';
@@ -334,6 +335,7 @@ class Interface extends React.Component {
{isSlicing && {progress.action}
}
{isSlicing && }
+ {settings && settings.printer === 'doodle3d_printer' && }
{onCancel &&
response.text())
+ .then(statusText => {
+ const [nozzleTemperature, nozzleTargetTemperature, bedTemperature, bedTargetTemperature, progress] = statusText.match(/\d+/g);
+ const status = { nozzleTemperature, nozzleTargetTemperature, bedTemperature, bedTargetTemperature, progress };
+
+ switch (statusText.charAt(statusText.length - 1)) {
+ case 'I':
+ status.state = 'idle';
+ break;
+ case 'P':
+ status.state = 'printing';
+ break;
+ default:
+ status.state = 'unknown';
+ break;
+ }
+ return status;
+ })
+}
+
+export function sleep(time) {
+ return new Promise(resolve => setTimeout(resolve, time));
+}
+
const GCODE_SERVER_URL = 'https://gcodeserver.doodle3d.com';
const CONNECT_URL = 'http://connect.doodle3d.com/';
@@ -127,6 +153,10 @@ export async function slice(target, name, mesh, settings, updateProgress) {
break;
case 'WIFI':
case 'DOODLE3D-WIFI-BOX':
+ if (settings.printer === 'doodle3d_printer') {
+ const { state } = await getMalyanStatus(settings.ip);
+ if (state !== 'idle') throw { message: 'printer must be idle before starting a print', code: 1 };
+ }
steps = 2;
break;
default:
@@ -161,7 +191,7 @@ export async function slice(target, name, mesh, settings, updateProgress) {
const file = new File([gcode], 'doodle.gcode', { type: 'plain/text' });
body.append('file', file);
- await fetchProgress(`http://${settings.ip}/set?code=M563 S4`, { method: 'GET' });
+ // await fetchProgress(`http://${settings.ip}/set?code=M563 S4`, { method: 'GET' });
await fetchProgress(`http://${settings.ip}/upload`, { method: 'POST', body }, (progress) => {
updateProgress({
action: 'Uploading',
diff --git a/test.js b/test.js
deleted file mode 100644
index d448d41..0000000
--- a/test.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import 'babel-polyfill'
-import React from 'react';
-import { render } from 'react-dom';
-import injectTapEventPlugin from 'react-tap-event-plugin';
-// import './fetch.js';
-
-injectTapEventPlugin();
-
-const IP = 'http://10.0.0.109';
-const DEFAULT_GCODE = `; Generated with Doodle3D Slicer V0.0.18
-G28
-G1 X30 Y30
-G1 X90 Y30
-G1 X30 Y30
-G1 X90 Y30
-G1 X30 Y30
-G1 X90 Y30
-G1 X30 Y30
-G1 X90 Y30
-G1 X30 Y30
-G1 X90 Y30
-G1 X30 Y30
-G1 X90 Y30
-; test
-`;
-
-const CIRCLE = `; Generated with Doodle3D Slicer V0.0.18
-G28
-G1 X50 Y70
-G1 X56.180339887498945 Y69.02113032590307
-G1 X61.75570504584947 Y66.18033988749895
-G1 X66.18033988749895 Y61.75570504584947
-G1 X69.02113032590307 Y56.180339887498945
-G1 X70 Y50
-G1 X69.02113032590307 Y43.819660112501055
-G1 X66.18033988749895 Y38.24429495415054
-G1 X61.75570504584947 Y33.819660112501055
-G1 X56.18033988749895 Y30.97886967409693
-G1 X50 Y30
-G1 X43.819660112501055 Y30.978869674096927
-G1 X38.24429495415054 Y33.819660112501055
-G1 X33.819660112501055 Y38.24429495415053
-G1 X30.97886967409693 Y43.81966011250105
-G1 X30 Y49.99999999999999
-G1 X30.978869674096927 Y56.180339887498945
-G1 X33.81966011250105 Y61.75570504584946
-G1 X38.24429495415053 Y66.18033988749895
-G1 X43.81966011250105 Y69.02113032590307
-; test
-`;
-
-// export function fetch(url, data = {}, onProgress) {
-// return new Promise((resolve, reject) => {
-// const request = new Request(url, data);
-// const xhr = new XMLHttpRequest();
-//
-// xhr.onload = () => {
-// const { status, statusText, responseURL: url } = xhr;
-// resolve(new Response(xhr.response, { status, statusText, url }));
-// }
-// xhr.onerror = () => reject(new TypeError('Network request failed'));
-// xhr.ontimeout = () => reject(new TypeError('Network request failed'));
-//
-// xhr.open(request.method, url);
-//
-// if (request.credentials === 'include') {
-// xhr.withCredentials = true
-// } else if (request.credentials === 'omit') {
-// xhr.withCredentials = false
-// }
-// if (xhr.upload && onProgress) xhr.upload.onprogress = onProgress;
-// if (xhr.responseType) xhr.responseType = 'blob';
-//
-// request.headers.forEach((value, name) => {
-// xhr.setRequestHeader(name, value)
-// });
-//
-// xhr.send(data.body);
-// });
-// }
-
-class Print extends React.Component {
- home = () => fetch(`${IP}/set?code=G28`, { method: 'GET', mode: 'no-cors' });
- status = () => fetch(`${IP}/inquiry`, { method: 'GET', mode: 'no-cors' })
- .then(response => response.text())
- .then(result => console.log('result: ', result));
- start = () => fetch(`${IP}/set?code=M565`, { method: 'GET', mode: 'no-cors' });
- stop = () => fetch(`${IP}/set?cmd={P:X}`, { method: 'GET', mode: 'no-cors' });
- upload = async () => {
- const gcode = this.refs.gcode.value;
-
- const headers = new Headers();
- headers.append('Content-Disposition', 'form-data; name="file"; filename="doodle.gcode"');
- headers.append('Content-Type', 'application/octet-stream');
- headers.append('Accept', 'application/json');
-
- const body = new FormData();
- const file = new File([gcode], 'doodle.gcode', { type: 'application/octet-stream' });
- body.append('file', file);
-
- const result = await fetch(`${IP}/upload`, { method: 'POST', mode: 'no-cors', headers, body });
- };
-
- render() {
- return (
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-render((
-
-), document.getElementById('app'));