diff --git a/package-lock.json b/package-lock.json
index 904c851..04700ef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.11",
"@material-ui/core": "^4.11.0",
+ "@monaco-editor/react": "^4.3.1",
"@sentry/react": "^6.0.0",
"@sentry/tracing": "^6.0.0",
"@testing-library/jest-dom": "^4.2.4",
@@ -3120,6 +3121,31 @@
"node": ">=8.0.0"
}
},
+ "node_modules/@monaco-editor/loader": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.2.0.tgz",
+ "integrity": "sha512-cJVCG/T/KxXgzYnjKqyAgsKDbH9mGLjcXxN6AmwumBwa2rVFkwvGcUj1RJtD0ko4XqLqJxwqsN/Z/KURB5f1OQ==",
+ "dependencies": {
+ "state-local": "^1.0.6"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.21.0 < 1"
+ }
+ },
+ "node_modules/@monaco-editor/react": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.3.1.tgz",
+ "integrity": "sha512-f+0BK1PP/W5I50hHHmwf11+Ea92E5H1VZXs+wvKplWUWOfyMa1VVwqkJrXjRvbcqHL+XdIGYWhWNdi4McEvnZg==",
+ "dependencies": {
+ "@monaco-editor/loader": "^1.2.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.25.0 < 1",
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -16643,6 +16669,12 @@
"node": "*"
}
},
+ "node_modules/monaco-editor": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.31.1.tgz",
+ "integrity": "sha512-FYPwxGZAeP6mRRyrr5XTGHD9gRXVjy7GUzF4IPChnyt3fS5WrNxIkS8DNujWf6EQy0Zlzpxw8oTVE+mWI2/D1Q==",
+ "peer": true
+ },
"node_modules/move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -21503,6 +21535,11 @@
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz",
"integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA=="
},
+ "node_modules/state-local": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
+ "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
+ },
"node_modules/static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -27515,6 +27552,23 @@
"react-is": "^16.8.0"
}
},
+ "@monaco-editor/loader": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.2.0.tgz",
+ "integrity": "sha512-cJVCG/T/KxXgzYnjKqyAgsKDbH9mGLjcXxN6AmwumBwa2rVFkwvGcUj1RJtD0ko4XqLqJxwqsN/Z/KURB5f1OQ==",
+ "requires": {
+ "state-local": "^1.0.6"
+ }
+ },
+ "@monaco-editor/react": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.3.1.tgz",
+ "integrity": "sha512-f+0BK1PP/W5I50hHHmwf11+Ea92E5H1VZXs+wvKplWUWOfyMa1VVwqkJrXjRvbcqHL+XdIGYWhWNdi4McEvnZg==",
+ "requires": {
+ "@monaco-editor/loader": "^1.2.0",
+ "prop-types": "^15.7.2"
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -38126,6 +38180,12 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
},
+ "monaco-editor": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.31.1.tgz",
+ "integrity": "sha512-FYPwxGZAeP6mRRyrr5XTGHD9gRXVjy7GUzF4IPChnyt3fS5WrNxIkS8DNujWf6EQy0Zlzpxw8oTVE+mWI2/D1Q==",
+ "peer": true
+ },
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -42087,6 +42147,11 @@
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz",
"integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA=="
},
+ "state-local": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
+ "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
+ },
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
diff --git a/package.json b/package.json
index 3ceca2c..8eaeb1a 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.11",
"@material-ui/core": "^4.11.0",
+ "@monaco-editor/react": "^4.3.1",
"@sentry/react": "^6.0.0",
"@sentry/tracing": "^6.0.0",
"@testing-library/jest-dom": "^4.2.4",
diff --git a/src/components/CodeEditor/CodeEditor.js b/src/components/CodeEditor/CodeEditor.js
new file mode 100644
index 0000000..75d2fb6
--- /dev/null
+++ b/src/components/CodeEditor/CodeEditor.js
@@ -0,0 +1,206 @@
+import React from "react";
+import { useState, useRef } from "react";
+import { default as MonacoEditor } from "@monaco-editor/react";
+import { withRouter } from "react-router-dom";
+import { Button, Grid } from "@material-ui/core";
+import Blockly from "blockly/core";
+import Divider from "@material-ui/core/Divider";
+import { saveAs } from "file-saver";
+import Drawer from "@material-ui/core/Drawer";
+import Sidebar from "./Sidebar";
+import Dialog from "../Dialog";
+
+const CodeEditor = (props) => {
+ const [fileHandle, setFileHandle] = useState();
+ const [fileContent, setFileContent] = useState("");
+ const [progress, setProgress] = useState(false);
+ const [id, setId] = useState("");
+ const [open, setOpen] = useState(false);
+ const [error, setError] = useState("");
+ const editorRef = useRef(null);
+
+ const compile = () => {
+ setProgress(true);
+ const data = {
+ board: process.env.REACT_APP_BOARD,
+ sketch: editorRef.current.getValue(),
+ };
+ fetch(`${process.env.REACT_APP_COMPILER_URL}/compile`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(data),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ if (data.code === "Internal Server Error") {
+ setProgress(false);
+ setOpen(true);
+ setError(data.message);
+ }
+ setProgress(false);
+ const result = data.data.id;
+ setId(result);
+ console.log(result);
+ const filename = "sketch";
+ window.open(
+ `${process.env.REACT_APP_COMPILER_URL}/download?id=${result}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`,
+ "_self"
+ );
+ })
+ .catch((err) => {
+ console.log(err);
+ });
+ };
+
+ const saveIno = () => {
+ var filename = "sketch";
+ var code = editorRef.current.getValue();
+
+ filename = `${filename}.ino`;
+ var blob = new Blob([code], { type: "text/plain;charset=utf-8" });
+ saveAs(blob, filename);
+ };
+
+ const openIno = async () => {
+ const [myFileHandle] = await window.showOpenFilePicker();
+ setFileHandle(myFileHandle);
+
+ const file = await myFileHandle.getFile();
+ const contents = await file.text();
+ setFileContent(contents);
+ };
+
+ const toggleDrawer = (anchor, open) => (event) => {
+ if (
+ event.type === "keydown" &&
+ (event.key === "Tab" || event.key === "Shift")
+ ) {
+ return;
+ }
+
+ setOpen(false);
+ };
+
+ const loadCode = () => {
+ editorRef.current.setValue("test");
+ };
+
+ return (
+
+
+
+
+ {Blockly.Msg.drawer_ideerror_head}
+
+
+ {Blockly.Msg.drawer_ideerror_text}
+
+
+
+ {" "}
+ {`${error}`}{" "}
+
+
+
+ Code Editor
+ {
+ editorRef.current = editor;
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default withRouter(CodeEditor);
diff --git a/src/components/CodeEditor/Compile.js b/src/components/CodeEditor/Compile.js
new file mode 100644
index 0000000..1bea26c
--- /dev/null
+++ b/src/components/CodeEditor/Compile.js
@@ -0,0 +1,338 @@
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
+import { workspaceName } from "../../actions/workspaceActions";
+
+import { detectWhitespacesAndReturnReadableResult } from "../../helpers/whitespace";
+
+import { withStyles } from "@material-ui/core/styles";
+import Button from "@material-ui/core/Button";
+import Backdrop from "@material-ui/core/Backdrop";
+import CircularProgress from "@material-ui/core/CircularProgress";
+import IconButton from "@material-ui/core/IconButton";
+import Tooltip from "@material-ui/core/Tooltip";
+import Divider from "@material-ui/core/Divider";
+import { faClipboardCheck } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as Blockly from "blockly/core";
+import Copy from "../copy.svg";
+import Prism from "prismjs";
+import "prismjs/themes/prism.css";
+import "prismjs/plugins/line-numbers/prism-line-numbers";
+import "prismjs/plugins/line-numbers/prism-line-numbers.css";
+import MuiDrawer from "@material-ui/core/Drawer";
+import Dialog from "../Dialog";
+
+const styles = (theme) => ({
+ backdrop: {
+ zIndex: theme.zIndex.drawer + 1,
+ color: "#fff",
+ },
+ iconButton: {
+ backgroundColor: theme.palette.button.compile,
+ color: theme.palette.primary.contrastText,
+ width: "40px",
+ height: "40px",
+ "&:hover": {
+ backgroundColor: theme.palette.button.compile,
+ color: theme.palette.primary.contrastText,
+ },
+ },
+ button: {
+ backgroundColor: theme.palette.button.compile,
+ color: theme.palette.primary.contrastText,
+ "&:hover": {
+ backgroundColor: theme.palette.button.compile,
+ color: theme.palette.primary.contrastText,
+ },
+ },
+});
+
+const Drawer = withStyles((theme) => ({
+ paperAnchorBottom: {
+ backgroundColor: "black",
+ height: "20vH",
+ },
+}))(MuiDrawer);
+
+class Compile extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ progress: false,
+ open: false,
+ file: false,
+ title: "",
+ content: "",
+ name: props.name,
+ error: "",
+ appLink: "",
+ appDialog: false,
+ };
+ }
+
+ componentDidMount() {
+ Prism.highlightAll();
+ }
+
+ componentDidUpdate(props) {
+ if (props.name !== this.props.name) {
+ this.setState({ name: this.props.name });
+ }
+ Prism.highlightAll();
+ }
+
+ compile = () => {
+ this.setState({ progress: true });
+ const data = {
+ board: process.env.REACT_APP_BOARD,
+ sketch: this.props.arduino,
+ };
+ fetch(`${process.env.REACT_APP_COMPILER_URL}/compile`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(data),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ if (data.code === "Internal Server Error") {
+ this.setState({
+ progress: false,
+ file: false,
+ open: true,
+ title: Blockly.Msg.compiledialog_headline,
+ content: Blockly.Msg.compiledialog_text,
+ error: data.message,
+ });
+ }
+ this.setState({ id: data.data.id }, () => {
+ this.createFileName();
+ });
+ })
+ .catch((err) => {
+ console.log(err);
+ //this.setState({ progress: false, file: false, open: true, title: Blockly.Msg.compiledialog_headline, content: Blockly.Msg.compiledialog_text });
+ });
+ };
+
+ download = () => {
+ const id = this.state.id;
+ const filename = detectWhitespacesAndReturnReadableResult(this.state.name);
+ this.toggleDialog();
+ this.props.workspaceName(this.state.name);
+ window.open(
+ `${process.env.REACT_APP_COMPILER_URL}/download?id=${id}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`,
+ "_self"
+ );
+ this.setState({ progress: false });
+ };
+
+ toggleDialog = () => {
+ this.setState({ open: !this.state, progress: false, appDialog: false });
+ };
+
+ createFileName = () => {
+ if (this.props.platform === true) {
+ const filename = detectWhitespacesAndReturnReadableResult(
+ this.state.name
+ );
+ this.setState({
+ link: `blocklyconnect-app://sketch/${filename}/${this.state.id}`,
+ });
+ this.setState({ appDialog: true });
+ } else {
+ if (this.state.name) {
+ this.download();
+ } else {
+ this.setState({
+ file: true,
+ open: true,
+ title: "Projekt kompilieren",
+ content:
+ "Bitte gib einen Namen für die Bennenung des zu kompilierenden Programms ein und bestätige diesen mit einem Klick auf 'Eingabe'.",
+ });
+ }
+ }
+
+ // if (this.state.name) {
+ // this.download();
+ // } else {
+ // this.setState({
+ // file: true,
+ // open: true,
+ // title: "Projekt kompilieren",
+ // content:
+ // "Bitte gib einen Namen für die Bennenung des zu kompilierenden Programms ein und bestätige diesen mit einem Klick auf 'Eingabe'.",
+ // });
+ // }
+ };
+
+ setFileName = (e) => {
+ this.setState({ name: e.target.value });
+ };
+
+ toggleDrawer = (anchor, open) => (event) => {
+ if (
+ event.type === "keydown" &&
+ (event.key === "Tab" || event.key === "Shift")
+ ) {
+ return;
+ }
+
+ this.setState({ open: false });
+ };
+
+ render() {
+ return (
+
+ {this.props.iconButton ? (
+
+ this.compile()}
+ >
+
+
+
+ ) : (
+
+ )}
+
+ {this.props.platform === false ? (
+
+
+

+
{Blockly.Msg.compile_overlay_head}
+
{Blockly.Msg.compile_overlay_text}
+
+ {Blockly.Msg.compile_overlay_help}
+
+ FAQ
+
+
+
+
+
+ ) : (
+
+
+ {/*

*/}
+
Dein Code wird kompiliert!
+
übertrage ihn anschließend mithlfe der senseBoxConnect-App
+
+ {Blockly.Msg.compile_overlay_help}
+
+ FAQ
+
+
+
+
+
+ )}
+
+
+ {Blockly.Msg.drawer_ideerror_head}
+
+
+ {Blockly.Msg.drawer_ideerror_text}
+
+
+
+ {" "}
+ {`${this.state.error}`}{" "}
+
+
+
+
+ );
+ }
+}
+
+Compile.propTypes = {
+ arduino: PropTypes.string.isRequired,
+ name: PropTypes.string,
+ workspaceName: PropTypes.func.isRequired,
+ platform: PropTypes.bool.isRequired,
+};
+
+const mapStateToProps = (state) => ({
+ arduino: state.workspace.code.arduino,
+ name: state.workspace.name,
+ platform: state.general.platform,
+});
+
+export default connect(mapStateToProps, { workspaceName })(
+ withStyles(styles, { withTheme: true })(Compile)
+);
diff --git a/src/components/CodeEditor/Sidebar.js b/src/components/CodeEditor/Sidebar.js
new file mode 100644
index 0000000..e051c71
--- /dev/null
+++ b/src/components/CodeEditor/Sidebar.js
@@ -0,0 +1,114 @@
+import React from "react";
+import Blockly from "blockly";
+import Accordion from "@material-ui/core/Accordion";
+import AccordionSummary from "@material-ui/core/AccordionSummary";
+import AccordionDetails from "@material-ui/core/AccordionDetails";
+import Typography from "@material-ui/core/Typography";
+import { LibraryVersions } from "../../data/versions.js";
+import { ArduinoExamples } from "../../data/arduinoExamples.js";
+import Editor, { useMonaco } from "@monaco-editor/react";
+import { Button } from "@material-ui/core";
+import Dialog from "../Dialog";
+
+const Sidebar = () => {
+ const [alert, setAlert] = React.useState(false);
+
+ const monaco = useMonaco();
+ const loadCode = (code) => {
+ console.log(code);
+ console.log(monaco);
+ const defaultCode = `
+void setup () {
+
+}
+
+void loop(){
+
+}`;
+ var currentCode = monaco.editor.getModels()[0].getValue();
+
+ setAlert(true);
+ monaco.editor.getModels()[0].setValue(code);
+ };
+
+ const toggleDialog = () => {
+ setAlert(false);
+ };
+
+ return (
+
+
+
+
+
+ {ArduinoExamples().map((object, i) => {
+ return (
+
+ );
+ })}
+
+
+
+
+
+
+
+
+ For Dokumentation take a look at the installed libraries and their
+ source
+
+ {LibraryVersions().map((object, i) => {
+ return (
+
+
+ {object.library} {object.version}
+
+
+ );
+ })}
+
+
+
+
+
+ );
+};
+
+export default Sidebar;
diff --git a/src/components/Navbar.js b/src/components/Navbar.js
index 8977637..10e3874 100644
--- a/src/components/Navbar.js
+++ b/src/components/Navbar.js
@@ -230,6 +230,11 @@ class Navbar extends Component {
icon: faLightbulb,
link: "/gallery",
},
+ {
+ text: "CodeEditor",
+ icon: faLightbulb,
+ link: "/codeeditor",
+ },
{
text: Blockly.Msg.navbar_projects,
icon: faLayerGroup,
diff --git a/src/components/Route/Routes.js b/src/components/Route/Routes.js
index 8bd9239..844fb66 100644
--- a/src/components/Route/Routes.js
+++ b/src/components/Route/Routes.js
@@ -24,6 +24,7 @@ import Login from "../User/Login";
import Account from "../User/Account";
import News from "../News";
import Faq from "../Faq";
+import CodeEditor from "../CodeEditor/CodeEditor";
class Routes extends Component {
componentDidUpdate() {
@@ -47,6 +48,9 @@ class Routes extends Component {
+
+
+
{/* Sharing */}
diff --git a/src/data/arduinoExamples.js b/src/data/arduinoExamples.js
new file mode 100644
index 0000000..207c203
--- /dev/null
+++ b/src/data/arduinoExamples.js
@@ -0,0 +1,16 @@
+import * as Blockly from "blockly/core";
+
+export const ArduinoExamples = () => {
+ return [
+ {
+ name: "MCU Component Test",
+ description: "Test the different compoenents of the MCU",
+ code: '// senseBox:home WiFi is enabled by default!\n// If you have a senseBox:home Ethernet comment out line 5\n// and comment in line 4\n// Do not comment in both at the same time!\n//#define ENABLE_ETHERNET\n#define ENABLE_WIFI\n\n#include \n#include \n#ifdef ENABLE_WIFI\n#include \n#include \n#endif\n#ifdef ENABLE_ETHERNET\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n/********WiFi User Settings********/\nconst char *ssid = ""; // your network SSID (name)\nconst char *pass = ""; // your network password\n/**********************************/\nchar server[] = "internet-test.testing.opensensemap.org";\n#ifdef ENABLE_WIFI\nint status = WL_IDLE_STATUS;\nWiFiClient client;\n#endif\n\n#ifdef ENABLE_ETHERNET\n/********Ethernet User Settings********/\n//Configure static IP setup (only needed if DHCP is disabled)\nbyte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED};\nIPAddress myIp(192, 168, 0, 42);\nIPAddress myDns(8, 8, 8, 8);\nIPAddress myGateway(192, 168, 0, 177);\nIPAddress mySubnet(255, 255, 255, 0);\n/**********************************/\nEthernetClient ethernetClient;\n#endif\n\n#define CMD_RESET (0x00)\n#define CMD_SEND (0x03)\n#define ECC_READ (0x02) // read command\n#define ECC_WRITE (0x12) // write command\n#define ECC_ZONE_CFG (0x00) // configuration zone\n#define ECC_ZONE_CNT_FLAG (0x80) // 1=32 bytes, 0=4 bytes\nvoid setup() {\n Serial.begin(9600);\n while(!Serial); // wait until serial is ready\n printMenu();\n // power on required ports\n senseBoxIO.powerI2C(false);\n senseBoxIO.powerXB1(false);\n senseBoxIO.powerUART(false);\n delay(250);\n senseBoxIO.powerI2C(true);\n senseBoxIO.powerXB1(true);\n senseBoxIO.powerUART(true);\n // init UART and I2C\n Serial1.begin(9600);\n Serial2.begin(9600);\n Wire.begin();\n}\nvoid loop() {\n char rx;\n if (Serial.available() > 0)\n {\n\n rx = Serial.read(); // get the character\n Serial.println("\\n\\n");\n // check if a number was received\n switch(rx)\n {\n case \'1\':\n check_uart_sensor();\n Serial.println("\\nI2C/Wire:");\n byte devices, address;\n devices = 0;\n for(address = 1; address < 127; address++ )\n {\n Wire.beginTransmission(address);\n byte error = Wire.endTransmission();\n\n if(error == 0)\n {\n devices++;\n Serial.print("Device found at 0x");\n delay(100);\n Serial.print(address, HEX);\n Serial.println();\n check_i2c_sensor(address);\n }\n else if(error==4)\n {\n Serial.print("Unknow error at 0x");\n delay(100);\n Serial.println(address, HEX);\n }\n }\n\n if(devices == 0) Serial.println("No devices found\\n");\n senseBoxIO.statusNone();\n delay(250);\n break;\n #ifdef ENABLE_WIFI\n case \'2\':\n connectionWiFiTest();\n Serial.println("");\n delay(250);\n break;\n #endif\n #ifdef ENABLE_ETHERNET\n case \'3\':\n connectionEthernetTest();\n Serial.println("");\n delay(250);\n break;\n #endif\n case \'4\':\n Serial.println("Security key:");\n getSecKey();\n Serial.println();\n delay(250);\n break;\n case \'5\':\n Serial.flush();\n NVIC_SystemReset();\n break;\n }\n Serial.flush();\n }\n}\nvoid printMenu()\n{\n Serial.println("senseBox MCU option menu\\nType one of the numbers in the input field above and hit \'Enter\'.");\n delay(100);\n Serial.println(" 1 - Find connected devices");\n #ifdef ENABLE_WIFI\n delay(100);\n Serial.println(" 2 - Test connection to openSenseMap (WiFi on XBee1)");\n #endif\n #ifdef ENABLE_ETHERNET\n delay(100);\n Serial.println(" 3 - Test connection to openSenseMap (Ethernet on XBee1)");\n #endif\n delay(100);\n Serial.println(" 4 - Get security key\\n");\n return;\n}\nvoid check_uart_sensor(){\n Serial.println("UART/Serial Port:");\n SDS011 sds1(Serial1);\n SDS011 sds2(Serial2);\n float pm10,pm25;\n int sds_error;\n sds_error = sds1.read(&pm25,&pm10);\n if (!sds_error)\n {\n Serial.println("SDS011 dust particle sensor found at serial port #1.");\n }\n else\n {\n sds_error = sds2.read(&pm25,&pm10);\n if (!sds_error)\n {\n Serial.println("SDS011 dust particle sensor found at serial port #2.");\n return;\n }\n }\n Serial.println("No device found.");\n}\nvoid check_i2c_sensor(byte address)\n{\n float t=0, h=0, p=0, a=0;\n unsigned int u=0;\n unsigned long l=0;\n Adafruit_BMP280 bmp280;\n Adafruit_BME280 bme280;\n Adafruit_BME680 bme680;\n Adafruit_HDC1000 hdc;\n if((address == 0) || (address > 127))\n {\n return;\n }\n switch(address)\n {\n case 0x29: //TSL45315\n Serial.println("--- TSL45315");\n Wire.beginTransmission(address);\n Wire.write(0x80|0x00); //control\n Wire.write(0x03);\n Wire.endTransmission();\n Wire.beginTransmission(address);\n Wire.write(0x80|0x01); //config\n Wire.write(0x02); //M=4 T=100ms\n Wire.endTransmission();\n delay(120);\n Wire.beginTransmission(address);\n Wire.write(0x80|0x04); //data low\n Wire.endTransmission();\n Wire.requestFrom((uint8_t)address, (uint8_t)2);\n delay(1);\n u |= (Wire.read()<<8);\n u |= (Wire.read()<<8);\n l = u * 4;\n Serial.print("Lux ");\n Serial.println(l, DEC);\n break;\n case 0x38: //VEML6070\n //case 0x39:\n Serial.println("--- VEML6070 (0x38+0x39)");\n Wire.beginTransmission(address);\n Wire.write((0x1<<2) | 0x02); //Integration Time 1\n Wire.endTransmission();\n delay(120);\n Wire.requestFrom((uint8_t)(address+1), (uint8_t)1); //MSB\n delay(1);\n u |= (Wire.read()<<8);\n Wire.requestFrom((uint8_t)(address+0), (uint8_t)1); //LSB\n delay(1);\n u |= (Wire.read()<<0);\n Serial.print("UV ");\n Serial.println(u, DEC);\n break;\n case 0x40: //HDC100X\n case 0x41:\n //case 0x42:\n case 0x43:\n Serial.println("--- HDC100X");\n hdc.begin(address);\n t = hdc.readTemperature();\n h = hdc.readHumidity();\n Serial.print("Temp ");\n Serial.print(t, DEC);\n Serial.println(" *C");\n Serial.print("Humi ");\n Serial.print(h, DEC);\n Serial.println(" %");\n break;\n case 0x76: //BMP280 or BME280 or BME680\n case 0x77:\n if(bmp280.begin(address) != 0)\n {\n Serial.println("--- BMP280");\n delay(100);\n t = bmp280.readTemperature();\n p = bmp280.readPressure();\n a = bmp280.readAltitude(1013.25); //1013.25 = sea level pressure\n }\n else if(bme280.begin(address) != 0)\n {\n Serial.println("--- BME280");\n delay(100);\n t = bme280.readTemperature();\n p = bme280.readPressure();\n a = bme280.readAltitude(1013.25); //1013.25 = sea level pressure\n h = bme280.readHumidity();\n }\n else if(bme680.begin(address) != 0)\n {\n Serial.println("--- BME680");\n delay(100);\n bme680.performReading();\n t = bme680.temperature;\n p = bme680.pressure;\n a = bme680.readAltitude(1013.25); //1013.25 = sea level pressure\n h = bme680.humidity;\n u = bme680.gas_resistance / 1000.0;\n }\n else\n {\n Wire.beginTransmission(address);\n Wire.write(0xD0); //chip id\n Wire.endTransmission();\n Wire.requestFrom(address, (byte)1);\n delay(1);\n u = Wire.read();\n if(u == 0x58) //BMP280\n {\n Serial.println("--- BMP280");\n }\n else if(u == 0x60) //BME280\n {\n Serial.println("--- BME280");\n }\n else if(u == 0x61) //BME680\n {\n Serial.println("--- BME680");\n }\n }\n Serial.print("Temp ");\n Serial.print(t, DEC);\n Serial.println(" *C");\n Serial.print("Pres ");\n Serial.print(p/100.0, DEC);\n Serial.println(" hPa");\n Serial.print("Alti ");\n Serial.print(a, DEC);\n Serial.println(" m");\n if(h != 0)\n {\n Serial.print("Humi ");\n Serial.print(h, DEC);\n Serial.println(" %");\n }\n if(u != 0)\n {\n Serial.print("Gas ");\n Serial.print(u, DEC);\n Serial.println(" kOhm");\n }\n break;\n case 0x42: //CAM-M8Q\n Serial.println("--- CAM-M8Q");\n break;\n case 0x50: //24LCxxx EEPROM\n Serial.println("--- 24LCxxx");\n break;\n case 0x60: //ATECCx08\n Serial.println("--- ATECCx08");\n break;\n case 0x68: //RV8523\n Serial.println("--- RV8523");\n break;\n }\n delay(250); //wait 250ms\n}\nvoid getSecKey()\n{\n Wire1.begin();\n // init ATECC\n write(CMD_RESET, 0x00); // reset\n delay(100); // wait 100ms\n // read config zone\n byte buf[64]; // buffer\n buf[0] = 5+2; // length: data + 2 crc bytes\n buf[1] = ECC_READ; // cmd\n buf[2] = ECC_ZONE_CFG|ECC_ZONE_CNT_FLAG; // param 1\n buf[3] = 0x00; // addr lsb\n buf[4] = 0x00; // addr msb\n //buf[5] = 0x00; // crc\n //buf[6] = 0x00; // crc\n calc_crc(buf, buf[0]-2, &buf[5]); // calc crc\n write(CMD_SEND, buf, buf[0]); // send cmd\n delay(10); // wait 10ms\n read(buf, sizeof(buf)); // read response\n Serial.print("0");\n Serial.print(buf[1], HEX); Serial.print(" ");\n Serial.print(buf[2], HEX); Serial.print(" ");\n Serial.print(buf[3], HEX); Serial.print(" ");\n Serial.print(buf[4], HEX); Serial.print(" ");\n Serial.print(buf[ 9], HEX); Serial.print(" ");\n Serial.print(buf[10], HEX); Serial.print(" ");\n Serial.print(buf[11], HEX); Serial.print(" ");\n Serial.print(buf[12], HEX); Serial.print(" ");\n Serial.print(buf[13], HEX); Serial.print(" ");\n Serial.println("");\n}\nvoid read(byte *data, byte max_len)\n{\n byte len;\n Wire1.requestFrom(I2C_ATECC, 1); // request length\n while(Wire1.available() == 0); // wait for data bytes\n len = Wire1.read();\n *data++ = len;\n if(len)\n {\n Wire1.requestFrom(I2C_ATECC, len); // request x bytes\n while(Wire1.available() == 0); // wait for data bytes\n delay(10); // wait 10ms\n for(byte i = 0; (i < len) && (i < max_len); i++)\n {\n *data++ = Wire1.read(); // read data byte\n }\n }\n}\nvoid write(byte reg, byte *data, byte len)\n{\n Wire1.beginTransmission(I2C_ATECC); // start transmission\n Wire1.write(reg); // write register byte\n for(; len != 0; len--)\n {\n Wire1.write(*data++); // write data byte\n }\n Wire1.endTransmission(); // stop transmission\n}\nvoid write(byte reg, byte data)\n{\n Wire1.beginTransmission(I2C_ATECC); // start transmission\n Wire1.write(reg); // write register byte\n Wire1.write(data); // write data byte\n Wire1.endTransmission(); // stop transmission\n}\nvoid calc_crc(byte *data, byte len, byte *crc)\n{\n uint8_t i, shift_reg, data_bit, crc_bit;\n uint16_t crc_reg = 0;\n uint16_t polynom = 0x8005;\n for(i = 0; i < len; i++)\n {\n for(shift_reg = 0x01; shift_reg > 0x00; shift_reg <<= 1)\n {\n data_bit = (data[i] & shift_reg) ? 1 : 0;\n crc_bit = crc_reg >> 15;\n crc_reg <<= 1;\n if(data_bit != crc_bit)\n {\n crc_reg ^= polynom;\n }\n }\n }\n crc[0] = (byte)(crc_reg & 0x00FF);\n crc[1] = (byte)(crc_reg >> 8);\n}\nvoid connectionWiFiTest(){\n #ifdef ENABLE_WIFI\n if (WiFi.status() == WL_NO_SHIELD)\n {\n Serial.println("WiFi bee not present");\n return;\n }\n Serial.println("Check WiFi firmware:");\n Serial.println("====================");\n // Print firmware version on the shield\n String fv = WiFi.firmwareVersion();\n String latestFv;\n Serial.print("Firmware version installed: ");\n Serial.println(fv);\n\n if (REV(GET_CHIPID()) >= REV_3A0) {\n // model B\n latestFv = WIFI_FIRMWARE_LATEST_MODEL_B;\n } else {\n // model A\n latestFv = WIFI_FIRMWARE_LATEST_MODEL_A;\n }\n\n // Print required firmware version\n Serial.print("Latest firmware version available : ");\n Serial.println(latestFv);\n\n // Check if the latest version is installed\n Serial.println();\n if (fv == latestFv || fv == "19.5.2") {\n Serial.println("Check result: PASSED");\n } else {\n Serial.println("Check result: NOT PASSED");\n Serial.println(" - The firmware version on the shield do not match the");\n Serial.println(" version required by the library, you may experience");\n Serial.println(" issues or failures.");\n Serial.println(" - Update the firmware at least to version 19.5.2");\n }\n\n Serial.println();\n Serial.println("Check internet connectivity:");\n Serial.println("============================");\n\n if (WiFi.status() != WL_CONNECTED) {\n Serial.print("Connecting to WiFi...");\n delay(1000); // wait 1s\n WiFi.begin(ssid, pass);\n delay(5000); // wait 5s\n }\n if (WiFi.status() == WL_CONNECTED) Serial.println("connected!");\n else\n {\n Serial.println("failed! Please check SSID and password.");\n return;\n }\n for (uint8_t timeout = 2; timeout != 0; timeout--)\n {\n Serial.print("Calling openSenseMap server...");\n if (client.connect(server, 80))\n {\n Serial.println("connected!");\n // Make a HTTP request:\n client.println("GET / HTTP/1.1");\n client.print("Host: ");\n client.println(server);\n client.println("Connection: close");\n client.println();\n }\n break;\n }\n if(client.connected())\n {\n // wait for server response\n Serial.println("Server response:\\n");\n while (!client.available())\n {\n delay(1);\n }\n // read server response\n while (client.available())\n {\n char c = client.read();\n Serial.write(c);\n }\n Serial.print("\\n");\n Serial.println("Disconnecting from server.");\n client.flush();\n client.stop();\n }else Serial.println("failed after 3 trys!");\n Serial.println("Disconnecting from WiFi.");\n WiFi.disconnect();\n #endif\n}\n\nvoid connectionEthernetTest() {\n #ifdef ENABLE_ETHERNET\n Ethernet.init(PIN_XB1_CS);\n Serial.println("Trying to initialize DHCP...");\n if (Ethernet.begin(mac) == 0) {\n Serial.println("Failed to configure Ethernet using DHCP");\n // start the Ethernet connection using a fixed IP address and DNS server:\n Serial.println("Trying Ethernet connection using a fixed IP address and DNS server");\n Ethernet.begin(mac, myIp, myDns, mySubnet);\n } else {\n // print your local IP address:\n Serial.println("DHCP is working.");\n Serial.print("My IP address: ");\n for (byte thisByte = 0; thisByte < 4; thisByte++) {\n // print the value of each byte of the IP address:\n Serial.print(Ethernet.localIP()[thisByte], DEC);\n Serial.print(".");\n }\n Serial.println();\n }\n for (uint8_t timeout = 2; timeout != 0; timeout--)\n {\n Serial.print("Calling openSenseMap server...");\n if (ethernetClient.connect(server, 80))\n {\n Serial.println("connected!");\n // Make a HTTP request:\n ethernetClient.println("GET / HTTP/1.1");\n ethernetClient.print("Host: ");\n ethernetClient.println(server);\n ethernetClient.println("Connection: close");\n ethernetClient.println();\n }\n break;\n }\n if(ethernetClient.connected())\n {\n // wait for server response\n Serial.println("Server response:\\n");\n while (!ethernetClient.available())\n {\n delay(1);\n }\n // read server response\n while (ethernetClient.available())\n {\n char c = ethernetClient.read();\n Serial.write(c);\n }\n Serial.print("\\n");\n Serial.println("Disconnecting from server.");\n ethernetClient.flush();\n ethernetClient.stop();\n }\n else Serial.println("failed after 3 trys!");\n #endif\n}',
+ },
+ {
+ name: "ArduinoBearSSL",
+ description: "BearSSL is a TLS/SSL library for Arduino",
+ code: "",
+ },
+ ];
+};
diff --git a/src/data/versions.js b/src/data/versions.js
new file mode 100644
index 0000000..d5d2e2c
--- /dev/null
+++ b/src/data/versions.js
@@ -0,0 +1,104 @@
+import * as Blockly from "blockly/core";
+
+export const LibraryVersions = () => {
+ return [
+ {
+ version: "1.4.2",
+ library: "sensebox/SenseBoxMCU-Lib",
+ link: "https://github.com/sensebox/SenseBoxMCU-Lib",
+ },
+ {
+ version: "1.0.12",
+ library: "sparkfun/SparkFun_SCD30_Arduino_Library",
+ },
+ { version: "1.2.3", library: "adafruit/Adafruit-GFX-Library" },
+ {
+ version: "2.1.2",
+ library: "adafruit/Adafruit_BME280_Library",
+ },
+ {
+ version: "2.1.0",
+ library: "adafruit/Adafruit_BMP280_Library",
+ },
+ {
+ version: "1.1.1",
+ library: "adafruit/Adafruit_BME680",
+ },
+ {
+ version: "2.0.1",
+ library: "adafruit/Adafruit_BMP3XX",
+ },
+ {
+ version: "2.0.0",
+ library: "adafruit/Adafruit_HDC1000_Library",
+ },
+ {
+ version: "1.7.1",
+ library: "adafruit/Adafruit_BusIO",
+ },
+ {
+ version: "1.0.6",
+ library: "adafruit/Adafruit_NeoPixel",
+ },
+ {
+ version: "1.1.2",
+ library: "adafruit/Adafruit_SSD1306",
+ },
+ {
+ version: "1.0.2",
+ library: "adafruit/Adafruit_Sensor",
+ },
+ {
+ version: "3.8.0",
+ library: "milesburton/Arduino-Temperature-Control-Library",
+ },
+ {
+ version: "1.5.0",
+ library: "arduino-libraries/ArduinoBearSSL",
+ },
+ {
+ version: "1.3.4",
+ library: "arduino-libraries/ArduinoECCX08",
+ },
+ {
+ version: "2.0.0",
+ library: "arduino-libraries/ArduinoECCX08", //todo
+ },
+ {
+ version: "0.7.1",
+ library: "cmaglie/FlashStorage",
+ },
+ {
+ version: "1.5.1",
+ library: "matthijskooijman/arduino-lmic",
+ },
+ {
+ version: "3.0.1",
+ library: "thesolarnomad/lora-serialization ",
+ },
+ {
+ version: "todo",
+ library: "TSL45xxx",
+ },
+ {
+ version: "2.3.4",
+ library: "teensy/td_libs_OneWire.html",
+ },
+ {
+ version: "1.0.0",
+ library: "watterott/Arduino-Libs/tree/master/RV8523",
+ },
+ {
+ version: "1.0.0",
+ library: "sensebox/SDS011-select-serial ",
+ },
+ {
+ version: "1.0.0",
+ library: "Lucas-Steinmann/SSD1306-Plot-Library",
+ },
+ {
+ version: "1.0.0",
+ library: "senseBoxIO",
+ },
+ ];
+};
diff --git a/yarn.lock b/yarn.lock
index 7ed0fee..f31665f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1542,6 +1542,21 @@
"prop-types" "^15.7.2"
"react-is" "^16.8.0"
+"@monaco-editor/loader@^1.2.0":
+ "integrity" "sha512-cJVCG/T/KxXgzYnjKqyAgsKDbH9mGLjcXxN6AmwumBwa2rVFkwvGcUj1RJtD0ko4XqLqJxwqsN/Z/KURB5f1OQ=="
+ "resolved" "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.2.0.tgz"
+ "version" "1.2.0"
+ dependencies:
+ "state-local" "^1.0.6"
+
+"@monaco-editor/react@^4.3.1":
+ "integrity" "sha512-f+0BK1PP/W5I50hHHmwf11+Ea92E5H1VZXs+wvKplWUWOfyMa1VVwqkJrXjRvbcqHL+XdIGYWhWNdi4McEvnZg=="
+ "resolved" "https://registry.npmjs.org/@monaco-editor/react/-/react-4.3.1.tgz"
+ "version" "4.3.1"
+ dependencies:
+ "@monaco-editor/loader" "^1.2.0"
+ "prop-types" "^15.7.2"
+
"@nodelib/fs.scandir@2.1.4":
"integrity" "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA=="
"resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz"
@@ -8224,6 +8239,11 @@
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz"
"version" "2.29.0"
+"monaco-editor@>= 0.21.0 < 1", "monaco-editor@>= 0.25.0 < 1":
+ "integrity" "sha512-FYPwxGZAeP6mRRyrr5XTGHD9gRXVjy7GUzF4IPChnyt3fS5WrNxIkS8DNujWf6EQy0Zlzpxw8oTVE+mWI2/D1Q=="
+ "resolved" "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.31.1.tgz"
+ "version" "0.31.1"
+
"move-concurrently@^1.0.1":
"integrity" "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I="
"resolved" "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz"
@@ -10032,7 +10052,7 @@
"strip-ansi" "6.0.0"
"text-table" "0.2.0"
-"react-dom@^17.0.0", "react-dom@^17.0.2":
+"react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0", "react-dom@^17.0.2":
"integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
"version" "17.0.2"
@@ -10211,7 +10231,7 @@
"loose-envify" "^1.4.0"
"prop-types" "^15.6.2"
-"react@^16.8.3 || ^17", "react@^17.0.0", "react@^17.0.2", "react@>= 16", "react@17.0.2":
+"react@^16.8.0 || ^17.0.0", "react@^16.8.3 || ^17", "react@^17.0.0", "react@^17.0.2", "react@>= 16", "react@17.0.2":
"integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA=="
"resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
"version" "17.0.2"
@@ -11408,6 +11428,11 @@
"resolved" "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz"
"version" "1.2.0"
+"state-local@^1.0.6":
+ "integrity" "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
+ "resolved" "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz"
+ "version" "1.0.7"
+
"static-extend@^0.1.1":
"integrity" "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY="
"resolved" "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz"