Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18b33946b5 | ||
|
|
69f3bf1db0 | ||
|
|
512839e1f5 | ||
|
|
ec141088cc | ||
|
|
be51eff3c8 | ||
|
|
cfd6fedc6e | ||
|
|
126606f4f5 | ||
|
|
cb12aef535 | ||
|
|
345c15ed77 | ||
|
|
b05b3017e1 | ||
|
|
a4641938f0 | ||
|
|
9526b154bf | ||
|
|
745f6940ec | ||
|
|
2874620a9f | ||
|
|
9bf17aed67 | ||
|
|
f6e5d086b5 | ||
|
|
50ffad0ad2 | ||
|
|
3a6fd07647 | ||
|
|
9295d92c65 | ||
|
|
338a0aada6 | ||
|
|
a528bb7378 | ||
|
|
719be33756 | ||
|
|
d983677d22 |
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: Short Issue
|
||||||
|
about: Template for Short Issues
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Current behaviour
|
||||||
|
Describe the current behaviour
|
||||||
|
|
||||||
|
### Expected behaviour
|
||||||
|
Describe how it is supposed to work
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.19",
|
"@fortawesome/react-fontawesome": "^0.1.19",
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.61",
|
|
||||||
"@monaco-editor/react": "^4.3.1",
|
"@monaco-editor/react": "^4.3.1",
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
"@testing-library/jest-dom": "^5.16.1",
|
||||||
"@testing-library/react": "^12.1.2",
|
"@testing-library/react": "^12.1.2",
|
||||||
@@ -42,7 +41,6 @@
|
|||||||
"reactour": "^1.18.7",
|
"reactour": "^1.18.7",
|
||||||
"redux": "^4.2.0",
|
"redux": "^4.2.0",
|
||||||
"redux-thunk": "^2.4.1",
|
"redux-thunk": "^2.4.1",
|
||||||
"rehype-raw": "^6.1.1",
|
|
||||||
"remark-gemoji": "^7.0.1",
|
"remark-gemoji": "^7.0.1",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
|
|||||||
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 777 KiB |
|
After Width: | Height: | Size: 728 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 79 KiB |
@@ -62,13 +62,3 @@ td {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
--url: url('./data/mcu_opacity.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklySvg {
|
|
||||||
background-image: var(--url);
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
BOARD,
|
BOARD,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import mini_opacity from "../data/mini_opacity.png"
|
|
||||||
import mcu_opacity from "../data/mcu_opacity.png"
|
|
||||||
|
|
||||||
export const setBoard = (board) => (dispatch) => {
|
export const setBoard = (board) => (dispatch) => {
|
||||||
window.sessionStorage.setItem("board", board);
|
|
||||||
const root = document.querySelector(':root');
|
|
||||||
root.style.setProperty('--url', `url(${board === "mcu" ? mcu_opacity : mini_opacity})`);
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: BOARD,
|
type: BOARD,
|
||||||
payload: board,
|
payload: board,
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
const fetchSensorWikiSuccess = sensors => ({
|
|
||||||
type: 'FETCH_SENSORWIKI_SUCCESS',
|
|
||||||
payload: { sensors }
|
|
||||||
})
|
|
||||||
|
|
||||||
export const fetchSensors = () => {
|
|
||||||
return async dispatch => {
|
|
||||||
try {
|
|
||||||
let sensors = await axios.get('https://api.sensors.wiki/sensors/all')
|
|
||||||
dispatch(fetchSensorWikiSuccess(sensors.data))
|
|
||||||
}
|
|
||||||
catch(e){
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -301,21 +301,12 @@ export const resetTutorial = () => (dispatch, getState) => {
|
|||||||
hardware: [],
|
hardware: [],
|
||||||
requirements: [],
|
requirements: [],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
type: "finalpage",
|
|
||||||
headline: "",
|
|
||||||
text: "",
|
|
||||||
samplesolutions: false,
|
|
||||||
solutions: [],
|
|
||||||
furthertutorials: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
dispatch(tutorialSteps(steps));
|
dispatch(tutorialSteps(steps));
|
||||||
dispatch({
|
dispatch({
|
||||||
type: BUILDER_ERROR,
|
type: BUILDER_ERROR,
|
||||||
payload: {
|
payload: {
|
||||||
steps: [{}, {}],
|
steps: [{}],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,15 +20,9 @@ export const onChangeCode = () => (dispatch, getState) => {
|
|||||||
if (selectedBlock !== null) {
|
if (selectedBlock !== null) {
|
||||||
code.helpurl = selectedBlock.helpUrl
|
code.helpurl = selectedBlock.helpUrl
|
||||||
code.tooltip = selectedBlock.tooltip
|
code.tooltip = selectedBlock.tooltip
|
||||||
if (selectedBlock.data) {
|
|
||||||
code.data = selectedBlock.data
|
|
||||||
} else {
|
|
||||||
code.data = null
|
|
||||||
}
|
|
||||||
} else if (selectedBlock === null) {
|
} else if (selectedBlock === null) {
|
||||||
code.tooltip = Blockly.Msg.tooltip_hint
|
code.tooltip = Blockly.Msg.tooltip_hint
|
||||||
code.helpurl = ''
|
code.helpurl = ''
|
||||||
code.data = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import "./sensebox-motors";
|
|||||||
import "./sensebox-lora";
|
import "./sensebox-lora";
|
||||||
import "./sensebox-led";
|
import "./sensebox-led";
|
||||||
import "./sensebox-rtc";
|
import "./sensebox-rtc";
|
||||||
|
import "./sensebox-ntp";
|
||||||
import "./sensebox-ble";
|
import "./sensebox-ble";
|
||||||
import "./sensebox-sd";
|
import "./sensebox-sd";
|
||||||
import "./mqtt";
|
import "./mqtt";
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import * as Blockly from "blockly";
|
||||||
|
import { getColour } from "../helpers/colour";
|
||||||
|
import * as Types from "../helpers/types";
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_ntp_init"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_ntp_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput().appendField(Blockly.Msg.sensebox_ntp_init);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_ntp_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_ntp_get"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_ntp_get_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.sensebox_ntp_get)
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldDropdown([
|
||||||
|
[Blockly.Msg.sensebox_ntp_epochTime, "getEpochTime"],
|
||||||
|
[Blockly.Msg.sensebox_ntp_formattedTimeStamp, "getFormattedTime"],
|
||||||
|
]),
|
||||||
|
"dropdown"
|
||||||
|
);
|
||||||
|
this.setOutput(true, Types.LARGE_NUMBER.typeName);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_rtc_get_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_ntp_get_timestamp"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_get_timestamp);
|
||||||
|
this.setOutput(true);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -19,6 +19,7 @@ Blockly.Blocks["sensebox_osem_connection"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.appendDummyInput()
|
this.appendDummyInput()
|
||||||
.appendField(Blockly.Msg.senseBox_osem_connection)
|
.appendField(Blockly.Msg.senseBox_osem_connection)
|
||||||
|
.appendField( new Blockly.FieldDropdown([[Blockly.Msg.senseBox_osem_host, "opensensemap.org"], [Blockly.Msg.senseBox_osem_host_testing, "testing.opensensemap.org"]]), "HOST")
|
||||||
.appendField("SSL")
|
.appendField("SSL")
|
||||||
.appendField(new Blockly.FieldCheckbox(ssl), "SSL");
|
.appendField(new Blockly.FieldCheckbox(ssl), "SSL");
|
||||||
this.appendDummyInput()
|
this.appendDummyInput()
|
||||||
@@ -53,6 +54,10 @@ Blockly.Blocks["sensebox_osem_connection"] = {
|
|||||||
.setAlign(Blockly.ALIGN_LEFT)
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
.appendField(Blockly.Msg.senseBox_osem_access_token)
|
.appendField(Blockly.Msg.senseBox_osem_access_token)
|
||||||
.appendField(new Blockly.FieldTextInput("access_token"), "access_token");
|
.appendField(new Blockly.FieldTextInput("access_token"), "access_token");
|
||||||
|
this.appendDummyInput()
|
||||||
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
|
.appendField(Blockly.Msg.senseBox_osem_xallowtoken)
|
||||||
|
.appendField(new Blockly.FieldTextInput("ratelimit-token"), "ratelimit-token");
|
||||||
this.appendStatementInput("DO")
|
this.appendStatementInput("DO")
|
||||||
.appendField(Blockly.Msg.senseBox_sensor)
|
.appendField(Blockly.Msg.senseBox_sensor)
|
||||||
.setCheck(null);
|
.setCheck(null);
|
||||||
|
|||||||
@@ -76,3 +76,67 @@ Blockly.Blocks["sensebox_rtc_get_timestamp"] = {
|
|||||||
this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip);
|
this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal RTC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_internal_rtc_init"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_internal_rtc_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput().appendField(Blockly.Msg.sensebox_internal_rtc_init);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_internal_rtc_init_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_internal_rtc_set"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendValueInput("time").appendField(
|
||||||
|
Blockly.Msg.sensebox_internal_rtc_set
|
||||||
|
);
|
||||||
|
this.setPreviousStatement(true);
|
||||||
|
this.setNextStatement(true);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_internal_rtc_set_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_internal_rtc_get"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(Blockly.Msg.sensebox_internal_rtc_get)
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldDropdown([
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_epoch, "Epoch"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_year, "Year"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_month, "Month"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_day, "Day"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_hour, "Hours"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_minutes, "Minutes"],
|
||||||
|
[Blockly.Msg.sensebox_internal_rtc_seconds, "Seconds"],
|
||||||
|
]),
|
||||||
|
"dropdown"
|
||||||
|
);
|
||||||
|
this.setOutput(true, Types.LARGE_NUMBER.typeName);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_internal_rtc_get_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_internal_rtc_get_timestamp"] = {
|
||||||
|
init: function () {
|
||||||
|
this.setHelpUrl(Blockly.Msg.sensebox_internal_rtc_helpurl);
|
||||||
|
this.setColour(getColour().time);
|
||||||
|
this.appendDummyInput().appendField(
|
||||||
|
Blockly.Msg.sensebox_internal_rtc_get_timestamp
|
||||||
|
);
|
||||||
|
this.setOutput(true);
|
||||||
|
this.setTooltip(Blockly.Msg.sensebox_internal_rtc_get_timestamp_tooltip);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ Blockly.Blocks["sensebox_sensor_temp_hum"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_temp_hum_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_temp_hum_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_temp_hum_helpurl);
|
||||||
this.data = {name: "hdc1080", connection: "I2C"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,7 +51,6 @@ Blockly.Blocks["sensebox_sensor_uv_light"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_uv_light_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_uv_light_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_uv_light_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_uv_light_helpurl);
|
||||||
this.data = {name: "veml6070"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,7 +91,6 @@ Blockly.Blocks["sensebox_sensor_bmx055_accelerometer"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_bmx055_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_bmx055_helpurl);
|
||||||
this.data = {name: "bmx055"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,14 +115,13 @@ Blockly.Blocks["sensebox_sensor_sds011"] = {
|
|||||||
.appendField(Blockly.Msg.senseBox_sds011_dimension)
|
.appendField(Blockly.Msg.senseBox_sds011_dimension)
|
||||||
.appendField(
|
.appendField(
|
||||||
new Blockly.FieldDropdown(
|
new Blockly.FieldDropdown(
|
||||||
selectedBoard().serial),
|
selectedBoard().serialSensors),
|
||||||
"SERIAL"
|
"SERIAL"
|
||||||
);
|
);
|
||||||
this.setOutput(true, Types.DECIMAL.typeName);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_sds011_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_sds011_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_sds011_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_sds011_helpurl);
|
||||||
this.data = {name: "sds011"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,7 +155,6 @@ Blockly.Blocks["sensebox_sensor_pressure"] = {
|
|||||||
this.setOutput(true, Types.DECIMAL.typeName);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_pressure_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_pressure_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_pressure_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_pressure_helpurl);
|
||||||
this.data = {name: "bmp280"};
|
|
||||||
this.getField("NAME").setValidator(
|
this.getField("NAME").setValidator(
|
||||||
function (val) {
|
function (val) {
|
||||||
this.updateShape_(val === "Altitude");
|
this.updateShape_(val === "Altitude");
|
||||||
@@ -191,7 +186,7 @@ Blockly.Blocks["sensebox_sensor_bme680_bsec"] = {
|
|||||||
var dropdownOptions = [
|
var dropdownOptions = [
|
||||||
[Blockly.Msg.senseBox_temp, "temperature"],
|
[Blockly.Msg.senseBox_temp, "temperature"],
|
||||||
[Blockly.Msg.senseBox_hum, "humidity"],
|
[Blockly.Msg.senseBox_hum, "humidity"],
|
||||||
[Blockly.Msg.senseBox_pressure, "pressure"],
|
[Blockly.Msg.senseBox_bme_pressure, "pressure"],
|
||||||
[Blockly.Msg.senseBox_bme_iaq, "IAQ"],
|
[Blockly.Msg.senseBox_bme_iaq, "IAQ"],
|
||||||
[Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"],
|
[Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"],
|
||||||
[Blockly.Msg.senseBox_bme_co2, "CO2"],
|
[Blockly.Msg.senseBox_bme_co2, "CO2"],
|
||||||
@@ -206,7 +201,6 @@ Blockly.Blocks["sensebox_sensor_bme680_bsec"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_bme_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_bme_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_bme680_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_bme680_helpurl);
|
||||||
this.data = {name: "bme680"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -251,7 +245,6 @@ Blockly.Blocks["sensebox_sensor_ultrasonic_ranger"] = {
|
|||||||
this.setOutput(true, Types.NUMBER.typeName);
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_ultrasonic_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_ultrasonic_helpurl);
|
||||||
this.data = {name: "hc-sr04"};
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Parse XML to restore the number of pins available.
|
* Parse XML to restore the number of pins available.
|
||||||
@@ -389,7 +382,6 @@ Blockly.Blocks["sensebox_scd30"] = {
|
|||||||
this.setColour(getColour().sensebox);
|
this.setColour(getColour().sensebox);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_scd_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_scd_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_scd_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_scd_helpurl);
|
||||||
this.data = {name: "scd30"};
|
|
||||||
},
|
},
|
||||||
onchange: function (e) {
|
onchange: function (e) {
|
||||||
var dropdown = this.getFieldValue("dropdown");
|
var dropdown = this.getFieldValue("dropdown");
|
||||||
@@ -456,7 +448,6 @@ Blockly.Blocks["sensebox_sensor_truebner_smt50"] = {
|
|||||||
this.setOutput(true, Types.NUMBER.typeName);
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_smt50_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_smt50_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_smt50_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_smt50_helpurl);
|
||||||
this.data = {name: "smt50"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -479,7 +470,6 @@ Blockly.Blocks["sensebox_sensor_watertemperature"] = {
|
|||||||
.appendField(new Blockly.FieldDropdown(dropdownOptions), "Port");
|
.appendField(new Blockly.FieldDropdown(dropdownOptions), "Port");
|
||||||
this.setOutput(true, Types.NUMBER.typeName);
|
this.setOutput(true, Types.NUMBER.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_watertemperature_tip);
|
this.setTooltip(Blockly.Msg.senseBox_watertemperature_tip);
|
||||||
this.data = {name: "ds18b20"};
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -552,7 +542,6 @@ Blockly.Blocks["sensebox_sensor_dps310"] = {
|
|||||||
this.setOutput(true, Types.DECIMAL.typeName);
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
this.setTooltip(Blockly.Msg.senseBox_sensor_dps310_tooltip);
|
this.setTooltip(Blockly.Msg.senseBox_sensor_dps310_tooltip);
|
||||||
this.setHelpUrl(Blockly.Msg.senseBox_sensor_dps310_helpurl);
|
this.setHelpUrl(Blockly.Msg.senseBox_sensor_dps310_helpurl);
|
||||||
this.data = {name: "dps310"};
|
|
||||||
this.getField("NAME").setValidator(
|
this.getField("NAME").setValidator(
|
||||||
function (val) {
|
function (val) {
|
||||||
this.updateShape_(val === "Altitude");
|
this.updateShape_(val === "Altitude");
|
||||||
@@ -573,3 +562,31 @@ Blockly.Blocks["sensebox_sensor_dps310"] = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sensirion SPS30 Fine Particular Matter Sensor
|
||||||
|
* added 02.12.2022
|
||||||
|
*/
|
||||||
|
|
||||||
|
Blockly.Blocks["sensebox_sensor_sps30"] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput().appendField(Blockly.Msg.senseBox_sps30);
|
||||||
|
this.appendDummyInput()
|
||||||
|
.setAlign(Blockly.ALIGN_LEFT)
|
||||||
|
.appendField(Blockly.Msg.senseBox_value)
|
||||||
|
.appendField(
|
||||||
|
new Blockly.FieldDropdown([
|
||||||
|
[Blockly.Msg.senseBox_sps30_1p0, "1p0"],
|
||||||
|
[Blockly.Msg.senseBox_sps30_2p5, "2p5"],
|
||||||
|
[Blockly.Msg.senseBox_sps30_4p0, "4p0"],
|
||||||
|
[Blockly.Msg.senseBox_sps30_10p0, "10p0"],
|
||||||
|
]),
|
||||||
|
"value"
|
||||||
|
)
|
||||||
|
.appendField(Blockly.Msg.senseBox_sps30_dimension);
|
||||||
|
this.setOutput(true, Types.DECIMAL.typeName);
|
||||||
|
this.setColour(getColour().sensebox);
|
||||||
|
this.setTooltip(Blockly.Msg.senseBox_sps30_tooltip);
|
||||||
|
this.setHelpUrl(Blockly.Msg.senseBox_sps30_helpurl);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -9,10 +9,10 @@ Blockly.Blocks["variables_set_dynamic"] = {
|
|||||||
this.setPreviousStatement(true, null);
|
this.setPreviousStatement(true, null);
|
||||||
this.setNextStatement(true, null);
|
this.setNextStatement(true, null);
|
||||||
this.appendValueInput("VALUE")
|
this.appendValueInput("VALUE")
|
||||||
.appendField(Blockly.Msg.variables_set, Blockly.Msg.variables_set)
|
.appendField("set", "set")
|
||||||
// .appendField("", "type")
|
.appendField("", "type")
|
||||||
.appendField(new Blockly.FieldVariable("VAR"), "VAR")
|
.appendField(new Blockly.FieldVariable("VAR"), "VAR")
|
||||||
.appendField(Blockly.Msg.variables_to);
|
.appendField("to");
|
||||||
},
|
},
|
||||||
onchange: function (e) {
|
onchange: function (e) {
|
||||||
let variableID = this.getFieldValue("VAR");
|
let variableID = this.getFieldValue("VAR");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import "./sensebox-lora";
|
|||||||
import "./sensebox-led";
|
import "./sensebox-led";
|
||||||
import "./sensebox";
|
import "./sensebox";
|
||||||
import "./sensebox-rtc";
|
import "./sensebox-rtc";
|
||||||
|
import "./sensebox-ntp";
|
||||||
import "./sensebox-ble";
|
import "./sensebox-ble";
|
||||||
import "./sensebox-sd";
|
import "./sensebox-sd";
|
||||||
import "./mqtt";
|
import "./mqtt";
|
||||||
|
|||||||
@@ -275,10 +275,15 @@ Blockly.Arduino["math_change"] = function (block) {
|
|||||||
"DELTA",
|
"DELTA",
|
||||||
Blockly.Arduino.ORDER_ADDITIVE
|
Blockly.Arduino.ORDER_ADDITIVE
|
||||||
) || "0";
|
) || "0";
|
||||||
var varName = Blockly.Arduino.nameDB_.getName(
|
var id = block.getFieldValue("VAR")
|
||||||
block.getFieldValue("VAR"),
|
const varName = Blockly.Variables.getVariable(
|
||||||
Blockly.Variables.NAME_TYPE
|
Blockly.getMainWorkspace(),
|
||||||
);
|
id
|
||||||
|
).name;
|
||||||
|
// var varName = Blockly.Arduino.nameDB_.getName(
|
||||||
|
// block.getFieldValue("VAR"),
|
||||||
|
// Blockly.Variables.NAME_TYPE
|
||||||
|
// );
|
||||||
return varName + " += " + argument0 + ";\n";
|
return varName + " += " + argument0 + ";\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import Blockly from "blockly";
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_ntp_init = function () {
|
||||||
|
Blockly.Arduino.libraries_["WiFiUdp"] = `#include <WiFiUdp.h>`;
|
||||||
|
Blockly.Arduino.libraries_["NTPClient"] = `#include <NTPClient.h>`;
|
||||||
|
Blockly.Arduino.definitions_["WiFiUDP"] = `WiFiUDP ntpUDP;`;
|
||||||
|
Blockly.Arduino.definitions_["NTPClient"] = `NTPClient timeClient(ntpUDP);`;
|
||||||
|
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||||
|
Blockly.Arduino.setupCode_["timeclient.begin"] = `timeClient.begin();`;
|
||||||
|
Blockly.Arduino.setupCode_["timeclient.update"] = `timeClient.update();`;
|
||||||
|
var code = ``;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_ntp_get = function () {
|
||||||
|
var format = this.getFieldValue("dropdown");
|
||||||
|
var code = `timeClient.${format}()`;
|
||||||
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
@@ -30,6 +30,8 @@ Blockly.Arduino.sensebox_osem_connection = function (Block) {
|
|||||||
var box_id = this.getFieldValue("BoxID");
|
var box_id = this.getFieldValue("BoxID");
|
||||||
var branch = Blockly.Arduino.statementToCode(Block, "DO");
|
var branch = Blockly.Arduino.statementToCode(Block, "DO");
|
||||||
var access_token = this.getFieldValue("access_token");
|
var access_token = this.getFieldValue("access_token");
|
||||||
|
var host = this.getFieldValue("HOST");
|
||||||
|
var ratelimit_token = this.getFieldValue("ratelimit-token");
|
||||||
var blocks = this.getDescendants();
|
var blocks = this.getDescendants();
|
||||||
var type = this.getFieldValue("type");
|
var type = this.getFieldValue("type");
|
||||||
var ssl = this.getFieldValue("SSL");
|
var ssl = this.getFieldValue("SSL");
|
||||||
@@ -50,7 +52,7 @@ Blockly.Arduino.sensebox_osem_connection = function (Block) {
|
|||||||
Blockly.Arduino.definitions_["SenseBoxID"] =
|
Blockly.Arduino.definitions_["SenseBoxID"] =
|
||||||
'const char SENSEBOX_ID [] PROGMEM = "' + box_id + '";';
|
'const char SENSEBOX_ID [] PROGMEM = "' + box_id + '";';
|
||||||
Blockly.Arduino.definitions_["host"] =
|
Blockly.Arduino.definitions_["host"] =
|
||||||
'const char server [] PROGMEM ="ingress.opensensemap.org";';
|
`const char server [] PROGMEM ="ingress.${host}";`;
|
||||||
if (wifi === true) {
|
if (wifi === true) {
|
||||||
if (ssl === "TRUE") {
|
if (ssl === "TRUE") {
|
||||||
Blockly.Arduino.libraries_["library_bearSSL"] =
|
Blockly.Arduino.libraries_["library_bearSSL"] =
|
||||||
@@ -154,7 +156,7 @@ ${
|
|||||||
if (connected == true) {
|
if (connected == true) {
|
||||||
// construct the HTTP POST request:
|
// construct the HTTP POST request:
|
||||||
sprintf_P(buffer,
|
sprintf_P(buffer,
|
||||||
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nHost: %s\\nContent-Type: "
|
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nX-Allow-Token: ${ratelimit_token}\\nHost: %s\\nContent-Type: "
|
||||||
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
|
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
|
||||||
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
|
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
|
||||||
// send the HTTP POST request:
|
// send the HTTP POST request:
|
||||||
@@ -253,7 +255,7 @@ ${
|
|||||||
if (connected == true) {
|
if (connected == true) {
|
||||||
// construct the HTTP POST request:
|
// construct the HTTP POST request:
|
||||||
sprintf_P(buffer,
|
sprintf_P(buffer,
|
||||||
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nHost: %s\\nContent-Type: "
|
PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_token}\\nX-Allow-Token: ${ratelimit_token}\\nHost: %s\\nContent-Type: "
|
||||||
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
|
"text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"),
|
||||||
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
|
SENSEBOX_ID, server, num_measurements * lengthMultiplikator);
|
||||||
// send the HTTP POST request:
|
// send the HTTP POST request:
|
||||||
|
|||||||
@@ -94,3 +94,46 @@ uint8_t sec, min, hour, day, month;
|
|||||||
var code = `getTimeStamp()`;
|
var code = `getTimeStamp()`;
|
||||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_internal_rtc_init = function () {
|
||||||
|
Blockly.Arduino.libraries_["RTClib"] = `#include <RTCZero.h>`;
|
||||||
|
Blockly.Arduino.definitions_["RTC"] = `RTCZero rtc;`;
|
||||||
|
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||||
|
Blockly.Arduino.setupCode_["rtc.begin"] = `rtc.begin();`;
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_internal_rtc_set = function () {
|
||||||
|
var branch =
|
||||||
|
Blockly.Arduino.valueToCode(this, "time", Blockly.Arduino.ORDER_ATOMIC) ||
|
||||||
|
"0";
|
||||||
|
Blockly.Arduino.setupCode_["rtc.setEpoch"] = `rtc.setEpoch(${branch});`;
|
||||||
|
var code = ``;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_internal_rtc_get = function () {
|
||||||
|
var dropdown = this.getFieldValue("dropdown");
|
||||||
|
var code = `rtc.get${dropdown}()`;
|
||||||
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_internal_rtc_get_timestamp = function () {
|
||||||
|
Blockly.Arduino.variables_["rtc_timestamp"] = `char timestamp[20];`;
|
||||||
|
Blockly.Arduino.codeFunctions_["getTimeStamp"] = `
|
||||||
|
char* getTimeStamp() {
|
||||||
|
uint8_t sec, min, hour, day, month;
|
||||||
|
uint16_t year;
|
||||||
|
sec = rtc.getSeconds();
|
||||||
|
min = rtc.getMinutes();
|
||||||
|
hour = rtc.getHours();
|
||||||
|
day = rtc.getDay();
|
||||||
|
month = rtc.getMonth();
|
||||||
|
year = rtc.getYear();
|
||||||
|
sprintf(timestamp, "%02d-%02d-%02dT%02d:%02d:%02dZ", year, month, day, hour, min, sec);
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
var code = `getTimeStamp()`;
|
||||||
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|||||||
@@ -434,6 +434,8 @@ Blockly.Arduino.sensebox_scd30 = function () {
|
|||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}`;
|
}`;
|
||||||
|
Blockly.Arduino.setupCode_["scd30_staleData"] =
|
||||||
|
"airSensor.useStaleData(true);";
|
||||||
var code = "";
|
var code = "";
|
||||||
switch (dropdown) {
|
switch (dropdown) {
|
||||||
case "temperature":
|
case "temperature":
|
||||||
@@ -692,3 +694,57 @@ Blockly.Arduino.sensebox_sensor_dps310 = function () {
|
|||||||
}
|
}
|
||||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sensirion SPS30 Fine Particlar Matter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Blockly.Arduino.sensebox_sensor_sps30 = function () {
|
||||||
|
var dropdown_name = this.getFieldValue("value");
|
||||||
|
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||||
|
Blockly.Arduino.libraries_[
|
||||||
|
"sps30"
|
||||||
|
] = `#include <sps30.h> // http://librarymanager/All#`;
|
||||||
|
Blockly.Arduino.variables_["sps30_measurement"] =
|
||||||
|
"struct sps30_measurement m;";
|
||||||
|
Blockly.Arduino.variables_["sps30_auto_clean_days"] =
|
||||||
|
"uint32_t auto_clean_days = 4;";
|
||||||
|
Blockly.Arduino.variables_["sps30_interval_intervalsps"] =
|
||||||
|
"const long intervalsps = 1000;";
|
||||||
|
Blockly.Arduino.variables_["sps30_time_startsps"] =
|
||||||
|
"unsigned long time_startsps = 0;";
|
||||||
|
Blockly.Arduino.variables_["sps30_time_actualsps"] =
|
||||||
|
"unsigned long time_actualsps = 0;";
|
||||||
|
Blockly.Arduino.codeFunctions_["sps30_getData"] = `
|
||||||
|
void getSPS30Data(){
|
||||||
|
|
||||||
|
uint16_t data_ready;
|
||||||
|
int16_t ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = sps30_read_data_ready(&data_ready);
|
||||||
|
if (ret < 0) {
|
||||||
|
} else if (!data_ready) {}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
delay(100); /* retry in 100ms */
|
||||||
|
} while (1);
|
||||||
|
ret = sps30_read_measurement(&m);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
Blockly.Arduino.setupCode_["sps30_begin"] = "sensirion_i2c_init();";
|
||||||
|
Blockly.Arduino.setupCode_["sps30_setFanCleaningInterval"] =
|
||||||
|
"sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);";
|
||||||
|
Blockly.Arduino.setupCode_["sps30_startMeasurement"] =
|
||||||
|
"sps30_start_measurement();";
|
||||||
|
Blockly.Arduino.loopCodeOnce_["getSPS30Data();"] = `
|
||||||
|
time_startsps = millis();
|
||||||
|
if (time_startsps > time_actualsps + intervalsps) {
|
||||||
|
time_actualsps = millis();
|
||||||
|
getSPS30Data();
|
||||||
|
}`;
|
||||||
|
var code = `m.mc_${dropdown_name}`;
|
||||||
|
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|||||||
@@ -46,9 +46,13 @@ const sensebox_mcu = {
|
|||||||
["C6", "6"],
|
["C6", "6"],
|
||||||
],
|
],
|
||||||
serial: [
|
serial: [
|
||||||
["serial", "SerialUSB"],
|
["SerialUSB", "SerialUSB"],
|
||||||
["serial_1", "Serial1"],
|
["Serial1", "Serial1"],
|
||||||
["serial_2", "Serial2"],
|
["Serial2", "Serial2"],
|
||||||
|
],
|
||||||
|
serialSensors: [
|
||||||
|
["Serial1", "Serial1"],
|
||||||
|
["Serial2", "Serial2"],
|
||||||
],
|
],
|
||||||
serialPins: {
|
serialPins: {
|
||||||
SerialUSB: [
|
SerialUSB: [
|
||||||
@@ -161,8 +165,11 @@ const sensebox_mini = {
|
|||||||
["IO2", "2"],
|
["IO2", "2"],
|
||||||
],
|
],
|
||||||
serial: [
|
serial: [
|
||||||
["serial", "SerialUSB"],
|
["SerialUSB", "SerialUSB"],
|
||||||
["serial_1", "Serial1"],
|
["Serial1", "Serial1"],
|
||||||
|
],
|
||||||
|
serialSensors: [
|
||||||
|
["Serial1", "Serial1"],
|
||||||
],
|
],
|
||||||
serialPins: {
|
serialPins: {
|
||||||
SerialUSB: [
|
SerialUSB: [
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
* @author samelh@google.com (Sam El-Husseini)
|
* @author samelh@google.com (Sam El-Husseini)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import BlocklyComponent from './BlocklyComponent';
|
import BlocklyComponent from "./BlocklyComponent";
|
||||||
|
|
||||||
export default BlocklyComponent;
|
export default BlocklyComponent;
|
||||||
|
|
||||||
@@ -56,4 +56,16 @@ const Shadow = (p) => {
|
|||||||
return React.createElement("shadow", props, children);
|
return React.createElement("shadow", props, children);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { Block, Category, Value, Field, Shadow }
|
const Sep = (p) => {
|
||||||
|
const { children, ...props } = p;
|
||||||
|
props.is = "blockly";
|
||||||
|
return React.createElement("sep", props, children);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Label = (p) => {
|
||||||
|
const { children, ...props } = p;
|
||||||
|
props.is = "blockly";
|
||||||
|
return React.createElement("label", props, children);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Block, Category, Value, Field, Shadow, Sep, Label };
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { LED } from "./de/sensebox-led";
|
|||||||
import { LORA } from "./de/sensebox-lora";
|
import { LORA } from "./de/sensebox-lora";
|
||||||
import { OSEM } from "./de/sensebox-osem";
|
import { OSEM } from "./de/sensebox-osem";
|
||||||
import { RTC } from "./de/sensebox-rtc";
|
import { RTC } from "./de/sensebox-rtc";
|
||||||
|
import { NTP } from "./de/sensebox-ntp";
|
||||||
import { SD } from "./de/sensebox-sd";
|
import { SD } from "./de/sensebox-sd";
|
||||||
import { SENSORS } from "./de/sensebox-sensors";
|
import { SENSORS } from "./de/sensebox-sensors";
|
||||||
import { SENSEBOX } from "./de/sensebox";
|
import { SENSEBOX } from "./de/sensebox";
|
||||||
@@ -40,6 +41,7 @@ export const De = {
|
|||||||
...LORA,
|
...LORA,
|
||||||
...OSEM,
|
...OSEM,
|
||||||
...RTC,
|
...RTC,
|
||||||
|
...NTP,
|
||||||
...SD,
|
...SD,
|
||||||
...SENSORS,
|
...SENSORS,
|
||||||
...SENSEBOX,
|
...SENSEBOX,
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export const NTP = {
|
||||||
|
sensebox_ntp_init: "Initialisiere NTP",
|
||||||
|
sensebox_ntp_init_tooltip: "Initialisiere den NTP Server.",
|
||||||
|
sensebox_ntp_get: "Hole Zeit von NTP Server: ",
|
||||||
|
sensebox_ntp_get_timestamp_tooltip:
|
||||||
|
"Gibt dir einen in ISO 8601 formatierten Zeitstempel zurück. Bsp: 2021-12-24T18:21Z",
|
||||||
|
sensebox_ntp_get_tooltip:
|
||||||
|
"Gibt dir den ausgewählten Wert zurück. Unix Zeit entspricht der Anzahl der Sekunden seit dem 1.1.1970",
|
||||||
|
sensebox_ntp_epochTime: "Unix Zeit",
|
||||||
|
sensebox_ntp_formattedTimeStamp: "Zeitstempel (hh:mm:ss)",
|
||||||
|
};
|
||||||
@@ -10,11 +10,12 @@ export const OSEM = {
|
|||||||
senseBox_send_to_osem: "Sende Messwert an die openSenseMap",
|
senseBox_send_to_osem: "Sende Messwert an die openSenseMap",
|
||||||
senseBox_osem_connection: "Verbinde mit openSenseMap:",
|
senseBox_osem_connection: "Verbinde mit openSenseMap:",
|
||||||
senseBox_osem_host: "opensensemap.org",
|
senseBox_osem_host: "opensensemap.org",
|
||||||
senseBox_osem_host_workshop: "workshop.opensensemap.org",
|
senseBox_osem_host_testing: "testing.opensensemap.org",
|
||||||
senseBox_osem_exposure: "Typ",
|
senseBox_osem_exposure: "Typ",
|
||||||
senseBox_osem_stationary: "Stationär",
|
senseBox_osem_stationary: "Stationär",
|
||||||
senseBox_osem_mobile: "Mobil",
|
senseBox_osem_mobile: "Mobil",
|
||||||
senseBox_osem_access_token: "API Schlüssel",
|
senseBox_osem_access_token: "API Schlüssel",
|
||||||
|
senseBox_osem_xallowtoken: "X-ALLOW-TOKEN",
|
||||||
senseBox_send_mobile_to_osem:
|
senseBox_send_mobile_to_osem:
|
||||||
"Sende Messwert und Standort an die openSenseMap",
|
"Sende Messwert und Standort an die openSenseMap",
|
||||||
senseBox_send_mobile_to_osem_tip:
|
senseBox_send_mobile_to_osem_tip:
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
export const RTC = {
|
export const RTC = {
|
||||||
sensebox_rtc_init: "Initialisiere RTC",
|
sensebox_rtc_init: "Initialisiere externe RTC",
|
||||||
sensebox_rtc_init_tooltip:
|
sensebox_rtc_init_tooltip:
|
||||||
"Initialisiere die RTC. Schließe diese an einen der 5 I2C/Wire Anschlüsse an und lege die Batterie ein. Bevor du die Uhrzeit auslesen kannst muss diese zunächst einmal gesetzt werden. Dieser Schritt muss normalerweise nur einmalig durchgeführt werden.",
|
"Initialisiere die RTC. Schließe diese an einen der 5 I2C/Wire Anschlüsse an und lege die Batterie ein. Bevor du die Uhrzeit auslesen kannst muss diese zunächst einmal gesetzt werden. Dieser Schritt muss normalerweise nur einmalig durchgeführt werden.",
|
||||||
sensebox_rtc_set: "Setze Uhrzeit/Datum der RTC",
|
sensebox_rtc_set: "Setze Uhrzeit/Datum der externen RTC",
|
||||||
sensebox_rtc_set_tooltip:
|
sensebox_rtc_set_tooltip:
|
||||||
"Stellt die Uhrzeit der RTC ein. Beachte, dass du diesen Block im Setup ausführst.",
|
"Stellt die Uhrzeit der RTC ein. Beachte, dass du diesen Block im Setup ausführst.",
|
||||||
sensebox_rtc_get_timestamp: "Zeitstempel (RFC 3339)",
|
sensebox_rtc_get_timestamp: "Zeitstempel externe RTC (RFC 3339)",
|
||||||
sensebox_rtc_get_timestamp_tooltip:
|
sensebox_rtc_get_timestamp_tooltip:
|
||||||
"Gibt dir einen in ISO 8601 formatierten Zeitstempel zurück. Bsp: 2021-12-24T18:21Z",
|
"Gibt dir einen in ISO 8601 formatierten Zeitstempel zurück. Bsp: 2021-12-24T18:21Z",
|
||||||
sensebox_rtc_get: "Wert: ",
|
sensebox_rtc_get: "Wert (externe RTC): ",
|
||||||
sensebox_rtc_get_tooltip: "Gibt dir den ausgewählten Wert zurück.",
|
sensebox_rtc_get_tooltip: "Gibt dir den ausgewählten Wert zurück.",
|
||||||
sensebox_rtc_second: "Sekunden",
|
sensebox_rtc_second: "Sekunden",
|
||||||
sensebox_rtc_minutes: "Minuten",
|
sensebox_rtc_minutes: "Minuten",
|
||||||
@@ -16,4 +16,22 @@ export const RTC = {
|
|||||||
sensebox_rtc_day: "Tag",
|
sensebox_rtc_day: "Tag",
|
||||||
sensebox_rtc_month: "Monat",
|
sensebox_rtc_month: "Monat",
|
||||||
sensebox_rtc_year: "Jahr",
|
sensebox_rtc_year: "Jahr",
|
||||||
|
sensebox_internal_rtc_init: "Initialisiere interne RTC",
|
||||||
|
sensebox_internal_rtc_init_tooltip:
|
||||||
|
"Initialisieren der internen RTC. Diese RTC ist nicht batteriegepuffert und wird bei jedem Einschaltvorgang zurückgesetzt",
|
||||||
|
sensebox_internal_rtc_set: "Setze interne RTC Zeit/Datum (Unix Time)",
|
||||||
|
sensebox_internal_rtc_set_tooltip:
|
||||||
|
"Setzt die Zeit der internen RTC. Führe den Block einmalig im Setup aus und setzte die Uhrzeit über die Unix Zeit.",
|
||||||
|
sensebox_internal_rtc_get: "Wert (interne RTC): ",
|
||||||
|
sensebox_internal_rtc_get_timestamp: "Zeitstempel interne RTC (RFC 3339)",
|
||||||
|
sensebox_internal_rtc_get_timestamp_tooltip:
|
||||||
|
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||||
|
sensebox_internal_rtc_get_tooltip: "Gibt den ausgewählten Wert zurück",
|
||||||
|
sensebox_internal_rtc_epoch: "Unix Zeit",
|
||||||
|
sensebox_internal_rtc_year: "Jahr",
|
||||||
|
sensebox_internal_rtc_month: "Monat",
|
||||||
|
sensebox_internal_rtc_day: "Tag",
|
||||||
|
sensebox_internal_rtc_hour: "Stunde",
|
||||||
|
sensebox_internal_rtc_minutes: "Minute",
|
||||||
|
sensebox_internal_rtc_seconds: "Sekunde",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ Wenn die maximale Distanz überschritten wird, wird ein Wert von **O** ausgegebe
|
|||||||
senseBox_bme_iaq: "Innenraumluftqualität (IAQ)",
|
senseBox_bme_iaq: "Innenraumluftqualität (IAQ)",
|
||||||
senseBox_bme_iaq_accuracy: "Kalibrierungswert",
|
senseBox_bme_iaq_accuracy: "Kalibrierungswert",
|
||||||
senseBox_bme_co2: "CO2 Äquivalent",
|
senseBox_bme_co2: "CO2 Äquivalent",
|
||||||
|
senseBox_bme_pressure: "Luftdruck in Pa",
|
||||||
senseBox_bme_breatheVocEquivalent: "Atemluft VOC Äquivalent",
|
senseBox_bme_breatheVocEquivalent: "Atemluft VOC Äquivalent",
|
||||||
senseBox_bme_tooltip: `Schließe den Umweltsensor an einen der 5 **I2C-Anschlüsse** an. **Beachte:** Der Sensor benöigt eine gewisse Zeit zum kalibrieren.
|
senseBox_bme_tooltip: `Schließe den Umweltsensor an einen der 5 **I2C-Anschlüsse** an. **Beachte:** Der Sensor benöigt eine gewisse Zeit zum kalibrieren.
|
||||||
Den Status der Kalibrierung kann über den Kalibrierungswert abgelesen werden. Er ist entweder 0, 1, 2 oder 3 und sagt folgendes aus:
|
Den Status der Kalibrierung kann über den Kalibrierungswert abgelesen werden. Er ist entweder 0, 1, 2 oder 3 und sagt folgendes aus:
|
||||||
@@ -175,7 +176,7 @@ Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt ver
|
|||||||
* Feinstaubsensor (SDS011)
|
* Feinstaubsensor (SDS011)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
senseBox_sds011: "Feinstaubsensor",
|
senseBox_sds011: "Feinstaubsensor SDS011",
|
||||||
senseBox_sds011_dimension: "in µg/m³ an",
|
senseBox_sds011_dimension: "in µg/m³ an",
|
||||||
senseBox_sds011_pm25: "PM2.5",
|
senseBox_sds011_pm25: "PM2.5",
|
||||||
senseBox_sds011_pm10: "PM10",
|
senseBox_sds011_pm10: "PM10",
|
||||||
@@ -200,4 +201,23 @@ Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt ver
|
|||||||
- "wurde gedrückt": Mit diesem Modus kannst du abfragen ob der Block gedrückt wurde. Erst wenn der Knopf gedrückt und wieder losgelassen wurde erhältst du TRUE zurück
|
- "wurde gedrückt": Mit diesem Modus kannst du abfragen ob der Block gedrückt wurde. Erst wenn der Knopf gedrückt und wieder losgelassen wurde erhältst du TRUE zurück
|
||||||
- "als Schalter": Wenn du diesen Block verwendest kannst du den Knopf wie ein Lichtschalter verwenden. Der Status wird gespeichert bis der Button erneut gedrückt wird`,
|
- "als Schalter": Wenn du diesen Block verwendest kannst du den Knopf wie ein Lichtschalter verwenden. Der Status wird gespeichert bis der Button erneut gedrückt wird`,
|
||||||
senseBox_button_helpurl: "",
|
senseBox_button_helpurl: "",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feinstaubsensor Sensirion SPS30
|
||||||
|
*/
|
||||||
|
|
||||||
|
senseBox_sps30: "Feinstaubsensor Sensirion SPS30",
|
||||||
|
senseBox_sps30_dimension: "in µg/m³",
|
||||||
|
senseBox_sps30_1p0: "PM1.0",
|
||||||
|
senseBox_sps30_2p5: "PM2.5",
|
||||||
|
senseBox_sps30_4p0: "PM4.0",
|
||||||
|
senseBox_sps30_10p0: "PM10",
|
||||||
|
senseBox_sps30_tooltip:"Dieser Block gibt dir den Messwert des Sensirion SPS30 Feinstaubsensor. Schließe den Feinstaubsensor an einen der 5 **I2C** Anschlüssen an. Im Dropdown Menü zwischen PM1.0, PM2.5, PM4.0 und PM10 auswählen. Der Messwert wird dir als **Kommazahl** in µg/m3",
|
||||||
|
senseBox_sps30_helpurl:
|
||||||
|
"https://docs.sensebox.de/hardware/sensoren-feinstaub/",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -8,23 +8,25 @@ export const UI = {
|
|||||||
toolbox_math: "Mathematik",
|
toolbox_math: "Mathematik",
|
||||||
toolbox_io: "Eingang/Ausgang",
|
toolbox_io: "Eingang/Ausgang",
|
||||||
toolbox_time: "Zeit",
|
toolbox_time: "Zeit",
|
||||||
|
toolbox_rtc: "RTC",
|
||||||
|
toolbox_ntp: "NTP",
|
||||||
toolbox_functions: "Funktionen",
|
toolbox_functions: "Funktionen",
|
||||||
toolbox_variables: "Variablen",
|
toolbox_variables: "Variablen",
|
||||||
toolbox_serial: "Seriell",
|
toolbox_serial: "Seriell",
|
||||||
toolbox_advanced: "Erweitert",
|
toolbox_advanced: "Erweitert",
|
||||||
toolbox_motors: "Motoren",
|
toolbox_motors: "Motoren",
|
||||||
|
toolbox_label_externalRTC: "Externe RTC",
|
||||||
|
toolbox_label_internalRTC: "Interne RTC",
|
||||||
variable_NUMBER: "Zahl (int)",
|
variable_NUMBER: "Zahl (int)",
|
||||||
variable_SHORT_NUMBER: "char",
|
variable_SHORT_NUMBER: "char",
|
||||||
variable_LONG: "große Zahl (long)",
|
variable_LONG: "große Zahl (long)",
|
||||||
variable_DECIMAL: "Kommazahl (float)",
|
variable_DECIMAL: "Kommazahl (float)",
|
||||||
variables_TEXT: "Text (string)",
|
variables_TEXT: "Text (string)",
|
||||||
variables_ARRAY: "Array (array)",
|
variables_ARRAY: "Array (array)",
|
||||||
variables_CHARACTER: "Buchstabe (char)",
|
variables_CHARACTER: "char (char)",
|
||||||
variables_BOOLEAN: "Boolean (boolean)",
|
variables_BOOLEAN: "Boolean (boolean)",
|
||||||
variables_NULL: "void (void)",
|
variables_NULL: "void (void)",
|
||||||
variables_UNDEF: "undefined",
|
variables_UNDEF: "undefined",
|
||||||
variables_set: "Schreibe",
|
|
||||||
variables_to: "",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tooltips
|
* Tooltips
|
||||||
@@ -152,7 +154,6 @@ export const UI = {
|
|||||||
button_next: "nächster Schritt",
|
button_next: "nächster Schritt",
|
||||||
button_tutorial_overview: "Tutorial Übersicht",
|
button_tutorial_overview: "Tutorial Übersicht",
|
||||||
button_login: "Anmelden",
|
button_login: "Anmelden",
|
||||||
button_createVariable: "Typisierte Variable erstellen",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -312,17 +313,8 @@ export const UI = {
|
|||||||
* Device Selction
|
* Device Selction
|
||||||
* */
|
* */
|
||||||
deviceselection_head: "Welches Board benutzt du?",
|
deviceselection_head: "Welches Board benutzt du?",
|
||||||
deviceselection_keep_selection: "Speichere meine Auswahl fürs nächste Mal (Du kannst das Board später in den Einstellungen wechseln)",
|
deviceselection_keep_selection:
|
||||||
|
"Speichere meine Auswahl fürs nächste Mal (Du kannst das Board später in den Einstellungen wechseln)",
|
||||||
deviceselection_footnote: "Hier kommst du zur alten Blockly Version für den ",
|
deviceselection_footnote: "Hier kommst du zur alten Blockly Version für den ",
|
||||||
deviceselection_footnote_02: "oder die",
|
deviceselection_footnote_02: "oder die",
|
||||||
|
|
||||||
/**
|
|
||||||
* Sensor Markdown Information
|
|
||||||
*/
|
|
||||||
sensorinfo_info: "Informationen zum Sensor",
|
|
||||||
sensorinfo_description: "Beschreibung",
|
|
||||||
sensorinfo_measurable_phenos: "Messbare Phänomene",
|
|
||||||
sensorinfo_manufacturer: "Hersteller",
|
|
||||||
sensorinfo_lifetime: "Lebensdauer",
|
|
||||||
sensorinfo_explanation: "Diese Informationen wurden aus [sensors.wiki](https://sensors.wiki) entnommen. Für weitere Informationen besuchen Sie den Abschnitt über diesen Sensor "
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { LED } from "./en/sensebox-led";
|
|||||||
import { LORA } from "./en/sensebox-lora";
|
import { LORA } from "./en/sensebox-lora";
|
||||||
import { OSEM } from "./en/sensebox-osem";
|
import { OSEM } from "./en/sensebox-osem";
|
||||||
import { RTC } from "./en/sensebox-rtc";
|
import { RTC } from "./en/sensebox-rtc";
|
||||||
|
import { NTP } from "./en/sensebox-ntp";
|
||||||
import { SD } from "./en/sensebox-sd";
|
import { SD } from "./en/sensebox-sd";
|
||||||
import { SENSORS } from "./en/sensebox-sensors";
|
import { SENSORS } from "./en/sensebox-sensors";
|
||||||
import { TELEGRAM } from "./en/sensebox-telegram";
|
import { TELEGRAM } from "./en/sensebox-telegram";
|
||||||
@@ -40,6 +41,7 @@ export const En = {
|
|||||||
...LORA,
|
...LORA,
|
||||||
...OSEM,
|
...OSEM,
|
||||||
...RTC,
|
...RTC,
|
||||||
|
...NTP,
|
||||||
...SD,
|
...SD,
|
||||||
...SENSORS,
|
...SENSORS,
|
||||||
...SENSEBOX,
|
...SENSEBOX,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export const NTP = {
|
||||||
|
sensebox_ntp_init: "Initialise NTP",
|
||||||
|
sensebox_ntp_init_tooltip:
|
||||||
|
"Initialisiere die RTC. Schließe diese an einen der 5 I2C/Wire Anschlüsse an und lege die Batterie ein. Bevor du die Uhrzeit auslesen kannst muss diese zunächst einmal gesetzt werden. Dieser Schritt muss normalerweise nur einmalig durchgeführt werden.",
|
||||||
|
sensebox_ntp_get: "Get time from NTP Server: ",
|
||||||
|
sensebox_ntp_get_tooltip:
|
||||||
|
"Gibt dir den ausgewählten Wert zurück. Unix Zeit entspricht der Anzahl der Sekunden seit dem 1.1.1970",
|
||||||
|
sensebox_ntp_epochTime: "Unix time",
|
||||||
|
sensebox_ntp_formattedTimeStamp: "Timestamp (hh:mm:ss)",
|
||||||
|
};
|
||||||
@@ -11,11 +11,12 @@ export const OSEM = {
|
|||||||
senseBox_send_to_osem: "Send measurement to openSenseMap",
|
senseBox_send_to_osem: "Send measurement to openSenseMap",
|
||||||
senseBox_osem_connection: "Connect to openSenseMap",
|
senseBox_osem_connection: "Connect to openSenseMap",
|
||||||
senseBox_osem_host: "opensensemap.org",
|
senseBox_osem_host: "opensensemap.org",
|
||||||
senseBox_osem_host_workshop: "workshop.opensensemap.org",
|
senseBox_osem_host_testing: "testing.opensensemap.org",
|
||||||
senseBox_osem_exposure: "Type",
|
senseBox_osem_exposure: "Type",
|
||||||
senseBox_osem_stationary: "Stationary",
|
senseBox_osem_stationary: "Stationary",
|
||||||
senseBox_osem_mobile: "Mobile",
|
senseBox_osem_mobile: "Mobile",
|
||||||
senseBox_osem_access_token: "API Key",
|
senseBox_osem_access_token: "API Key",
|
||||||
|
senseBox_osem_xallowtoken: "X-ALLOW-TOKEN",
|
||||||
senseBox_send_mobile_to_osem: "Send measurement and location to openSenseMap",
|
senseBox_send_mobile_to_osem: "Send measurement and location to openSenseMap",
|
||||||
senseBox_send_mobile_to_osem_tip: "Send Value and Location to openSenseMap",
|
senseBox_send_mobile_to_osem_tip: "Send Value and Location to openSenseMap",
|
||||||
senseBox_osem_restart: "Restart device if disconnected?",
|
senseBox_osem_restart: "Restart device if disconnected?",
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
export const RTC = {
|
export const RTC = {
|
||||||
sensebox_rtc_init: "Initialise RTC",
|
sensebox_rtc_init: "Initialise external RTC",
|
||||||
sensebox_rtc_init_tooltip:
|
sensebox_rtc_init_tooltip:
|
||||||
"Initialise the RTC. Connect it to one of the 5 I2C/Wire connections and insert the battery. Before you can read out the time, it must first be set. This step usually only needs to be done once.",
|
"Initialise the RTC. Connect it to one of the 5 I2C/Wire connections and insert the battery. Before you can read out the time, it must first be set. This step usually only needs to be done once.",
|
||||||
sensebox_rtc_set: "Set RTC time/date:",
|
sensebox_rtc_set: "Set RTC time/date:",
|
||||||
sensebox_rtc_set_tooltip:
|
sensebox_rtc_set_tooltip:
|
||||||
"Sets the time of the RTC. Note that you execute this block in the setup.",
|
"Sets the time of the RTC. Note that you execute this block in the setup.",
|
||||||
sensebox_rtc_get_timestamp: "Get timestamp",
|
sensebox_rtc_get_timestamp: "Timestamp external RTC (RFC 3339)",
|
||||||
sensebox_rtc_get_timestamp_tooltip:
|
sensebox_rtc_get_timestamp_tooltip:
|
||||||
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||||
sensebox_rtc_get_tooltip: "Returns the selected value",
|
sensebox_rtc_get_tooltip: "Returns the selected value",
|
||||||
@@ -17,4 +17,22 @@ export const RTC = {
|
|||||||
sensebox_rtc_day: "day",
|
sensebox_rtc_day: "day",
|
||||||
sensebox_rtc_month: "month",
|
sensebox_rtc_month: "month",
|
||||||
sensebox_rtc_year: "year",
|
sensebox_rtc_year: "year",
|
||||||
|
sensebox_internal_rtc_init: "Initialise internal RTC",
|
||||||
|
sensebox_internal_rtc_init_tooltip:
|
||||||
|
"Initialise the internal RTC. This RTC is not battery backed and will be reset on every power cycle.",
|
||||||
|
sensebox_internal_rtc_set: "Set internal RTC time/date:",
|
||||||
|
sensebox_internal_rtc_set_tooltip:
|
||||||
|
"Sets the time of the internal RTC. Note that you execute this block in the setup.",
|
||||||
|
sensebox_internal_rtc_get: "Get: ",
|
||||||
|
sensebox_internal_rtc_get_timestamp: "Timestamp internal RTC (RFC 3339)",
|
||||||
|
sensebox_internal_rtc_get_timestamp_tooltip:
|
||||||
|
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||||
|
sensebox_internal_rtc_get_tooltip: "Returns the selected value",
|
||||||
|
sensebox_internal_rtc_epoch: "Unix Time",
|
||||||
|
sensebox_internal_rtc_year: "year",
|
||||||
|
sensebox_internal_rtc_month: "month",
|
||||||
|
sensebox_internal_rtc_day: "day",
|
||||||
|
sensebox_internal_rtc_hour: "hour",
|
||||||
|
sensebox_internal_rtc_minutes: "minutes",
|
||||||
|
sensebox_internal_rtc_seconds: "seconds",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ If the max distance is reached the a value of **O** will be returned`,
|
|||||||
senseBox_bme680: "Environmental sensor (BME680)",
|
senseBox_bme680: "Environmental sensor (BME680)",
|
||||||
senseBox_bme_iaq: "Indoor Air Quality (IAQ)",
|
senseBox_bme_iaq: "Indoor Air Quality (IAQ)",
|
||||||
senseBox_bme_iaq_accuracy: "Calibration Value",
|
senseBox_bme_iaq_accuracy: "Calibration Value",
|
||||||
|
senseBox_bme_pressure: "Airpressure in Pa",
|
||||||
senseBox_bme_co2: "CO2 Equivalent",
|
senseBox_bme_co2: "CO2 Equivalent",
|
||||||
senseBox_bme_breatheVocEquivalent: "Breathe VOC Equivalent",
|
senseBox_bme_breatheVocEquivalent: "Breathe VOC Equivalent",
|
||||||
senseBox_bme_tooltip: `Connect the environmental sensor to one of the 5 **I2C ports**. **Note:** The sensor needs some time to calibrate.
|
senseBox_bme_tooltip: `Connect the environmental sensor to one of the 5 **I2C ports**. **Note:** The sensor needs some time to calibrate.
|
||||||
@@ -205,4 +206,23 @@ The measured values for temperature, humidity and air pressure can be used direc
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
senseBox_watertemperature: "Water Temperature",
|
senseBox_watertemperature: "Water Temperature",
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feinstaubsensor Sensirion SPS30
|
||||||
|
*/
|
||||||
|
|
||||||
|
senseBox_sps30: "Particulate Matter Sensor (Sensirion SPS30)",
|
||||||
|
senseBox_sps30_dimension: "in µg/m³",
|
||||||
|
senseBox_sps30_1p0: "PM1.0",
|
||||||
|
senseBox_sps30_2p5: "PM2.5",
|
||||||
|
senseBox_sps30_4p0: "PM4.0",
|
||||||
|
senseBox_sps30_10p0: "PM10",
|
||||||
|
senseBox_sps30_tooltip:
|
||||||
|
"This block gives you the measured value of the Sensirion SPS30 fine dust sensor. Connect the fine dust sensor to one of the 5 **I2C** connectors. Select between PM1.0, PM2.5, PM4.0 and PM10 in the dropdown menu. The measured value will be displayed as **decimal** in µg/m3",
|
||||||
|
senseBox_sps30_helpurl:
|
||||||
|
"https://docs.sensebox.de/hardware/sensoren-feinstaub/",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,23 +8,25 @@ export const UI = {
|
|||||||
toolbox_math: "Math",
|
toolbox_math: "Math",
|
||||||
toolbox_io: "Input/Output",
|
toolbox_io: "Input/Output",
|
||||||
toolbox_time: "Time",
|
toolbox_time: "Time",
|
||||||
|
toolbox_rtc: "RTC",
|
||||||
|
toolbox_ntp: "NTP",
|
||||||
toolbox_functions: "Functions",
|
toolbox_functions: "Functions",
|
||||||
toolbox_variables: "Variables",
|
toolbox_variables: "Variables",
|
||||||
toolbox_serial: "Serial",
|
toolbox_serial: "Serial",
|
||||||
toolbox_advanced: "Erweitert",
|
toolbox_advanced: "Erweitert",
|
||||||
toolbox_motors: "Motors",
|
toolbox_motors: "Motors",
|
||||||
|
toolbox_label_externalRTC: "External RTC",
|
||||||
|
toolbox_label_internalRTC: "Internal RTC",
|
||||||
variable_NUMBER: "Number (int)",
|
variable_NUMBER: "Number (int)",
|
||||||
variable_SHORT_NUMBER: "char",
|
variable_SHORT_NUMBER: "char",
|
||||||
variable_LONG: "Big number (long)",
|
variable_LONG: " Zahl (long)",
|
||||||
variable_DECIMAL: "Decimal (float)",
|
variable_DECIMAL: "Decimal (float)",
|
||||||
variables_TEXT: "Text (string)",
|
variables_TEXT: "Text (string)",
|
||||||
variables_ARRAY: "Array (array)",
|
variables_ARRAY: "Array (array)",
|
||||||
variables_CHARACTER: "Character (char)",
|
variables_CHARACTER: "char (char)",
|
||||||
variables_BOOLEAN: "Boolean (boolean)",
|
variables_BOOLEAN: "Boolean (boolean)",
|
||||||
variables_NULL: "void (void)",
|
variables_NULL: "void (void)",
|
||||||
variables_UNDEF: "undefined",
|
variables_UNDEF: "undefined",
|
||||||
variables_set: "set",
|
|
||||||
variables_to: "to",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tooltips
|
* Tooltips
|
||||||
@@ -147,7 +149,6 @@ export const UI = {
|
|||||||
button_next: "Next step",
|
button_next: "Next step",
|
||||||
button_tutorial_overview: "Tutorial overview",
|
button_tutorial_overview: "Tutorial overview",
|
||||||
button_login: "Login",
|
button_login: "Login",
|
||||||
button_createVariable: "Create Typed Variable",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -307,17 +308,9 @@ export const UI = {
|
|||||||
* Device Selction
|
* Device Selction
|
||||||
* */
|
* */
|
||||||
deviceselection_head: "Which board are you using?",
|
deviceselection_head: "Which board are you using?",
|
||||||
deviceselection_keep_selection: "Save my choice (You can change the board later in the settings)",
|
deviceselection_keep_selection:
|
||||||
deviceselection_footnote: "Here you can access the old blockly Version for the",
|
"Save my choice (You can change the board later in the settings)",
|
||||||
|
deviceselection_footnote:
|
||||||
|
"Here you can access the old blockly Version for the",
|
||||||
deviceselection_footnote_02: "or the",
|
deviceselection_footnote_02: "or the",
|
||||||
|
|
||||||
/**
|
|
||||||
* Sensor Markdown Information
|
|
||||||
* */
|
|
||||||
sensorinfo_info: "Informationen regarding the Sensor",
|
|
||||||
sensorinfo_description: "Description",
|
|
||||||
sensorinfo_measurable_phenos: "Measurable Phenomena",
|
|
||||||
sensorinfo_manufacturer: "Manufacturer",
|
|
||||||
sensorinfo_lifetime: "Lifetime",
|
|
||||||
sensorinfo_explanation: "This information was fetched from [sensors.wiki](https://sensors.wiki). For more information visit the section on this sensor ",
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Block, Value, Field, Shadow, Category } from "../";
|
import { Block, Value, Field, Shadow, Category, Sep, Label } from "../";
|
||||||
import { getColour } from "../helpers/colour";
|
import { getColour } from "../helpers/colour";
|
||||||
import "@blockly/block-plus-minus";
|
import "@blockly/block-plus-minus";
|
||||||
import { TypedVariableModal } from "@blockly/plugin-typed-variable-modal";
|
import { TypedVariableModal } from "@blockly/plugin-typed-variable-modal";
|
||||||
@@ -16,6 +16,7 @@ class Toolbox extends React.Component {
|
|||||||
this.props.workspace,
|
this.props.workspace,
|
||||||
"callbackName",
|
"callbackName",
|
||||||
[
|
[
|
||||||
|
[`${Blockly.Msg.variable_SHORT_NUMBER}`, "char"],
|
||||||
[`${Blockly.Msg.variable_NUMBER}`, "int"],
|
[`${Blockly.Msg.variable_NUMBER}`, "int"],
|
||||||
[`${Blockly.Msg.variable_LONG}`, "long"],
|
[`${Blockly.Msg.variable_LONG}`, "long"],
|
||||||
[`${Blockly.Msg.variable_DECIMAL}`, "float"],
|
[`${Blockly.Msg.variable_DECIMAL}`, "float"],
|
||||||
@@ -32,7 +33,7 @@ class Toolbox extends React.Component {
|
|||||||
|
|
||||||
// Add your button and give it a callback name.
|
// Add your button and give it a callback name.
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.setAttribute("text", Blockly.Msg.button_createVariable);
|
button.setAttribute("text", "Create Typed Variable");
|
||||||
button.setAttribute("callbackKey", "callbackName");
|
button.setAttribute("callbackKey", "callbackName");
|
||||||
|
|
||||||
xmlList.push(button);
|
xmlList.push(button);
|
||||||
@@ -40,7 +41,6 @@ class Toolbox extends React.Component {
|
|||||||
// This gets all the variables that the user creates and adds them to the
|
// This gets all the variables that the user creates and adds them to the
|
||||||
// flyout.
|
// flyout.
|
||||||
const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
|
const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
|
||||||
console.log(blockList);
|
|
||||||
xmlList = xmlList.concat(blockList);
|
xmlList = xmlList.concat(blockList);
|
||||||
return xmlList;
|
return xmlList;
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,7 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="sensebox_sensor_uv_light" />
|
<Block type="sensebox_sensor_uv_light" />
|
||||||
<Block type="sensebox_sensor_bmx055_accelerometer" />
|
<Block type="sensebox_sensor_bmx055_accelerometer" />
|
||||||
<Block type="sensebox_sensor_sds011" />
|
<Block type="sensebox_sensor_sds011" />
|
||||||
|
<Block type="sensebox_sensor_sps30" />
|
||||||
<Block type="sensebox_sensor_pressure" />
|
<Block type="sensebox_sensor_pressure" />
|
||||||
<Block type="sensebox_sensor_dps310" />
|
<Block type="sensebox_sensor_dps310" />
|
||||||
<Block type="sensebox_sensor_bme680_bsec" />
|
<Block type="sensebox_sensor_bme680_bsec" />
|
||||||
@@ -502,6 +503,12 @@ class Toolbox extends React.Component {
|
|||||||
<Block type="time_micros"></Block>
|
<Block type="time_micros"></Block>
|
||||||
<Block type="infinite_loop"></Block>
|
<Block type="infinite_loop"></Block>
|
||||||
<Block type="sensebox_interval_timer"></Block>
|
<Block type="sensebox_interval_timer"></Block>
|
||||||
|
<Category
|
||||||
|
id="time"
|
||||||
|
name={Blockly.Msg.toolbox_rtc}
|
||||||
|
colour={getColour().time}
|
||||||
|
>
|
||||||
|
<Label text={Blockly.Msg.toolbox_label_externalRTC}></Label>
|
||||||
<Block type="sensebox_rtc_init"></Block>
|
<Block type="sensebox_rtc_init"></Block>
|
||||||
<Block type="sensebox_rtc_set">
|
<Block type="sensebox_rtc_set">
|
||||||
<Value name="second">
|
<Value name="second">
|
||||||
@@ -538,6 +545,21 @@ class Toolbox extends React.Component {
|
|||||||
{/* <Block type="sensebox_rtc_set_ntp"></Block> */}
|
{/* <Block type="sensebox_rtc_set_ntp"></Block> */}
|
||||||
<Block type="sensebox_rtc_get"></Block>
|
<Block type="sensebox_rtc_get"></Block>
|
||||||
<Block type="sensebox_rtc_get_timestamp"></Block>
|
<Block type="sensebox_rtc_get_timestamp"></Block>
|
||||||
|
<Sep gap="40"></Sep>
|
||||||
|
<Label text={Blockly.Msg.toolbox_label_internalRTC}></Label>
|
||||||
|
<Block type="sensebox_internal_rtc_init"></Block>
|
||||||
|
<Block type="sensebox_internal_rtc_set"></Block>
|
||||||
|
<Block type="sensebox_internal_rtc_get"></Block>
|
||||||
|
<Block type="sensebox_internal_rtc_get_timestamp"></Block>
|
||||||
|
</Category>
|
||||||
|
<Category
|
||||||
|
id="timeUTP"
|
||||||
|
name={Blockly.Msg.toolbox_ntp}
|
||||||
|
colour={getColour().time}
|
||||||
|
>
|
||||||
|
<Block type="sensebox_ntp_init"></Block>
|
||||||
|
<Block type="sensebox_ntp_get"></Block>
|
||||||
|
</Category>
|
||||||
</Category>
|
</Category>
|
||||||
<Category
|
<Category
|
||||||
id="math"
|
id="math"
|
||||||
@@ -643,7 +665,10 @@ class Toolbox extends React.Component {
|
|||||||
</Value>
|
</Value>
|
||||||
</Block>
|
</Block>
|
||||||
</Category>
|
</Category>
|
||||||
<Category name={Blockly.Msg.toolbox_motors} colour={getColour().motors}>
|
<Category
|
||||||
|
name={Blockly.Msg.toolbox_motors}
|
||||||
|
colour={getColour().motors}
|
||||||
|
>
|
||||||
<Block type="sensebox_motors_beginServoMotor" />
|
<Block type="sensebox_motors_beginServoMotor" />
|
||||||
<Block type="sensebox_motors_moveServoMotor">
|
<Block type="sensebox_motors_moveServoMotor">
|
||||||
<Value name="degrees">
|
<Value name="degrees">
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import Sidebar from "./Sidebar";
|
|||||||
import Dialog from "../Dialog";
|
import Dialog from "../Dialog";
|
||||||
import SaveIcon from "./SaveIcon";
|
import SaveIcon from "./SaveIcon";
|
||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import DeviceSelection from "../DeviceSelection";
|
|
||||||
|
|
||||||
const CodeEditor = (props) => {
|
const CodeEditor = (props) => {
|
||||||
//const [filehandle, setFileHandle] = useState();
|
//const [filehandle, setFileHandle] = useState();
|
||||||
@@ -193,7 +192,6 @@ void loop() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<DeviceSelection />
|
|
||||||
<Grid item lg={4} md={4}>
|
<Grid item lg={4} md={4}>
|
||||||
<Button
|
<Button
|
||||||
style={{ padding: "1rem", margin: "1rem" }}
|
style={{ padding: "1rem", margin: "1rem" }}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { connect } from "react-redux";
|
|||||||
import Dialog from "./Dialog";
|
import Dialog from "./Dialog";
|
||||||
|
|
||||||
import { withStyles } from "@material-ui/core/styles";
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
|
import Checkbox from "@material-ui/core/Checkbox";
|
||||||
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import { IconButton, Grid, Avatar, Typography } from "@material-ui/core";
|
import { IconButton, Grid, Avatar, Typography } from "@material-ui/core";
|
||||||
import { setBoard } from "../actions/boardAction";
|
import { setBoard } from "../actions/boardAction";
|
||||||
@@ -25,9 +27,15 @@ const styles = (theme) => ({
|
|||||||
|
|
||||||
class DeviceSeclection extends Component {
|
class DeviceSeclection extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
var previousPageWasAnotherDomain = props.pageVisits === 0;
|
||||||
|
var userWantToKeepBoard = window.localStorage.getItem("board")
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
open: props.selectedBoard ? false : true,
|
open: userWantToKeepBoard
|
||||||
|
? !userWantToKeepBoard
|
||||||
|
: previousPageWasAnotherDomain,
|
||||||
selectedBoard : "",
|
selectedBoard : "",
|
||||||
saveSettings: false,
|
saveSettings: false,
|
||||||
|
|
||||||
@@ -35,7 +43,12 @@ class DeviceSeclection extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleDialog = () => {
|
toggleDialog = () => {
|
||||||
|
this.setState({ open: !this.state });
|
||||||
|
if(this.state.saveSettings){
|
||||||
|
window.localStorage.setItem("board", this.state.selectedBoard)
|
||||||
|
}
|
||||||
this.props.setBoard(this.state.selectedBoard)
|
this.props.setBoard(this.state.selectedBoard)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onChange = (e) => {
|
onChange = (e) => {
|
||||||
@@ -47,9 +60,8 @@ class DeviceSeclection extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onclick = (e, value) => {
|
onclick = (e, value) => {
|
||||||
|
console.log(e, value)
|
||||||
this.setState({selectedBoard: value})
|
this.setState({selectedBoard: value})
|
||||||
this.props.setBoard(value)
|
|
||||||
this.setState({ open: !this.state });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -62,6 +74,7 @@ class DeviceSeclection extends Component {
|
|||||||
title={Blockly.Msg.deviceselection_head}
|
title={Blockly.Msg.deviceselection_head}
|
||||||
content={""}
|
content={""}
|
||||||
onClick={this.toggleDialog}
|
onClick={this.toggleDialog}
|
||||||
|
button={Blockly.Msg.button_accept}
|
||||||
disabled={this.state.selectedBoard===""}
|
disabled={this.state.selectedBoard===""}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
@@ -80,6 +93,7 @@ class DeviceSeclection extends Component {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
<p>senseBox MCU</p>
|
<p>senseBox MCU</p>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/* <Grid item xs={4}>
|
{/* <Grid item xs={4}>
|
||||||
<IconButton onClick={(e) => this.onclick(e, "esp")}>
|
<IconButton onClick={(e) => this.onclick(e, "esp")}>
|
||||||
<Avatar
|
<Avatar
|
||||||
@@ -110,6 +124,21 @@ class DeviceSeclection extends Component {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
|
<FormControlLabel
|
||||||
|
style={{ marginTop: "20px" }}
|
||||||
|
classes={{ label: this.props.classes.label }}
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
size={"small"}
|
||||||
|
value={true}
|
||||||
|
checked={this.state.checked}
|
||||||
|
onChange={(e) => this.onChange(e)}
|
||||||
|
name="dialog"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={Blockly.Msg.deviceselection_keep_selection}
|
||||||
|
/>
|
||||||
<Typography variant="body1" >
|
<Typography variant="body1" >
|
||||||
{Blockly.Msg.deviceselection_footnote} <a href="https://sensebox.github.io/blockly/">Arduino UNO</a> {Blockly.Msg.deviceselection_footnote_02} <a href="https://sensebox-blockly.netlify.app/ardublockly/?board=sensebox-mcu">senseBox MCU</a>
|
{Blockly.Msg.deviceselection_footnote} <a href="https://sensebox.github.io/blockly/">Arduino UNO</a> {Blockly.Msg.deviceselection_footnote_02} <a href="https://sensebox-blockly.netlify.app/ardublockly/?board=sensebox-mcu">senseBox MCU</a>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import Button from "@material-ui/core/Button";
|
|||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import rehypeRaw from "rehype-raw";
|
|
||||||
import Container from "@material-ui/core/Container";
|
import Container from "@material-ui/core/Container";
|
||||||
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
|
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
|
||||||
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
|
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
|
||||||
@@ -62,7 +61,6 @@ class Faq extends Component {
|
|||||||
className="news"
|
className="news"
|
||||||
allowDangerousHtml="true"
|
allowDangerousHtml="true"
|
||||||
children={object.answer}
|
children={object.answer}
|
||||||
rehypePlugins={[rehypeRaw]}
|
|
||||||
></ReactMarkdown>
|
></ReactMarkdown>
|
||||||
</Typography>
|
</Typography>
|
||||||
</ExpansionPanelDetails>
|
</ExpansionPanelDetails>
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import Divider from "@material-ui/core/Divider";
|
|||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Backdrop from "@material-ui/core/Backdrop";
|
import Backdrop from "@material-ui/core/Backdrop";
|
||||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||||
import DeviceSelection from "../DeviceSelection";
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
link: {
|
link: {
|
||||||
@@ -61,7 +60,8 @@ class ProjectHome extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
snackbar: true,
|
snackbar: true,
|
||||||
key: Date.now(),
|
key: Date.now(),
|
||||||
message: `Dein angefragtes ${type === "gallery" ? "Galerie-" : ""
|
message: `Dein angefragtes ${
|
||||||
|
type === "gallery" ? "Galerie-" : ""
|
||||||
}Projekt konnte nicht gefunden werden.`,
|
}Projekt konnte nicht gefunden werden.`,
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
@@ -108,7 +108,6 @@ class ProjectHome extends Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<h1>{data}</h1>
|
<h1>{data}</h1>
|
||||||
<DeviceSelection />
|
|
||||||
{this.props.progress ? (
|
{this.props.progress ? (
|
||||||
<Backdrop open invisible>
|
<Backdrop open invisible>
|
||||||
<CircularProgress color="primary" />
|
<CircularProgress color="primary" />
|
||||||
@@ -128,7 +127,8 @@ class ProjectHome extends Component {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
to={`/${data === "Projekte" ? "project" : "gallery"
|
to={`/${
|
||||||
|
data === "Projekte" ? "project" : "gallery"
|
||||||
}/${project._id}`}
|
}/${project._id}`}
|
||||||
style={{ textDecoration: "none", color: "inherit" }}
|
style={{ textDecoration: "none", color: "inherit" }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { visitPage } from "../../actions/generalActions";
|
import { visitPage, setPlatform } from "../../actions/generalActions";
|
||||||
|
|
||||||
import { Route, Switch, withRouter } from "react-router-dom";
|
import { Route, Switch, withRouter } from "react-router-dom";
|
||||||
|
|
||||||
@@ -27,6 +27,24 @@ import Faq from "../Faq";
|
|||||||
import CodeEditor from "../CodeEditor/CodeEditor";
|
import CodeEditor from "../CodeEditor/CodeEditor";
|
||||||
|
|
||||||
class Routes extends Component {
|
class Routes extends Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { location } = this.props;
|
||||||
|
const query = new URLSearchParams(location.search, [location.search]);
|
||||||
|
const mode = query.get('mode');
|
||||||
|
|
||||||
|
if (!this.props.platform && mode) {
|
||||||
|
switch (mode.toLowerCase()) {
|
||||||
|
case 'tablet':
|
||||||
|
this.props.setPlatform(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
this.props.visitPage();
|
this.props.visitPage();
|
||||||
}
|
}
|
||||||
@@ -105,6 +123,12 @@ class Routes extends Component {
|
|||||||
|
|
||||||
Home.propTypes = {
|
Home.propTypes = {
|
||||||
visitPage: PropTypes.func,
|
visitPage: PropTypes.func,
|
||||||
|
platform: PropTypes.bool.isRequired,
|
||||||
|
setPlatform: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, { visitPage })(withRouter(Routes));
|
const mapStateToProps = (state) => ({
|
||||||
|
platform: state.general.platform,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, { visitPage, setPlatform })(withRouter(Routes));
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import Box from "@material-ui/core/Box";
|
|
||||||
import Tab from "@material-ui/core/Tab";
|
|
||||||
import TabContext from "@material-ui/lab/TabContext";
|
|
||||||
import TabList from "@material-ui/lab/TabList";
|
|
||||||
import TabPanel from "@material-ui/lab/TabPanel";
|
|
||||||
import store from "../store";
|
|
||||||
import ReactMarkdown from "react-markdown";
|
|
||||||
import * as Blockly from "blockly";
|
|
||||||
|
|
||||||
|
|
||||||
export default function LabTabs() {
|
|
||||||
const [value, setValue] = React.useState('1');
|
|
||||||
|
|
||||||
const handleChange = (event, newValue) => {
|
|
||||||
setValue(newValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
// get the description in the current language if no lang is give return english or the first one
|
|
||||||
function filterLanguage(options) {
|
|
||||||
var lang;
|
|
||||||
if (window.localStorage.getItem("locale")) {
|
|
||||||
lang = window.localStorage.getItem("locale").split("_")[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lang = "en";
|
|
||||||
}
|
|
||||||
for (var i = 0; i < options.length; i++) {
|
|
||||||
if (options[i].languageCode === lang) {
|
|
||||||
return options[i].text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options[0].text;
|
|
||||||
}
|
|
||||||
var currentStore = store.getState();
|
|
||||||
// ALL SENSOR DATA FROM WIKI
|
|
||||||
var sensorData = currentStore.sensorwiki;
|
|
||||||
// NAME OF SELECTED BLOCK
|
|
||||||
var sensorName = currentStore.workspace.code.data.name;
|
|
||||||
// SEARCH ALL DATA FOR SELECTED BLOCK NAME
|
|
||||||
var sensorInfo = sensorData.find(function (element) {
|
|
||||||
return element.slug === sensorName;
|
|
||||||
});
|
|
||||||
if (sensorInfo) {
|
|
||||||
sensorInfo.markdown = "Coming soon...";
|
|
||||||
|
|
||||||
// GET DESCRIPTION OF SELECTED BLOCK
|
|
||||||
sensorInfo.details = `# ${sensorName.toUpperCase()}
|
|
||||||
${Blockly.Msg.sensorinfo_explanation} [${sensorName.toUpperCase()}](https://sensors.wiki/sensor/detail/${sensorName})
|
|
||||||
## ${Blockly.Msg.sensorinfo_description}
|
|
||||||
${filterLanguage(sensorInfo.description.item)}
|
|
||||||
## ${Blockly.Msg.sensorinfo_measurable_phenos}
|
|
||||||
## ${Blockly.Msg.sensorinfo_manufacturer}
|
|
||||||
${sensorInfo.manufacturer}
|
|
||||||
## ${Blockly.Msg.sensorinfo_lifetime}
|
|
||||||
${sensorInfo.lifePeriod}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box sx={{ width: '100%', typography: 'body1' }}>
|
|
||||||
<TabContext value={value}>
|
|
||||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
|
||||||
<TabList onChange={handleChange}>
|
|
||||||
<Tab label="Basic Information" value="1" />
|
|
||||||
<Tab label="Details" value="2" />
|
|
||||||
</TabList>
|
|
||||||
</Box>
|
|
||||||
<TabPanel value="1">
|
|
||||||
{sensorInfo ? <ReactMarkdown>{sensorInfo.markdown}</ReactMarkdown> : "No data available"}
|
|
||||||
</TabPanel>
|
|
||||||
<TabPanel value="2">
|
|
||||||
{sensorInfo ? <ReactMarkdown>{sensorInfo.details}</ReactMarkdown> : "No data available"}
|
|
||||||
</TabPanel>
|
|
||||||
</TabContext>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,41 +1,17 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
import withWidth from "@material-ui/core/withWidth";
|
import withWidth from "@material-ui/core/withWidth";
|
||||||
import { Button, Card } from "@material-ui/core";
|
|
||||||
|
import { Card } from "@material-ui/core";
|
||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import CardContent from "@material-ui/core/CardContent";
|
import CardContent from "@material-ui/core/CardContent";
|
||||||
|
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import Dialog from "@material-ui/core/Dialog";
|
|
||||||
import DialogActions from "@material-ui/core/DialogActions";
|
|
||||||
import DialogContent from "@material-ui/core/DialogContent";
|
|
||||||
import Slide from "@material-ui/core/Slide";
|
|
||||||
import SensorInfo from "./SensorInfo";
|
|
||||||
import store from "../store";
|
|
||||||
|
|
||||||
const Transition = React.forwardRef(function Transition(props, ref) {
|
|
||||||
return <Slide direction="up" ref={ref} {...props} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
class TooltipViewer extends Component {
|
class TooltipViewer extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.inputRef = React.createRef();
|
|
||||||
this.state = {
|
|
||||||
open: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDialog = () => {
|
|
||||||
this.setState({ open: !this.state });
|
|
||||||
};
|
|
||||||
|
|
||||||
openDialog = () => {
|
|
||||||
this.setState({ open: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
@@ -53,46 +29,14 @@ class TooltipViewer extends Component {
|
|||||||
{Blockly.Msg.tooltip_viewer}
|
{Blockly.Msg.tooltip_viewer}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Typography variant="body2" component="p">
|
|
||||||
<ReactMarkdown linkTarget="_blank">
|
<ReactMarkdown linkTarget="_blank">
|
||||||
{this.props.tooltip}
|
{this.props.tooltip}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
{store.getState().workspace.code.data ? (
|
|
||||||
<Button
|
{this.props.helpurl !== "" ? (
|
||||||
label="Mehr"
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={() => {
|
|
||||||
this.openDialog();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Sensor Informationen
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<ReactMarkdown>{`${Blockly.Msg.tooltip_moreInformation} [${Blockly.Msg.labels_here}](${this.props.helpurl})`}</ReactMarkdown>
|
<ReactMarkdown>{`${Blockly.Msg.tooltip_moreInformation} [${Blockly.Msg.labels_here}](${this.props.helpurl})`}</ReactMarkdown>
|
||||||
)}
|
) : null}
|
||||||
</Typography>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
{store.getState().workspace.code.data ? (<Dialog
|
|
||||||
open={this.state.open}
|
|
||||||
TransitionComponent={Transition}
|
|
||||||
keepMounted
|
|
||||||
aria-describedby="alert-dialog-slide-description"
|
|
||||||
onClose={() => {
|
|
||||||
this.toggleDialog();
|
|
||||||
}}
|
|
||||||
maxWidth={"md"}
|
|
||||||
fullWidth={true}
|
|
||||||
>
|
|
||||||
<DialogContent>
|
|
||||||
<SensorInfo></SensorInfo>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={() => {
|
|
||||||
this.toggleDialog();
|
|
||||||
}}>Close</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>) : (null)}
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ class Builder extends Component {
|
|||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
submit = () => {;
|
submit = () => {
|
||||||
var isError = this.props.checkError();
|
var isError = this.props.checkError();
|
||||||
if (isError) {
|
if (isError) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -273,8 +273,6 @@ class Builder extends Component {
|
|||||||
} else {
|
} else {
|
||||||
// export steps without attribute 'url'
|
// export steps without attribute 'url'
|
||||||
var steps = this.props.steps;
|
var steps = this.props.steps;
|
||||||
// console.log(steps);
|
|
||||||
var length = steps.length;
|
|
||||||
var newTutorial = new FormData();
|
var newTutorial = new FormData();
|
||||||
newTutorial.append("title", this.props.title);
|
newTutorial.append("title", this.props.title);
|
||||||
newTutorial.append("difficulty", this.props.difficulty);
|
newTutorial.append("difficulty", this.props.difficulty);
|
||||||
@@ -301,30 +299,11 @@ class Builder extends Component {
|
|||||||
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
|
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (i === length-1 && step.type === "finalpage") {
|
|
||||||
newTutorial.append(`steps[${i}][samplesolutions]`, step.samplesolutions);
|
|
||||||
newTutorial.append(`steps[${i}][furthertutorials]`, step.furthertutorials);
|
|
||||||
|
|
||||||
if (step.samplesolutions === true) {
|
|
||||||
var solutionindex = 0;
|
|
||||||
steps.forEach((solutionstep) => {
|
|
||||||
if (solutionstep.type === "task"&& solutionstep.xml) {
|
|
||||||
newTutorial.append(`steps[${i}][solutions][${solutionindex}][type]`, solutionstep.type);
|
|
||||||
newTutorial.append(`steps[${i}][solutions][${solutionindex}][headline]`, solutionstep.headline);
|
|
||||||
newTutorial.append(`steps[${i}][solutions][${solutionindex}][xml]`, solutionstep.xml);
|
|
||||||
solutionindex++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (step.xml) {
|
if (step.xml) {
|
||||||
// optional
|
// optional
|
||||||
newTutorial.append(`steps[${i}][xml]`, step.xml);
|
newTutorial.append(`steps[${i}][xml]`, step.xml);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (const pair of newTutorial.entries()) {
|
|
||||||
console.log(`${pair[0]}, ${pair[1]}`);
|
|
||||||
}
|
|
||||||
return newTutorial;
|
return newTutorial;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
import React, { Component } from "react";
|
|
||||||
import PropTypes from "prop-types";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { changeContent } from "../../../actions/tutorialBuilderActions";
|
|
||||||
|
|
||||||
import { withStyles } from "@material-ui/core/styles";
|
|
||||||
import Switch from "@material-ui/core/Switch";
|
|
||||||
import FormGroup from '@material-ui/core/FormGroup';
|
|
||||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
|
||||||
errorColor: {
|
|
||||||
color: theme.palette.error.dark,
|
|
||||||
},
|
|
||||||
errorBorder: {
|
|
||||||
border: `1px solid ${theme.palette.error.dark}`,
|
|
||||||
},
|
|
||||||
errorButton: {
|
|
||||||
marginTop: "5px",
|
|
||||||
height: "40px",
|
|
||||||
backgroundColor: theme.palette.error.dark,
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.error.dark,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
class FinalPageOptions extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
checkedSampleSolutions: props.checkedSampleSolutions,
|
|
||||||
checkedFurtherTutorials: props.checkedFurtherTutorials,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeSampleSolutions = (value) => {
|
|
||||||
var oldValue = this.state.checked;
|
|
||||||
this.setState({ checked: value });
|
|
||||||
if (oldValue !== value) {
|
|
||||||
this.props.changeContent(value, this.props.index, "samplesolutions");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onChangeFurtherTutorials = (value) => {
|
|
||||||
var oldValue = this.state.checked;
|
|
||||||
this.setState({ checked: value });
|
|
||||||
if (oldValue !== value) {
|
|
||||||
this.props.changeContent(value, this.props.index, "furthertutorials");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
var steps = this.props.steps;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
marginBottom: "10px",
|
|
||||||
padding: "18.5px 14px",
|
|
||||||
borderRadius: "25px",
|
|
||||||
border: "1px solid lightgrey",
|
|
||||||
width: "calc(100% - 28px)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormGroup>
|
|
||||||
<FormControlLabel
|
|
||||||
labelPlacement="end"
|
|
||||||
label={
|
|
||||||
"Musterlösung(en) der Aufgabe(n) auf der Abschlussseite anzeigen"
|
|
||||||
}
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={this.state.checked}
|
|
||||||
onChange={(e) => this.onChangeSampleSolutions(e.target.checked)}
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<FormControlLabel
|
|
||||||
labelPlacement="end"
|
|
||||||
label={
|
|
||||||
"Vorschläge für weitere Tutorials auf der Abschlussseite anzeigen"
|
|
||||||
}
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={this.state.checked}
|
|
||||||
onChange={(e) => this.onChangeFurtherTutorials(e.target.checked)}
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FinalPageOptions.propTypes = {
|
|
||||||
changeContent: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, {
|
|
||||||
changeContent,
|
|
||||||
})(withStyles(styles, { withTheme: true })(FinalPageOptions));
|
|
||||||
@@ -29,7 +29,6 @@ import {
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import MarkdownEditor from "./MarkdownEditor";
|
import MarkdownEditor from "./MarkdownEditor";
|
||||||
import FinalPageOptions from "./FinalPageOptions";
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
button: {
|
button: {
|
||||||
@@ -56,8 +55,6 @@ class Step extends Component {
|
|||||||
render() {
|
render() {
|
||||||
var index = this.props.index;
|
var index = this.props.index;
|
||||||
var steps = this.props.steps;
|
var steps = this.props.steps;
|
||||||
// console.log(this.props.steps);
|
|
||||||
// console.log(this.props.step);
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -67,21 +64,12 @@ class Step extends Component {
|
|||||||
marginBottom: "20px",
|
marginBottom: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{this.props.step.type !== "finalpage" ? (
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="h6"
|
variant="h6"
|
||||||
style={{ marginBottom: "10px", marginLeft: "4px" }}
|
style={{ marginBottom: "10px", marginLeft: "4px" }}
|
||||||
>
|
>
|
||||||
Schritt {index + 1}
|
Schritt {index + 1}
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
|
||||||
<Typography
|
|
||||||
variant="h6"
|
|
||||||
style={{ marginBottom: "10px", marginLeft: "4px" }}
|
|
||||||
>
|
|
||||||
Abschlussseite
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
<div style={{ display: "flex", position: "relative" }}>
|
<div style={{ display: "flex", position: "relative" }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -92,8 +80,6 @@ class Step extends Component {
|
|||||||
bottom: "10px",
|
bottom: "10px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{this.props.step.type !== "finalpage" ? (
|
|
||||||
<div>
|
|
||||||
<Tooltip title="Schritt hinzufügen" arrow>
|
<Tooltip title="Schritt hinzufügen" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={this.props.classes.button}
|
className={this.props.classes.button}
|
||||||
@@ -123,7 +109,7 @@ class Step extends Component {
|
|||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={index >= this.props.steps.length - 2}
|
disabled={index === steps.length - 1}
|
||||||
className={this.props.classes.button}
|
className={this.props.classes.button}
|
||||||
style={{ marginBottom: "5px" }}
|
style={{ marginBottom: "5px" }}
|
||||||
onClick={() => this.props.changeStepIndex(index, index + 1)}
|
onClick={() => this.props.changeStepIndex(index, index + 1)}
|
||||||
@@ -133,7 +119,7 @@ class Step extends Component {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
|
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={index === 0 && index === steps.length - 1}
|
disabled={index === 0}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
this.props.classes.button,
|
this.props.classes.button,
|
||||||
this.props.classes.delete
|
this.props.classes.delete
|
||||||
@@ -146,12 +132,8 @@ class Step extends Component {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
<div style={{ width: "100%", marginLeft: "54px" }}>
|
<div style={{ width: "100%", marginLeft: "54px" }}>
|
||||||
{this.props.step.type !== "finalpage" ? (
|
|
||||||
<StepType value={this.props.step.type} index={index} />
|
<StepType value={this.props.step.type} index={index} />
|
||||||
) : null}
|
|
||||||
<Textfield
|
<Textfield
|
||||||
value={this.props.step.headline}
|
value={this.props.step.headline}
|
||||||
property={"headline"}
|
property={"headline"}
|
||||||
@@ -196,21 +178,12 @@ class Step extends Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{this.props.step.type !== "finalpage" ? (
|
|
||||||
<BlocklyExample
|
<BlocklyExample
|
||||||
value={this.props.step.xml}
|
value={this.props.step.xml}
|
||||||
index={index}
|
index={index}
|
||||||
task={this.props.step.type === "task"}
|
task={this.props.step.type === "task"}
|
||||||
error={this.props.error.steps[index].xml ? true : false}
|
error={this.props.error.steps[index].xml ? true : false}
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<FinalPageOptions
|
|
||||||
steps={steps}
|
|
||||||
checkedSampleSolutions={this.props.step.samplesolutions}
|
|
||||||
checkedFurtherTutorials={this.props.step.furthertutorials}
|
|
||||||
index={index}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,430 +0,0 @@
|
|||||||
import React, { Component } from "react";
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
import BlocklyWindow from "../Blockly/BlocklyWindow";
|
|
||||||
|
|
||||||
import clsx from "clsx";
|
|
||||||
import { alpha } from "@material-ui/core/styles";
|
|
||||||
import { withStyles } from "@material-ui/core/styles";
|
|
||||||
|
|
||||||
import {
|
|
||||||
faCheck,
|
|
||||||
faTimes,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import ReactStars from "react-rating-stars-component";
|
|
||||||
import Grid from "@material-ui/core/Grid";
|
|
||||||
import Typography from "@material-ui/core/Typography";
|
|
||||||
import Paper from "@material-ui/core/Paper";
|
|
||||||
import ReactMarkdown from "react-markdown";
|
|
||||||
import remarkGfm from "remark-gfm";
|
|
||||||
import remarkGemoji from "remark-gemoji";
|
|
||||||
import Dialog from "../Dialog";
|
|
||||||
import { IconButton } from "@material-ui/core";
|
|
||||||
import { clearMessages } from "../../actions/messageActions";
|
|
||||||
|
|
||||||
import * as Blockly from "blockly/core";
|
|
||||||
|
|
||||||
// import { getTutorials,
|
|
||||||
// tutorialProgress,
|
|
||||||
// resetTutorial
|
|
||||||
// } from "../../actions/tutorialActions";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
|
||||||
outerDiv: {
|
|
||||||
position: "absolute",
|
|
||||||
right: "-30px",
|
|
||||||
bottom: "-30px",
|
|
||||||
width: "160px",
|
|
||||||
height: "160px",
|
|
||||||
color: alpha(theme.palette.secondary.main, 0.6),
|
|
||||||
},
|
|
||||||
outerDivError: {
|
|
||||||
stroke: alpha(theme.palette.error.dark, 0.6),
|
|
||||||
color: alpha(theme.palette.error.dark, 0.6),
|
|
||||||
},
|
|
||||||
outerDivSuccess: {
|
|
||||||
stroke: alpha(theme.palette.primary.main, 0.6),
|
|
||||||
color: alpha(theme.palette.primary.main, 0.6),
|
|
||||||
},
|
|
||||||
outerDivOther: {
|
|
||||||
stroke: alpha(theme.palette.secondary.main, 0.6),
|
|
||||||
},
|
|
||||||
innerDiv: {
|
|
||||||
width: "inherit",
|
|
||||||
height: "inherit",
|
|
||||||
display: "table-cell",
|
|
||||||
verticalAlign: "middle",
|
|
||||||
textAlign: "center",
|
|
||||||
},
|
|
||||||
// button: {
|
|
||||||
// backgroundColor: theme.palette.primary.main,
|
|
||||||
// color: theme.palette.primary.contrastText,
|
|
||||||
// width: "40px",
|
|
||||||
// height: "40px",
|
|
||||||
// "&:hover": {
|
|
||||||
// backgroundColor: theme.palette.primary.main,
|
|
||||||
// color: theme.palette.primary.contrastText,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// link: {
|
|
||||||
// color: theme.palette.primary.main,
|
|
||||||
// textDecoration: "none",
|
|
||||||
// "&:hover": {
|
|
||||||
// color: theme.palette.primary.main,
|
|
||||||
// textDecoration: "underline",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
|
|
||||||
class FinalPage extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
open: false,
|
|
||||||
title: "",
|
|
||||||
content: "",
|
|
||||||
tutorials: [],
|
|
||||||
randomtutorials: [],
|
|
||||||
activeXML: "",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
if (this.props.step.furthertutorials === true) {
|
|
||||||
axios
|
|
||||||
.get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial`)
|
|
||||||
.then((res) => {
|
|
||||||
this.setState({ tutorials: res.data.tutorials });
|
|
||||||
this.setState({ randomtutorials: this.getRandomTutorials(this.state.tutorials, 3) });
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDialog = (solution) => {
|
|
||||||
console.log(solution)
|
|
||||||
if (this.state.open === true) {
|
|
||||||
this.setState({ open: !this.state.open, title: "", activeXML: "" });
|
|
||||||
} else if (this.state.open === false) {
|
|
||||||
this.setState({ open: !this.state.open, title: "Task - " + solution.headline, activeXML: solution.xml });
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
getRandomTutorials = (tutorials, n) => {
|
|
||||||
var length = tutorials.length;
|
|
||||||
var taken = new Array(length);
|
|
||||||
var result = new Array(n);
|
|
||||||
if (n > length)
|
|
||||||
throw new RangeError("getRandom: more elements taken than available");
|
|
||||||
while (n--) {
|
|
||||||
var x = Math.floor(Math.random() * length);
|
|
||||||
result[n] = tutorials[x in taken ? taken[x] : x];
|
|
||||||
taken[x] = --length in taken ? taken[length] : length;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// toggleDialog = (solution) => {
|
|
||||||
// this.setState({ open: !this.state.open });
|
|
||||||
// // if (solution) {
|
|
||||||
// // this.setState({ open: !this.state.open, activeSolution: solution });
|
|
||||||
// // } else {
|
|
||||||
// // this.setState({ open: !this.state.open, activeSolution: null });
|
|
||||||
// // }
|
|
||||||
// };
|
|
||||||
|
|
||||||
render() {
|
|
||||||
var step = this.props.step;
|
|
||||||
var tutorials = this.state.tutorials;
|
|
||||||
var randomtutorials = this.state.randomtutorials;
|
|
||||||
// var randomtutorials = this.getRandomTutorials(tutorials, 3);
|
|
||||||
// console.log(randomtutorials)
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Typography>
|
|
||||||
<ReactMarkdown
|
|
||||||
className={"tutorial"}
|
|
||||||
linkTarget={"_blank"}
|
|
||||||
skipHtml={false}
|
|
||||||
allowDangerousHtml={true}
|
|
||||||
remarkPlugins={[remarkGfm, remarkGemoji]}
|
|
||||||
>
|
|
||||||
{step.text}
|
|
||||||
</ReactMarkdown>
|
|
||||||
</Typography>
|
|
||||||
{step.media ? (
|
|
||||||
step.media.picture ? (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
marginBottom: "5px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={`${process.env.REACT_APP_BLOCKLY_API}/media/${step.media.picture.path}`}
|
|
||||||
alt=""
|
|
||||||
style={{ maxHeight: "40vH", maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : step.media.youtube ? (
|
|
||||||
/*16:9; width: 800px; height: width/16*9=450px*/
|
|
||||||
<div style={{ maxWidth: "800px", margin: "auto" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "relative",
|
|
||||||
height: 0,
|
|
||||||
paddingBottom: "calc(100% / 16 * 9)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<iframe
|
|
||||||
title={step.media.youtube}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
top: "0",
|
|
||||||
left: "0",
|
|
||||||
width: "100%",
|
|
||||||
maxWidth: "800px",
|
|
||||||
height: "100%",
|
|
||||||
maxHeight: "450px",
|
|
||||||
}}
|
|
||||||
src={`https://www.youtube.com/embed/${step.media.youtube}`}
|
|
||||||
frameBorder="0"
|
|
||||||
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
|
||||||
allowFullScreen
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null
|
|
||||||
) : null}
|
|
||||||
{step.samplesolutions === true ? (
|
|
||||||
<div>
|
|
||||||
<h2 style={{ justifyContent: "center" }}>Musterlösungen</h2>
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
spacing={2}
|
|
||||||
style={{ marginBottom: "5px", justifyContent: "space-evenly" }}
|
|
||||||
>
|
|
||||||
{step.solutions.map((solution) => {
|
|
||||||
return (
|
|
||||||
<Grid
|
|
||||||
item
|
|
||||||
xs={12}
|
|
||||||
sm={6}
|
|
||||||
md={4}
|
|
||||||
xl={3}
|
|
||||||
style={{ display: "flex", justifyContent: "center" }}
|
|
||||||
// onclick={this.toggleDialog(solution)}
|
|
||||||
>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => this.toggleDialog(solution)}
|
|
||||||
>
|
|
||||||
<Paper
|
|
||||||
style={{
|
|
||||||
padding: "10px",
|
|
||||||
position: "relative",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h3>{"Task - " + solution.headline}</h3>
|
|
||||||
<BlocklyWindow
|
|
||||||
svg
|
|
||||||
blockDisabled
|
|
||||||
initialXml={solution.xml}
|
|
||||||
/>
|
|
||||||
</Paper>
|
|
||||||
</IconButton>
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Dialog
|
|
||||||
open={this.state.open}
|
|
||||||
onClose={this.toggleDialog}
|
|
||||||
onClick={this.toggleDialog}
|
|
||||||
title={this.state.title}
|
|
||||||
button={Blockly.Msg.button_close}
|
|
||||||
>
|
|
||||||
<BlocklyWindow
|
|
||||||
svg
|
|
||||||
blockDisabled
|
|
||||||
initialXml={this.state.activeXML}
|
|
||||||
/>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{step.furthertutorials === true ? (
|
|
||||||
<div>
|
|
||||||
<h2 style={{ justifyContent: "center" }}>Weitere Tutorials</h2>
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
spacing={2}
|
|
||||||
style={{ justifyContent: "space-evenly" }}
|
|
||||||
>
|
|
||||||
{randomtutorials.map((tutorial, i) => {
|
|
||||||
var status = this.props.status.filter(
|
|
||||||
(status) => status._id === tutorial._id
|
|
||||||
)[0];
|
|
||||||
var tasks = status.tasks;
|
|
||||||
var error =
|
|
||||||
status.tasks.filter((task) => task.type === "error").length > 0;
|
|
||||||
var success =
|
|
||||||
status.tasks.filter((task) => task.type === "success").length /
|
|
||||||
tasks.length;
|
|
||||||
var tutorialStatus =
|
|
||||||
success === 1 ? "Success" : error ? "Error" : "Other";
|
|
||||||
const firstExample = {
|
|
||||||
size: 30,
|
|
||||||
value: tutorial.difficulty,
|
|
||||||
edit: false,
|
|
||||||
isHalf: true,
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Grid item xs={12} sm={6} md={4} xl={3} key={i} style={{}}>
|
|
||||||
<Link
|
|
||||||
to={`/tutorial/${tutorial._id}`}
|
|
||||||
style={{ textDecoration: "none", color: "inherit" }}
|
|
||||||
>
|
|
||||||
<Paper
|
|
||||||
style={{
|
|
||||||
height: "150px",
|
|
||||||
padding: "10px",
|
|
||||||
position: "relative",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{tutorial.title}
|
|
||||||
<ReactStars {...firstExample} />
|
|
||||||
<div
|
|
||||||
className={clsx(this.props.classes.outerDiv)}
|
|
||||||
style={{ width: "160px", height: "160px", border: 0 }}
|
|
||||||
>
|
|
||||||
<svg style={{ width: "100%", height: "100%" }}>
|
|
||||||
{error || success === 1 ? (
|
|
||||||
<circle
|
|
||||||
className={
|
|
||||||
error
|
|
||||||
? this.props.classes.outerDivError
|
|
||||||
: this.props.classes.outerDivSuccess
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
transform: "rotate(-44deg)",
|
|
||||||
transformOrigin: "50% 50%",
|
|
||||||
}}
|
|
||||||
r="75"
|
|
||||||
cx="50%"
|
|
||||||
cy="50%"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="10"
|
|
||||||
></circle>
|
|
||||||
) : (
|
|
||||||
<circle
|
|
||||||
className={this.props.classes.outerDivOther}
|
|
||||||
style={{
|
|
||||||
transform: "rotate(-44deg)",
|
|
||||||
transformOrigin: "50% 50%",
|
|
||||||
}}
|
|
||||||
r="75"
|
|
||||||
cx="50%"
|
|
||||||
cy="50%"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="10"
|
|
||||||
stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
|
||||||
}`}
|
|
||||||
stroke-dasharray={`${75 * 2 * Math.PI * (1 - (50 / 100 - success / 2))
|
|
||||||
} ${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
|
||||||
}`}
|
|
||||||
></circle>
|
|
||||||
)}
|
|
||||||
{success < 1 && !error ? (
|
|
||||||
<circle
|
|
||||||
className={this.props.classes.outerDivSuccess}
|
|
||||||
style={{
|
|
||||||
transform: "rotate(-44deg)",
|
|
||||||
transformOrigin: "50% 50%",
|
|
||||||
}}
|
|
||||||
r="75"
|
|
||||||
cx="50%"
|
|
||||||
cy="50%"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="10"
|
|
||||||
stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
|
||||||
}`}
|
|
||||||
stroke-dasharray={`${75 * 2 * Math.PI}`}
|
|
||||||
></circle>
|
|
||||||
) : null}
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={clsx(
|
|
||||||
this.props.classes.outerDiv,
|
|
||||||
tutorialStatus === "Error"
|
|
||||||
? this.props.classes.outerDivError
|
|
||||||
: tutorialStatus === "Success"
|
|
||||||
? this.props.classes.outerDivSuccess
|
|
||||||
: null
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className={this.props.classes.innerDiv}>
|
|
||||||
{error || success === 1 ? (
|
|
||||||
<FontAwesomeIcon
|
|
||||||
size="4x"
|
|
||||||
icon={
|
|
||||||
tutorialStatus === "Success" ? faCheck : faTimes
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Typography
|
|
||||||
variant="h3"
|
|
||||||
className={
|
|
||||||
success > 0
|
|
||||||
? this.props.classes.outerDivSuccess
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{Math.round(success * 100)}%
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Paper>
|
|
||||||
</Link>
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Grid>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
tutorials: state.tutorial.tutorials,
|
|
||||||
status: state.tutorial.status,
|
|
||||||
isLoading: state.tutorial.progress,
|
|
||||||
message: state.message,
|
|
||||||
progress: state.auth.progress,
|
|
||||||
user: state.auth.user,
|
|
||||||
authProgress: state.auth.progress,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, {
|
|
||||||
// getTutorials,
|
|
||||||
// resetTutorial,
|
|
||||||
// tutorialProgress,
|
|
||||||
clearMessages,
|
|
||||||
})(withStyles(styles, { withTheme: true })(FinalPage));
|
|
||||||
@@ -31,9 +31,6 @@ const styles = (theme) => ({
|
|||||||
width: "24px",
|
width: "24px",
|
||||||
height: "24px",
|
height: "24px",
|
||||||
},
|
},
|
||||||
stepIconSuccess: {
|
|
||||||
borderColor: theme.palette.primary.main,
|
|
||||||
},
|
|
||||||
stepIconLargeSuccess: {
|
stepIconLargeSuccess: {
|
||||||
borderColor: theme.palette.primary.main,
|
borderColor: theme.palette.primary.main,
|
||||||
},
|
},
|
||||||
@@ -133,25 +130,12 @@ class StepperVertical extends Component {
|
|||||||
"stepIconLarge" + taskStatus
|
"stepIconLarge" + taskStatus
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
: step.type === "instruction"
|
: i === activeStep
|
||||||
? i === activeStep
|
|
||||||
? clsx(
|
? clsx(
|
||||||
this.props.classes.stepIcon,
|
this.props.classes.stepIcon,
|
||||||
this.props.classes.stepIconActiveOther
|
this.props.classes.stepIconActiveOther
|
||||||
)
|
)
|
||||||
: clsx(this.props.classes.stepIcon)
|
: clsx(this.props.classes.stepIcon),
|
||||||
: step.type === "finalpage"
|
|
||||||
? i === activeStep
|
|
||||||
? clsx(
|
|
||||||
this.props.classes.stepIcon,
|
|
||||||
this.props.classes.stepIconSuccess,
|
|
||||||
this.props.classes.stepIconActiveSuccess
|
|
||||||
)
|
|
||||||
: clsx(
|
|
||||||
this.props.classes.stepIcon,
|
|
||||||
this.props.classes.stepIconSuccess
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
}}
|
}}
|
||||||
></StepLabel>
|
></StepLabel>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import StepperHorizontal from "./StepperHorizontal";
|
|||||||
import StepperVertical from "./StepperVertical";
|
import StepperVertical from "./StepperVertical";
|
||||||
import Instruction from "./Instruction";
|
import Instruction from "./Instruction";
|
||||||
import Assessment from "./Assessment";
|
import Assessment from "./Assessment";
|
||||||
import FinalPage from "./FinalPage";
|
|
||||||
import NotFound from "../NotFound";
|
import NotFound from "../NotFound";
|
||||||
import * as Blockly from "blockly";
|
import * as Blockly from "blockly";
|
||||||
import { detectWhitespacesAndReturnReadableResult } from "../../helpers/whitespace";
|
import { detectWhitespacesAndReturnReadableResult } from "../../helpers/whitespace";
|
||||||
@@ -75,9 +74,7 @@ class Tutorial extends Component {
|
|||||||
(() => {
|
(() => {
|
||||||
var tutorial = this.props.tutorial;
|
var tutorial = this.props.tutorial;
|
||||||
var steps = this.props.tutorial.steps;
|
var steps = this.props.tutorial.steps;
|
||||||
console.log(steps)
|
|
||||||
var step = steps[this.props.activeStep];
|
var step = steps[this.props.activeStep];
|
||||||
console.log(step)
|
|
||||||
var name = `${detectWhitespacesAndReturnReadableResult(
|
var name = `${detectWhitespacesAndReturnReadableResult(
|
||||||
tutorial.title
|
tutorial.title
|
||||||
)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`;
|
)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`;
|
||||||
@@ -110,10 +107,8 @@ class Tutorial extends Component {
|
|||||||
{step ? (
|
{step ? (
|
||||||
step.type === "instruction" ? (
|
step.type === "instruction" ? (
|
||||||
<Instruction step={step} />
|
<Instruction step={step} />
|
||||||
) : step.type === "task" ? (
|
|
||||||
<Assessment step={step} name={name} />
|
|
||||||
) : (
|
) : (
|
||||||
<FinalPage step={step} />
|
<Assessment step={step} name={name} />
|
||||||
) // if step.type === 'assessment'
|
) // if step.type === 'assessment'
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import Tooltip from "@material-ui/core/Tooltip";
|
|||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import Snackbar from "../Snackbar";
|
import Snackbar from "../Snackbar";
|
||||||
import Divider from "@material-ui/core/Divider";
|
import Divider from "@material-ui/core/Divider";
|
||||||
import DeviceSelection from "../DeviceSelection";
|
|
||||||
|
|
||||||
const styles = (theme) => ({
|
const styles = (theme) => ({
|
||||||
outerDiv: {
|
outerDiv: {
|
||||||
@@ -244,10 +243,13 @@ class TutorialHome extends Component {
|
|||||||
cy="50%"
|
cy="50%"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="10"
|
stroke-width="10"
|
||||||
stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
stroke-dashoffset={`${
|
||||||
|
75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
||||||
}`}
|
}`}
|
||||||
stroke-dasharray={`${75 * 2 * Math.PI * (1 - (50 / 100 - success / 2))
|
stroke-dasharray={`${
|
||||||
} ${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
75 * 2 * Math.PI * (1 - (50 / 100 - success / 2))
|
||||||
|
} ${
|
||||||
|
75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
||||||
}`}
|
}`}
|
||||||
></circle>
|
></circle>
|
||||||
)}
|
)}
|
||||||
@@ -263,7 +265,8 @@ class TutorialHome extends Component {
|
|||||||
cy="50%"
|
cy="50%"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="10"
|
stroke-width="10"
|
||||||
stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
stroke-dashoffset={`${
|
||||||
|
75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
|
||||||
}`}
|
}`}
|
||||||
stroke-dasharray={`${75 * 2 * Math.PI}`}
|
stroke-dasharray={`${75 * 2 * Math.PI}`}
|
||||||
></circle>
|
></circle>
|
||||||
@@ -308,7 +311,6 @@ class TutorialHome extends Component {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Grid>
|
</Grid>
|
||||||
<DeviceSelection />
|
|
||||||
{this.props.user ? (
|
{this.props.user ? (
|
||||||
<div>
|
<div>
|
||||||
<h2>User Tutorials</h2>
|
<h2>User Tutorials</h2>
|
||||||
|
|||||||
@@ -38,19 +38,6 @@ export class Login extends Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
if (this.props.message.id === "LOGIN_FAIL") {
|
|
||||||
this.setState({
|
|
||||||
email: "",
|
|
||||||
password: "",
|
|
||||||
snackbar: true,
|
|
||||||
key: Date.now(),
|
|
||||||
message: Blockly.Msg.messages_LOGIN_FAIL,
|
|
||||||
type: "error",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(props) {
|
componentDidUpdate(props) {
|
||||||
const { message } = this.props;
|
const { message } = this.props;
|
||||||
if (message !== props.message) {
|
if (message !== props.message) {
|
||||||
|
|||||||
@@ -4,12 +4,22 @@
|
|||||||
"name": "senseBox MCU",
|
"name": "senseBox MCU",
|
||||||
"src": "senseboxmcu.png",
|
"src": "senseboxmcu.png",
|
||||||
"url": "https://docs.sensebox.de/hardware/allgemein-sensebox-mcu/",
|
"url": "https://docs.sensebox.de/hardware/allgemein-sensebox-mcu/",
|
||||||
|
"category": "boards",
|
||||||
"description": "test"
|
"description": "test"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "senseboxmcumini",
|
||||||
|
"name": "senseBox MCU:mini",
|
||||||
|
"src": "senseboxmcumini.png",
|
||||||
|
"url": "https://docs.sensebox.de/hardware/allgemein-sensebox-mcu-mini/",
|
||||||
|
"category": "boards",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "breadboard",
|
"id": "breadboard",
|
||||||
"name": "Breadboard",
|
"name": "Breadboard",
|
||||||
"src": "breadboard.png",
|
"src": "breadboard.png",
|
||||||
|
"category": "misc",
|
||||||
"url": ""
|
"url": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,10 +66,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "feinstaub",
|
"id": "feinstaub",
|
||||||
"name": "Feinstaubsensor",
|
"name": "Feinstaubsensor (SDS011)",
|
||||||
"src": "feinstaub.png",
|
"src": "feinstaub.png",
|
||||||
"url": "https://docs.sensebox.de/hardware/sensoren-feinstaub/"
|
"url": "https://docs.sensebox.de/hardware/sensoren-feinstaub/"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "feinstaub-sps30",
|
||||||
|
"name": "Feinstaubsensor (SPS30)",
|
||||||
|
"src": "sps30.png",
|
||||||
|
"url": "https://docs.sensebox.de/hardware/sensoren-feinstaub/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "gps",
|
"id": "gps",
|
||||||
"name": "GPS-Modul",
|
"name": "GPS-Modul",
|
||||||
@@ -140,8 +156,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ds1820b",
|
"id": "ds1820b",
|
||||||
"name": "Wassertemperatur",
|
"name": "Wassertemperatur Sensor",
|
||||||
"src": "ws2818.png",
|
"src": "wassertemp.png",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "expander",
|
||||||
|
"name": "I2C Expander",
|
||||||
|
"src": "expander.png",
|
||||||
"url": ""
|
"url": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -162,6 +184,18 @@
|
|||||||
"src": "jst-jst.png",
|
"src": "jst-jst.png",
|
||||||
"url": ""
|
"url": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "jst-qwiic",
|
||||||
|
"name": "JST-QWIIC Kabel",
|
||||||
|
"src": "jst-qwiic.png",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "qwiic-qwiic",
|
||||||
|
"name": "QWIIC-QWICC Kabel",
|
||||||
|
"src": "qwiic-qwiic.png",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "jumperwire",
|
"id": "jumperwire",
|
||||||
"name": "Steckkabel",
|
"name": "Steckkabel",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 105 KiB |
@@ -15,13 +15,11 @@ const compareNumberOfBlocks = (originalBlocks, userBlocks) => {
|
|||||||
var blocks;
|
var blocks;
|
||||||
if(originalBlocks.length > userBlocks.length){
|
if(originalBlocks.length > userBlocks.length){
|
||||||
blocks = originalBlocks.length-userBlocks.length;
|
blocks = originalBlocks.length-userBlocks.length;
|
||||||
//return {text: `Es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} zu wenig verwendet.`, type: 'error'};
|
return {text: `Es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} zu wenig verwendet.`, type: 'error'};
|
||||||
return {text: `Du kannst deinen Programmcode kompilieren, aber es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} weniger verwendet als in der hinterlegten Lösung.`, type: 'success'};
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blocks = userBlocks.length-originalBlocks.length;
|
blocks = userBlocks.length-originalBlocks.length;
|
||||||
//return {text: `Es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} zu viel verwendet.`, type: 'error'};
|
return {text: `Es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} zu viel verwendet.`, type: 'error'};
|
||||||
return {text: `Du kannst deinen Programmcode kompilieren, aber es wurde${blocks === 1 ? '' : 'n'} ${blocks} Bl${blocks === 1 ? 'ock' : 'öcke'} mehr verwendet als in der hinterlegten Lösung.`, type: 'success'};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,12 +3,7 @@ import ReactDOM from "react-dom";
|
|||||||
import "./index.css";
|
import "./index.css";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
import store from "./store";
|
|
||||||
import { fetchSensors } from "./actions/sensorwikiActions";
|
|
||||||
|
|
||||||
store.dispatch(fetchSensors());
|
|
||||||
|
|
||||||
fetchSensors();
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
|||||||
@@ -1,20 +1,12 @@
|
|||||||
import { BOARD } from '../actions/types';
|
import { BOARD } from '../actions/types';
|
||||||
import mini_opacity from "../data/mini_opacity.png"
|
|
||||||
import mcu_opacity from "../data/mcu_opacity.png"
|
|
||||||
|
|
||||||
const initialValue = () => {
|
const initialValue = () => {
|
||||||
if (window.sessionStorage.getItem("board")) {
|
if (window.localStorage.getItem("board")) {
|
||||||
setBackgroundImage(window.sessionStorage.getItem("board"));
|
return window.localStorage.getItem("board");
|
||||||
return window.sessionStorage.getItem("board");
|
|
||||||
}
|
}
|
||||||
return null;
|
return "bla";
|
||||||
};
|
};
|
||||||
|
|
||||||
const setBackgroundImage = (board) => {
|
|
||||||
const root = document.querySelector(':root');
|
|
||||||
root.style.setProperty('--url', `url(${board === "mcu" ? mcu_opacity : mini_opacity})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
board: initialValue()
|
board: initialValue()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import generalReducer from './generalReducer';
|
|||||||
import projectReducer from './projectReducer';
|
import projectReducer from './projectReducer';
|
||||||
import messageReducer from './messageReducer';
|
import messageReducer from './messageReducer';
|
||||||
import authReducer from './authReducer';
|
import authReducer from './authReducer';
|
||||||
import boardReducer from './boardReducer';
|
import boardReducer from './boardReducer'
|
||||||
import sensorwikiReducer from './sensorwikiReducer';
|
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
@@ -17,6 +16,5 @@ export default combineReducers({
|
|||||||
builder: tutorialBuilderReducer,
|
builder: tutorialBuilderReducer,
|
||||||
project: projectReducer,
|
project: projectReducer,
|
||||||
general: generalReducer,
|
general: generalReducer,
|
||||||
message: messageReducer,
|
message: messageReducer
|
||||||
sensorwiki: sensorwikiReducer
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
const sensors = (state = [] , action) => {
|
|
||||||
switch(action.type) {
|
|
||||||
case 'FETCH_SENSORWIKI_SUCCESS':
|
|
||||||
return action.payload.sensors
|
|
||||||
default:
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default sensors
|
|
||||||
@@ -33,18 +33,9 @@ const initialState = {
|
|||||||
hardware: [],
|
hardware: [],
|
||||||
requirements: [],
|
requirements: [],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
type: "finalpage",
|
|
||||||
headline: "",
|
|
||||||
text: "",
|
|
||||||
samplesolutions: false,
|
|
||||||
solutions: [],
|
|
||||||
furthertutorials: false,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
error: {
|
error: {
|
||||||
steps: [{},{}],
|
steps: [{}],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||