Compare commits

..
Author SHA1 Message Date
fab-scm fd6358ea2b implement FinalPage 2023-01-21 17:48:07 +01:00
fab-scm 912440f64c added Tutorial Builder FinalPage 2022-11-24 11:45:58 +01:00
Mario PeschandGitHub 77b338ffb6 Merge pull request #203 from sensebox/development-featSensorWiki
sensorwiki with tabs and only one request
2022-11-16 12:19:54 +01:00
Mario Pesch 8571f0430f Merge branch 'development-featSensorWiki' of https://github.com/sensebox/React-Ardublockly into development-featSensorWiki 2022-11-16 12:07:44 +01:00
Mario Pesch 1bfe1a26ba change to coming soon... 2022-11-16 12:07:35 +01:00
Mario PeschandGitHub 564dcc4d4a Merge branch 'development' into development-featSensorWiki 2022-11-16 12:04:05 +01:00
Mario PeschandGitHub 50b70b4ee3 Merge pull request #216 from sensebox/development-deviceSelection
Development device selection
2022-11-16 11:56:38 +01:00
Mario PeschandGitHub 00310a49dc Merge pull request #201 from sensebox/development-tutorialSolution
disable solution block length check
2022-11-16 11:48:40 +01:00
fbruc03 ec1eea110c fix baground mcu image 2022-11-16 11:44:16 +01:00
fbruc03 22d11773e9 save current board in session storage 2022-11-15 16:54:09 +01:00
fbruc03 2de54c0e9b rewrite board check 2022-11-15 16:30:13 +01:00
fbruc03 5974608fd8 add DeviceSelection to CodeEditor,Project+Tutorial 2022-11-15 16:22:29 +01:00
fbruc03 6fcaff9cc3 save board model to localstorage 2022-11-15 16:11:35 +01:00
fbruc03 f95b1b36ca fix faq video 2022-11-11 12:21:13 +01:00
fbruc03 a31195f71e fix german variable translations 2022-11-09 17:05:51 +01:00
fbruc03 506ddef7e9 solve login snackbar issue 2022-11-09 15:41:26 +01:00
fbruc03 9ac98aa06d change block data to json 2022-11-09 11:20:15 +01:00
fbruc03 a8704316ac sensorwiki with tabs and only one request 2022-11-08 15:59:09 +01:00
fbruc03 c950dbbd86 disable solution block length check 2022-11-07 10:33:45 +01:00
Mario PeschandGitHub e00617ac78 Merge pull request #198 from sensebox/dev/update-deviceSelector
update device Selector
2022-11-04 15:50:40 +01:00
Mario Pesch d61d0cc5c4 update device Selector 2022-11-03 20:04:39 +01:00
65 changed files with 1133 additions and 839 deletions
-38
View File
@@ -1,38 +0,0 @@
---
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.
-20
View File
@@ -1,20 +0,0 @@
---
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.
-14
View File
@@ -1,14 +0,0 @@
---
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
+2
View File
@@ -14,6 +14,7 @@
"@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",
@@ -41,6 +42,7 @@
"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",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 777 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

+10
View File
@@ -62,3 +62,13 @@ 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;
}
+12 -7
View File
@@ -1,10 +1,15 @@
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) => {
dispatch({ window.sessionStorage.setItem("board", board);
type: BOARD, const root = document.querySelector(':root');
payload: board, root.style.setProperty('--url', `url(${board === "mcu" ? mcu_opacity : mini_opacity})`);
}); dispatch({
}; type: BOARD,
payload: board,
});
};
+18
View File
@@ -0,0 +1,18 @@
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)
}
}
}
+10 -1
View File
@@ -301,12 +301,21 @@ 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: [{}, {}],
}, },
}); });
}; };
+6
View File
@@ -20,9 +20,15 @@ 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
} }
-1
View File
@@ -10,7 +10,6 @@ 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";
@@ -1,42 +0,0 @@
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,7 +19,6 @@ 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()
@@ -54,10 +53,6 @@ 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,67 +76,3 @@ 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,6 +26,7 @@ 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"};
}, },
}; };
@@ -51,6 +52,7 @@ 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"};
}, },
}; };
@@ -91,6 +93,7 @@ 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"};
}, },
}; };
@@ -115,13 +118,14 @@ 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().serialSensors), selectedBoard().serial),
"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"};
}, },
}; };
@@ -155,6 +159,7 @@ 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");
@@ -186,7 +191,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_bme_pressure, "pressure"], [Blockly.Msg.senseBox_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"],
@@ -201,6 +206,7 @@ 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"};
}, },
}; };
@@ -245,6 +251,7 @@ 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.
@@ -382,6 +389,7 @@ 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");
@@ -448,6 +456,7 @@ 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"};
}, },
}; };
@@ -470,6 +479,7 @@ 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"};
}, },
}; };
@@ -542,6 +552,7 @@ 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");
@@ -562,31 +573,3 @@ 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);
},
};
+3 -3
View File
@@ -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("set", "set") .appendField(Blockly.Msg.variables_set, Blockly.Msg.variables_set)
.appendField("", "type") // .appendField("", "type")
.appendField(new Blockly.FieldVariable("VAR"), "VAR") .appendField(new Blockly.FieldVariable("VAR"), "VAR")
.appendField("to"); .appendField(Blockly.Msg.variables_to);
}, },
onchange: function (e) { onchange: function (e) {
let variableID = this.getFieldValue("VAR"); let variableID = this.getFieldValue("VAR");
@@ -10,7 +10,6 @@ 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";
+4 -9
View File
@@ -275,15 +275,10 @@ Blockly.Arduino["math_change"] = function (block) {
"DELTA", "DELTA",
Blockly.Arduino.ORDER_ADDITIVE Blockly.Arduino.ORDER_ADDITIVE
) || "0"; ) || "0";
var id = block.getFieldValue("VAR") var varName = Blockly.Arduino.nameDB_.getName(
const varName = Blockly.Variables.getVariable( block.getFieldValue("VAR"),
Blockly.getMainWorkspace(), Blockly.Variables.NAME_TYPE
id );
).name;
// var varName = Blockly.Arduino.nameDB_.getName(
// block.getFieldValue("VAR"),
// Blockly.Variables.NAME_TYPE
// );
return varName + " += " + argument0 + ";\n"; return varName + " += " + argument0 + ";\n";
}; };
@@ -1,19 +0,0 @@
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,8 +30,6 @@ 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");
@@ -52,7 +50,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.${host}";`; 'const char server [] PROGMEM ="ingress.opensensemap.org";';
if (wifi === true) { if (wifi === true) {
if (ssl === "TRUE") { if (ssl === "TRUE") {
Blockly.Arduino.libraries_["library_bearSSL"] = Blockly.Arduino.libraries_["library_bearSSL"] =
@@ -156,7 +154,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}\\nX-Allow-Token: ${ratelimit_token}\\nHost: %s\\nContent-Type: " PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_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:
@@ -255,7 +253,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}\\nX-Allow-Token: ${ratelimit_token}\\nHost: %s\\nContent-Type: " PSTR("POST /boxes/%s/data HTTP/1.1\\nAuthorization: ${access_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,46 +94,3 @@ 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];
};
@@ -429,13 +429,11 @@ Blockly.Arduino.sensebox_scd30 = function () {
"#include <SparkFun_SCD30_Arduino_Library.h> // http://librarymanager/All#SparkFun_SCD30_Arduino_Library"; "#include <SparkFun_SCD30_Arduino_Library.h> // http://librarymanager/All#SparkFun_SCD30_Arduino_Library";
Blockly.Arduino.definitions_["SCD30"] = "SCD30 airSensor;"; Blockly.Arduino.definitions_["SCD30"] = "SCD30 airSensor;";
Blockly.Arduino.setupCode_["init_scd30"] = ` Wire.begin(); Blockly.Arduino.setupCode_["init_scd30"] = ` Wire.begin();
if (airSensor.begin() == false) if (airSensor.begin() == false)
{ {
while (1) while (1)
; ;
}`; }`;
Blockly.Arduino.setupCode_["scd30_staleData"] =
"airSensor.useStaleData(true);";
var code = ""; var code = "";
switch (dropdown) { switch (dropdown) {
case "temperature": case "temperature":
@@ -694,57 +692,3 @@ 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];
};
+5 -12
View File
@@ -46,13 +46,9 @@ const sensebox_mcu = {
["C6", "6"], ["C6", "6"],
], ],
serial: [ serial: [
["SerialUSB", "SerialUSB"], ["serial", "SerialUSB"],
["Serial1", "Serial1"], ["serial_1", "Serial1"],
["Serial2", "Serial2"], ["serial_2", "Serial2"],
],
serialSensors: [
["Serial1", "Serial1"],
["Serial2", "Serial2"],
], ],
serialPins: { serialPins: {
SerialUSB: [ SerialUSB: [
@@ -165,11 +161,8 @@ const sensebox_mini = {
["IO2", "2"], ["IO2", "2"],
], ],
serial: [ serial: [
["SerialUSB", "SerialUSB"], ["serial", "SerialUSB"],
["Serial1", "Serial1"], ["serial_1", "Serial1"],
],
serialSensors: [
["Serial1", "Serial1"],
], ],
serialPins: { serialPins: {
SerialUSB: [ SerialUSB: [
+19 -31
View File
@@ -1,6 +1,6 @@
/** /**
* @license * @license
* *
* Copyright 2019 Google LLC * Copyright 2019 Google LLC
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,51 +21,39 @@
* @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;
const Block = (p) => { const Block = (p) => {
const { children, ...props } = p; const { children, ...props } = p;
props.is = "blockly"; props.is = "blockly";
return React.createElement("block", props, children); return React.createElement("block", props, children);
}; };
const Category = (p) => { const Category = (p) => {
const { children, ...props } = p; const { children, ...props } = p;
props.is = "blockly"; props.is = "blockly";
return React.createElement("category", props, children); return React.createElement("category", props, children);
}; };
const Value = (p) => { const Value = (p) => {
const { children, ...props } = p; const { children, ...props } = p;
props.is = "blockly"; props.is = "blockly";
return React.createElement("value", props, children); return React.createElement("value", props, children);
}; };
const Field = (p) => { const Field = (p) => {
const { children, ...props } = p; const { children, ...props } = p;
props.is = "blockly"; props.is = "blockly";
return React.createElement("field", props, children); return React.createElement("field", props, children);
}; };
const Shadow = (p) => { const Shadow = (p) => {
const { children, ...props } = p; const { children, ...props } = p;
props.is = "blockly"; props.is = "blockly";
return React.createElement("shadow", props, children); return React.createElement("shadow", props, children);
}; };
const Sep = (p) => { export { Block, Category, Value, Field, Shadow }
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 };
-2
View File
@@ -12,7 +12,6 @@ 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";
@@ -41,7 +40,6 @@ export const De = {
...LORA, ...LORA,
...OSEM, ...OSEM,
...RTC, ...RTC,
...NTP,
...SD, ...SD,
...SENSORS, ...SENSORS,
...SENSEBOX, ...SENSEBOX,
@@ -1,11 +0,0 @@
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,12 +10,11 @@ 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_testing: "testing.opensensemap.org", senseBox_osem_host_workshop: "workshop.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:
+4 -22
View File
@@ -1,14 +1,14 @@
export const RTC = { export const RTC = {
sensebox_rtc_init: "Initialisiere externe RTC", sensebox_rtc_init: "Initialisiere 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 externen RTC", sensebox_rtc_set: "Setze Uhrzeit/Datum der 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 externe RTC (RFC 3339)", sensebox_rtc_get_timestamp: "Zeitstempel (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 (externe RTC): ", sensebox_rtc_get: "Wert: ",
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,22 +16,4 @@ 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,7 +140,6 @@ 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:
@@ -176,7 +175,7 @@ Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt ver
* Feinstaubsensor (SDS011) * Feinstaubsensor (SDS011)
*/ */
senseBox_sds011: "Feinstaubsensor SDS011", senseBox_sds011: "Feinstaubsensor",
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",
@@ -201,23 +200,4 @@ 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/",
};
+15 -7
View File
@@ -8,25 +8,23 @@ 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: "char (char)", variables_CHARACTER: "Buchstabe (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
@@ -154,6 +152,7 @@ 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",
/** /**
* *
@@ -313,8 +312,17 @@ export const UI = {
* Device Selction * Device Selction
* */ * */
deviceselection_head: "Welches Board benutzt du?", deviceselection_head: "Welches Board benutzt du?",
deviceselection_keep_selection: deviceselection_keep_selection: "Speichere meine Auswahl fürs nächste Mal (Du kannst das Board später in den Einstellungen wechseln)",
"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 "
}; };
-2
View File
@@ -13,7 +13,6 @@ 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";
@@ -41,7 +40,6 @@ export const En = {
...LORA, ...LORA,
...OSEM, ...OSEM,
...RTC, ...RTC,
...NTP,
...SD, ...SD,
...SENSORS, ...SENSORS,
...SENSEBOX, ...SENSEBOX,
@@ -1,10 +0,0 @@
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,12 +11,11 @@ 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_testing: "testing.opensensemap.org", senseBox_osem_host_workshop: "workshop.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?",
+2 -20
View File
@@ -1,11 +1,11 @@
export const RTC = { export const RTC = {
sensebox_rtc_init: "Initialise external RTC", sensebox_rtc_init: "Initialise 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: "Timestamp external RTC (RFC 3339)", sensebox_rtc_get_timestamp: "Get timestamp",
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,22 +17,4 @@ 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,7 +141,6 @@ 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.
@@ -206,23 +205,4 @@ 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/",
}; };
+19 -12
View File
@@ -8,25 +8,23 @@ 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: " Zahl (long)", variable_LONG: "Big number (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: "char (char)", variables_CHARACTER: "Character (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
@@ -149,6 +147,7 @@ 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",
/** /**
* *
@@ -305,12 +304,20 @@ export const UI = {
"Your code will now be compiled and then downloaded to your computer", "Your code will now be compiled and then downloaded to your computer",
/** /**
* Device Selction * Device Selction
* */ * */
deviceselection_head: "Which board are you using?", deviceselection_head: "Which board are you using?",
deviceselection_keep_selection: deviceselection_keep_selection: "Save my choice (You can change the board later in the settings)",
"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:
"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 ",
}; };
+51 -76
View File
@@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { Block, Value, Field, Shadow, Category, Sep, Label } from "../"; import { Block, Value, Field, Shadow, Category } 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,7 +16,6 @@ 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"],
@@ -33,7 +32,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", "Create Typed Variable"); button.setAttribute("text", Blockly.Msg.button_createVariable);
button.setAttribute("callbackKey", "callbackName"); button.setAttribute("callbackKey", "callbackName");
xmlList.push(button); xmlList.push(button);
@@ -41,6 +40,7 @@ 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,7 +61,6 @@ 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" />
@@ -296,7 +295,7 @@ class Toolbox extends React.Component {
</Value> </Value>
</Block> </Block>
</Category> </Category>
{/* <Category name="Telegram" colour={getColour().sensebox}> {/* <Category name="Telegram" colour={getColour().sensebox}>
<Block type="sensebox_telegram" /> <Block type="sensebox_telegram" />
<Block type="sensebox_telegram_do" /> <Block type="sensebox_telegram_do" />
@@ -503,63 +502,42 @@ 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 <Block type="sensebox_rtc_init"></Block>
id="time" <Block type="sensebox_rtc_set">
name={Blockly.Msg.toolbox_rtc} <Value name="second">
colour={getColour().time} <Block type="math_number">
> <Field name="NUM">00</Field>
<Label text={Blockly.Msg.toolbox_label_externalRTC}></Label> </Block>
<Block type="sensebox_rtc_init"></Block> </Value>
<Block type="sensebox_rtc_set"> <Value name="minutes">
<Value name="second"> <Block type="math_number">
<Block type="math_number"> <Field name="NUM">00</Field>
<Field name="NUM">00</Field> </Block>
</Block> </Value>
</Value> <Value name="hour">
<Value name="minutes"> <Block type="math_number">
<Block type="math_number"> <Field name="NUM">00</Field>
<Field name="NUM">00</Field> </Block>
</Block> </Value>
</Value> <Value name="day">
<Value name="hour"> <Block type="math_number">
<Block type="math_number"> <Field name="NUM">01</Field>
<Field name="NUM">00</Field> </Block>
</Block> </Value>
</Value> <Value name="month">
<Value name="day"> <Block type="math_number">
<Block type="math_number"> <Field name="NUM">01</Field>
<Field name="NUM">01</Field> </Block>
</Block> </Value>
</Value> <Value name="year">
<Value name="month"> <Block type="math_number">
<Block type="math_number"> <Field name="NUM">1970</Field>
<Field name="NUM">01</Field> </Block>
</Block> </Value>
</Value> </Block>
<Value name="year"> {/* <Block type="sensebox_rtc_set_ntp"></Block> */}
<Block type="math_number"> <Block type="sensebox_rtc_get"></Block>
<Field name="NUM">1970</Field> <Block type="sensebox_rtc_get_timestamp"></Block>
</Block>
</Value>
</Block>
{/* <Block type="sensebox_rtc_set_ntp"></Block> */}
<Block type="sensebox_rtc_get"></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"
@@ -665,19 +643,16 @@ class Toolbox extends React.Component {
</Value> </Value>
</Block> </Block>
</Category> </Category>
<Category <Category name={Blockly.Msg.toolbox_motors} colour={getColour().motors}>
name={Blockly.Msg.toolbox_motors} <Block type="sensebox_motors_beginServoMotor" />
colour={getColour().motors} <Block type="sensebox_motors_moveServoMotor">
> <Value name="degrees">
<Block type="sensebox_motors_beginServoMotor" /> <Block type="math_number">
<Block type="sensebox_motors_moveServoMotor"> <Field name="NUM">90</Field>
<Value name="degrees"> </Block>
<Block type="math_number"> </Value>
<Field name="NUM">90</Field> </Block>
</Block> {/* <Block type="sensebox_motors_I2CMotorBoard_begin" />
</Value>
</Block>
{/* <Block type="sensebox_motors_I2CMotorBoard_begin" />
<Block type="sensebox_motors_I2CMotorBoard_moveDCMotor"> <Block type="sensebox_motors_I2CMotorBoard_moveDCMotor">
<Value name="speed"> <Value name="speed">
<Block type="math_number"> <Block type="math_number">
@@ -694,7 +669,7 @@ class Toolbox extends React.Component {
</Block> </Block>
</Value> </Value>
</Block> */} </Block> */}
</Category> </Category>
<Category name="Watchdog" colour={getColour().io}> <Category name="Watchdog" colour={getColour().io}>
<Block type="watchdog_enable"></Block> <Block type="watchdog_enable"></Block>
<Block type="watchdog_reset"></Block> <Block type="watchdog_reset"></Block>
+2
View File
@@ -11,6 +11,7 @@ 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();
@@ -192,6 +193,7 @@ 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" }}
+30 -59
View File
@@ -4,8 +4,6 @@ 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";
@@ -27,41 +25,31 @@ 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: userWantToKeepBoard open: props.selectedBoard ? false : true,
? !userWantToKeepBoard selectedBoard: "",
: previousPageWasAnotherDomain,
selectedBoard : "",
saveSettings: false, saveSettings: false,
}; };
} }
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) => {
if (e.target.checked) { if (e.target.checked) {
this.setState({ saveSettings: true}); this.setState({ saveSettings: true });
} else { } else {
this.setState({ saveSettings: false}); this.setState({ saveSettings: false });
} }
}; };
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() {
@@ -74,26 +62,24 @@ 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>
<Grid container spacing={2} style={{ textAlign : "center" }}> <Grid container spacing={2} style={{ textAlign: "center" }}>
<Grid item xs={6}> <Grid item xs={6}>
<IconButton onClick={(e) => this.onclick(e, "mcu")}> <IconButton onClick={(e) => this.onclick(e, "mcu")}>
<Avatar <Avatar
alt="Sensebox MCU" alt="Sensebox MCU"
src="/media/hardware/senseboxmcu.png" src="/media/hardware/senseboxmcu.png"
style={{ style={{
border: this.state.selectedBoard === "mcu" ? 'medium solid DeepSkyBlue': "0.1px solid lightgray", border: this.state.selectedBoard === "mcu" ? 'medium solid DeepSkyBlue' : "0.1px solid lightgray",
width:"20vw", width: "20vw",
height: "20vw" height: "20vw"
}} }}
/> />
</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
@@ -103,42 +89,27 @@ class DeviceSeclection extends Component {
border: this.state.selectedBoard == "esp" ? 'medium solid DeepSkyBlue': "0.1px solid lightgray", border: this.state.selectedBoard == "esp" ? 'medium solid DeepSkyBlue': "0.1px solid lightgray",
width:"20vw", width:"20vw",
height: "20vw" height: "20vw"
}} }}
/> />
</IconButton> </IconButton>
<p>Sensebox ESP</p> <p>Sensebox ESP</p>
</Grid> */} </Grid> */}
<Grid item xs={6}> <Grid item xs={6}>
<IconButton onClick={(e) => this.onclick(e, "mini")}> <IconButton onClick={(e) => this.onclick(e, "mini")}>
<Avatar <Avatar
alt="Sensebox Mini" alt="Sensebox Mini"
src="/media/hardware/senseboxmcumini.png" src="/media/hardware/senseboxmcumini.png"
style={{ style={{
border: this.state.selectedBoard === "mini" ? 'medium solid DeepSkyBlue': "0.1px solid lightgray", border: this.state.selectedBoard === "mini" ? 'medium solid DeepSkyBlue' : "0.1px solid lightgray",
width:"20vw", width: "20vw",
height: "20vw" height: "20vw"
}} }}
/> />
</IconButton> </IconButton>
<p>senseBox MCU:mini</p> <p>senseBox MCU:mini</p>
</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>
@@ -158,5 +129,5 @@ const mapStateToProps = (state) => ({
export default connect( export default connect(
mapStateToProps, mapStateToProps,
{setBoard} { setBoard }
)(withStyles(styles, { withTheme: true })(DeviceSeclection)); )(withStyles(styles, { withTheme: true })(DeviceSeclection));
+2
View File
@@ -8,6 +8,7 @@ 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";
@@ -61,6 +62,7 @@ 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>
+7 -7
View File
@@ -18,6 +18,7 @@ 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: {
@@ -60,9 +61,8 @@ class ProjectHome extends Component {
this.setState({ this.setState({
snackbar: true, snackbar: true,
key: Date.now(), key: Date.now(),
message: `Dein angefragtes ${ message: `Dein angefragtes ${type === "gallery" ? "Galerie-" : ""
type === "gallery" ? "Galerie-" : "" }Projekt konnte nicht gefunden werden.`,
}Projekt konnte nicht gefunden werden.`,
type: "error", type: "error",
}); });
} }
@@ -108,6 +108,7 @@ 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" />
@@ -127,9 +128,8 @@ class ProjectHome extends Component {
}} }}
> >
<Link <Link
to={`/${ to={`/${data === "Projekte" ? "project" : "gallery"
data === "Projekte" ? "project" : "gallery" }/${project._id}`}
}/${project._id}`}
style={{ textDecoration: "none", color: "inherit" }} style={{ textDecoration: "none", color: "inherit" }}
> >
<h3 style={{ marginTop: 0 }}>{project.title}</h3> <h3 style={{ marginTop: 0 }}>{project.title}</h3>
@@ -153,7 +153,7 @@ class ProjectHome extends Component {
</Typography> </Typography>
</Link> </Link>
{this.props.user && {this.props.user &&
this.props.user.email === project.creator ? ( this.props.user.email === project.creator ? (
<div> <div>
<Divider <Divider
style={{ style={{
+2 -26
View File
@@ -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, setPlatform } from "../../actions/generalActions"; import { visitPage } from "../../actions/generalActions";
import { Route, Switch, withRouter } from "react-router-dom"; import { Route, Switch, withRouter } from "react-router-dom";
@@ -27,24 +27,6 @@ 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();
} }
@@ -123,12 +105,6 @@ class Routes extends Component {
Home.propTypes = { Home.propTypes = {
visitPage: PropTypes.func, visitPage: PropTypes.func,
platform: PropTypes.bool.isRequired,
setPlatform: PropTypes.func.isRequired
}; };
const mapStateToProps = (state) => ({ export default connect(null, { visitPage })(withRouter(Routes));
platform: state.general.platform,
});
export default connect(mapStateToProps, { visitPage, setPlatform })(withRouter(Routes));
+77
View File
@@ -0,0 +1,77 @@
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>
);
}
+67 -11
View File
@@ -1,17 +1,41 @@
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
@@ -29,14 +53,46 @@ class TooltipViewer extends Component {
{Blockly.Msg.tooltip_viewer} {Blockly.Msg.tooltip_viewer}
</Typography> </Typography>
<ReactMarkdown linkTarget="_blank"> <Typography variant="body2" component="p">
{this.props.tooltip} <ReactMarkdown linkTarget="_blank">
</ReactMarkdown> {this.props.tooltip}
</ReactMarkdown>
{this.props.helpurl !== "" ? ( {store.getState().workspace.code.data ? (
<ReactMarkdown>{`${Blockly.Msg.tooltip_moreInformation} [${Blockly.Msg.labels_here}](${this.props.helpurl})`}</ReactMarkdown> <Button
) : null} 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>
)}
</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>
); );
} }
+22 -1
View File
@@ -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,6 +273,8 @@ 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);
@@ -299,11 +301,30 @@ 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;
} }
}; };
@@ -0,0 +1,107 @@
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));
+83 -56
View File
@@ -29,6 +29,7 @@ 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: {
@@ -55,6 +56,8 @@ 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={{
@@ -64,12 +67,21 @@ class Step extends Component {
marginBottom: "20px", marginBottom: "20px",
}} }}
> >
<Typography {this.props.step.type !== "finalpage" ? (
variant="h6" <Typography
style={{ marginBottom: "10px", marginLeft: "4px" }} variant="h6"
> style={{ marginBottom: "10px", marginLeft: "4px" }}
Schritt {index + 1} >
</Typography> Schritt {index + 1}
</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={{
@@ -80,60 +92,66 @@ class Step extends Component {
bottom: "10px", bottom: "10px",
}} }}
> >
<Tooltip title="Schritt hinzufügen" arrow> {this.props.step.type !== "finalpage" ? (
<IconButton
className={this.props.classes.button}
style={index === 0 ? {} : { marginBottom: "5px" }}
onClick={() => this.props.addStep(index + 1)}
>
<FontAwesomeIcon icon={faPlus} size="xs" />
</IconButton>
</Tooltip>
{index !== 0 ? (
<div> <div>
<Tooltip <Tooltip title="Schritt hinzufügen" arrow>
title={`Schritt ${index + 1} nach oben schieben`}
arrow
>
<IconButton <IconButton
disabled={index < 2}
className={this.props.classes.button} className={this.props.classes.button}
style={{ marginBottom: "5px" }} style={index === 0 ? {} : { marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index - 1)} onClick={() => this.props.addStep(index + 1)}
> >
<FontAwesomeIcon icon={faAngleDoubleUp} size="xs" /> <FontAwesomeIcon icon={faPlus} size="xs" />
</IconButton>
</Tooltip>
<Tooltip
title={`Schritt ${index + 1} nach unten schieben`}
arrow
>
<IconButton
disabled={index === steps.length - 1}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index + 1)}
>
<FontAwesomeIcon icon={faAngleDoubleDown} size="xs" />
</IconButton>
</Tooltip>
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
<IconButton
disabled={index === 0}
className={clsx(
this.props.classes.button,
this.props.classes.delete
)}
onClick={() => this.props.removeStep(index)}
>
<FontAwesomeIcon icon={faTrash} size="xs" />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
{index !== 0 ? (
<div>
<Tooltip
title={`Schritt ${index + 1} nach oben schieben`}
arrow
>
<IconButton
disabled={index < 2}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index - 1)}
>
<FontAwesomeIcon icon={faAngleDoubleUp} size="xs" />
</IconButton>
</Tooltip>
<Tooltip
title={`Schritt ${index + 1} nach unten schieben`}
arrow
>
<IconButton
disabled={index >= this.props.steps.length - 2}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index + 1)}
>
<FontAwesomeIcon icon={faAngleDoubleDown} size="xs" />
</IconButton>
</Tooltip>
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
<IconButton
disabled={index === 0 && index === steps.length - 1}
className={clsx(
this.props.classes.button,
this.props.classes.delete
)}
onClick={() => this.props.removeStep(index)}
>
<FontAwesomeIcon icon={faTrash} size="xs" />
</IconButton>
</Tooltip>
</div>
) : null}
</div> </div>
) : null} ) : null}
</div> </div>
<div style={{ width: "100%", marginLeft: "54px" }}> <div style={{ width: "100%", marginLeft: "54px" }}>
<StepType value={this.props.step.type} index={index} /> {this.props.step.type !== "finalpage" ? (
<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"}
@@ -178,12 +196,21 @@ class Step extends Component {
/> />
</div> </div>
) : null} ) : null}
<BlocklyExample {this.props.step.type !== "finalpage" ? (
value={this.props.step.xml} <BlocklyExample
index={index} value={this.props.step.xml}
task={this.props.step.type === "task"} index={index}
error={this.props.error.steps[index].xml ? true : false} task={this.props.step.type === "task"}
/> 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>
+430
View File
@@ -0,0 +1,430 @@
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));
+22 -6
View File
@@ -31,6 +31,9 @@ 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,
}, },
@@ -130,12 +133,25 @@ class StepperVertical extends Component {
"stepIconLarge" + taskStatus "stepIconLarge" + taskStatus
] ]
) )
: i === activeStep : step.type === "instruction"
? clsx( ? i === activeStep
this.props.classes.stepIcon, ? clsx(
this.props.classes.stepIconActiveOther this.props.classes.stepIcon,
) 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>
+6 -1
View File
@@ -17,6 +17,7 @@ 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";
@@ -74,7 +75,9 @@ 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)}`;
@@ -107,8 +110,10 @@ 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} /> <Assessment step={step} name={name} />
) : (
<FinalPage step={step} />
) // if step.type === 'assessment' ) // if step.type === 'assessment'
) : null} ) : null}
+11 -13
View File
@@ -37,6 +37,7 @@ 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: {
@@ -243,14 +244,11 @@ class TutorialHome extends Component {
cy="50%" cy="50%"
fill="none" fill="none"
stroke-width="10" stroke-width="10"
stroke-dashoffset={`${ stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
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>
)} )}
{success < 1 && !error ? ( {success < 1 && !error ? (
@@ -265,9 +263,8 @@ class TutorialHome extends Component {
cy="50%" cy="50%"
fill="none" fill="none"
stroke-width="10" stroke-width="10"
stroke-dashoffset={`${ stroke-dashoffset={`${75 * 2 * Math.PI * (1 - (50 / 100 + success / 2))
75 * 2 * Math.PI * (1 - (50 / 100 + success / 2)) }`}
}`}
stroke-dasharray={`${75 * 2 * Math.PI}`} stroke-dasharray={`${75 * 2 * Math.PI}`}
></circle> ></circle>
) : null} ) : null}
@@ -279,8 +276,8 @@ class TutorialHome extends Component {
tutorialStatus === "Error" tutorialStatus === "Error"
? this.props.classes.outerDivError ? this.props.classes.outerDivError
: tutorialStatus === "Success" : tutorialStatus === "Success"
? this.props.classes.outerDivSuccess ? this.props.classes.outerDivSuccess
: null : null
)} )}
> >
<div className={this.props.classes.innerDiv}> <div className={this.props.classes.innerDiv}>
@@ -311,6 +308,7 @@ class TutorialHome extends Component {
); );
})} })}
</Grid> </Grid>
<DeviceSelection />
{this.props.user ? ( {this.props.user ? (
<div> <div>
<h2>User Tutorials</h2> <h2>User Tutorials</h2>
+13
View File
@@ -38,6 +38,19 @@ 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) {
+3 -37
View File
@@ -4,22 +4,12 @@
"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": ""
}, },
{ {
@@ -66,16 +56,10 @@
}, },
{ {
"id": "feinstaub", "id": "feinstaub",
"name": "Feinstaubsensor (SDS011)", "name": "Feinstaubsensor",
"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",
@@ -156,14 +140,8 @@
}, },
{ {
"id": "ds1820b", "id": "ds1820b",
"name": "Wassertemperatur Sensor", "name": "Wassertemperatur",
"src": "wassertemp.png", "src": "ws2818.png",
"url": ""
},
{
"id": "expander",
"name": "I2C Expander",
"src": "expander.png",
"url": "" "url": ""
}, },
{ {
@@ -184,18 +162,6 @@
"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",
Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

+4 -2
View File
@@ -15,11 +15,13 @@ 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'};
} }
} }
}; };
+5
View File
@@ -3,7 +3,12 @@ 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>
+11 -3
View File
@@ -1,12 +1,20 @@
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.localStorage.getItem("board")) { if (window.sessionStorage.getItem("board")) {
return window.localStorage.getItem("board"); setBackgroundImage(window.sessionStorage.getItem("board"));
return window.sessionStorage.getItem("board");
} }
return "bla"; return null;
}; };
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()
}; };
+4 -2
View File
@@ -6,7 +6,8 @@ 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,
@@ -16,5 +17,6 @@ export default combineReducers({
builder: tutorialBuilderReducer, builder: tutorialBuilderReducer,
project: projectReducer, project: projectReducer,
general: generalReducer, general: generalReducer,
message: messageReducer message: messageReducer,
sensorwiki: sensorwikiReducer
}); });
+10
View File
@@ -0,0 +1,10 @@
const sensors = (state = [] , action) => {
switch(action.type) {
case 'FETCH_SENSORWIKI_SUCCESS':
return action.payload.sensors
default:
return state
}
}
export default sensors
+10 -1
View File
@@ -33,9 +33,18 @@ const initialState = {
hardware: [], hardware: [],
requirements: [], requirements: [],
}, },
{
id: 2,
type: "finalpage",
headline: "",
text: "",
samplesolutions: false,
solutions: [],
furthertutorials: false,
},
], ],
error: { error: {
steps: [{}], steps: [{},{}],
}, },
}; };