Merge branch 'master' into development
This commit is contained in:
commit
ade6f3d4bd
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
14
.github/ISSUE_TEMPLATE/short-issue.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/short-issue.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Short Issue
|
||||
about: Template for Short Issues
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Current behaviour
|
||||
Describe the current behaviour
|
||||
|
||||
### Expected behaviour
|
||||
Describe how it is supposed to work
|
BIN
public/media/hardware/expander.png
Normal file
BIN
public/media/hardware/expander.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
BIN
public/media/hardware/jst-qwiic.png
Normal file
BIN
public/media/hardware/jst-qwiic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 777 KiB |
BIN
public/media/hardware/qwiic-qwiic.png
Normal file
BIN
public/media/hardware/qwiic-qwiic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 728 KiB |
BIN
public/media/hardware/sps30.png
Normal file
BIN
public/media/hardware/sps30.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
BIN
public/media/hardware/wassertemp.png
Normal file
BIN
public/media/hardware/wassertemp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
@ -10,6 +10,7 @@ import "./sensebox-motors";
|
||||
import "./sensebox-lora";
|
||||
import "./sensebox-led";
|
||||
import "./sensebox-rtc";
|
||||
import "./sensebox-ntp";
|
||||
import "./sensebox-ble";
|
||||
import "./sensebox-sd";
|
||||
import "./mqtt";
|
||||
|
42
src/components/Blockly/blocks/sensebox-ntp.js
Normal file
42
src/components/Blockly/blocks/sensebox-ntp.js
Normal file
@ -0,0 +1,42 @@
|
||||
import * as Blockly from "blockly";
|
||||
import { getColour } from "../helpers/colour";
|
||||
import * as Types from "../helpers/types";
|
||||
|
||||
Blockly.Blocks["sensebox_ntp_init"] = {
|
||||
init: function () {
|
||||
this.setHelpUrl(Blockly.Msg.sensebox_ntp_helpurl);
|
||||
this.setColour(getColour().time);
|
||||
this.appendDummyInput().appendField(Blockly.Msg.sensebox_ntp_init);
|
||||
this.setPreviousStatement(true);
|
||||
this.setNextStatement(true);
|
||||
this.setTooltip(Blockly.Msg.sensebox_ntp_tooltip);
|
||||
},
|
||||
};
|
||||
|
||||
Blockly.Blocks["sensebox_ntp_get"] = {
|
||||
init: function () {
|
||||
this.setHelpUrl(Blockly.Msg.sensebox_ntp_get_helpurl);
|
||||
this.setColour(getColour().time);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.sensebox_ntp_get)
|
||||
.appendField(
|
||||
new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.sensebox_ntp_epochTime, "getEpochTime"],
|
||||
[Blockly.Msg.sensebox_ntp_formattedTimeStamp, "getFormattedTime"],
|
||||
]),
|
||||
"dropdown"
|
||||
);
|
||||
this.setOutput(true, Types.LARGE_NUMBER.typeName);
|
||||
this.setTooltip(Blockly.Msg.sensebox_rtc_get_tooltip);
|
||||
},
|
||||
};
|
||||
|
||||
Blockly.Blocks["sensebox_ntp_get_timestamp"] = {
|
||||
init: function () {
|
||||
this.setHelpUrl(Blockly.Msg.sensebox_rtc_helpurl);
|
||||
this.setColour(getColour().time);
|
||||
this.appendDummyInput().appendField(Blockly.Msg.sensebox_rtc_get_timestamp);
|
||||
this.setOutput(true);
|
||||
this.setTooltip(Blockly.Msg.sensebox_rtc_get_timestamp_tooltip);
|
||||
},
|
||||
};
|
@ -76,3 +76,67 @@ Blockly.Blocks["sensebox_rtc_get_timestamp"] = {
|
||||
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);
|
||||
},
|
||||
};
|
||||
|
@ -118,7 +118,7 @@ Blockly.Blocks["sensebox_sensor_sds011"] = {
|
||||
.appendField(Blockly.Msg.senseBox_sds011_dimension)
|
||||
.appendField(
|
||||
new Blockly.FieldDropdown(
|
||||
selectedBoard().serial),
|
||||
selectedBoard().serialSensors),
|
||||
"SERIAL"
|
||||
);
|
||||
this.setOutput(true, Types.DECIMAL.typeName);
|
||||
@ -191,7 +191,7 @@ Blockly.Blocks["sensebox_sensor_bme680_bsec"] = {
|
||||
var dropdownOptions = [
|
||||
[Blockly.Msg.senseBox_temp, "temperature"],
|
||||
[Blockly.Msg.senseBox_hum, "humidity"],
|
||||
[Blockly.Msg.senseBox_pressure, "pressure"],
|
||||
[Blockly.Msg.senseBox_bme_pressure, "pressure"],
|
||||
[Blockly.Msg.senseBox_bme_iaq, "IAQ"],
|
||||
[Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"],
|
||||
[Blockly.Msg.senseBox_bme_co2, "CO2"],
|
||||
@ -573,3 +573,31 @@ Blockly.Blocks["sensebox_sensor_dps310"] = {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Sensirion SPS30 Fine Particular Matter Sensor
|
||||
* added 02.12.2022
|
||||
*/
|
||||
|
||||
Blockly.Blocks["sensebox_sensor_sps30"] = {
|
||||
init: function () {
|
||||
this.appendDummyInput().appendField(Blockly.Msg.senseBox_sps30);
|
||||
this.appendDummyInput()
|
||||
.setAlign(Blockly.ALIGN_LEFT)
|
||||
.appendField(Blockly.Msg.senseBox_value)
|
||||
.appendField(
|
||||
new Blockly.FieldDropdown([
|
||||
[Blockly.Msg.senseBox_sps30_1p0, "1p0"],
|
||||
[Blockly.Msg.senseBox_sps30_2p5, "2p5"],
|
||||
[Blockly.Msg.senseBox_sps30_4p0, "4p0"],
|
||||
[Blockly.Msg.senseBox_sps30_10p0, "10p0"],
|
||||
]),
|
||||
"value"
|
||||
)
|
||||
.appendField(Blockly.Msg.senseBox_sps30_dimension);
|
||||
this.setOutput(true, Types.DECIMAL.typeName);
|
||||
this.setColour(getColour().sensebox);
|
||||
this.setTooltip(Blockly.Msg.senseBox_sps30_tooltip);
|
||||
this.setHelpUrl(Blockly.Msg.senseBox_sps30_helpurl);
|
||||
},
|
||||
};
|
@ -10,6 +10,7 @@ import "./sensebox-lora";
|
||||
import "./sensebox-led";
|
||||
import "./sensebox";
|
||||
import "./sensebox-rtc";
|
||||
import "./sensebox-ntp";
|
||||
import "./sensebox-ble";
|
||||
import "./sensebox-sd";
|
||||
import "./mqtt";
|
||||
|
@ -275,10 +275,15 @@ Blockly.Arduino["math_change"] = function (block) {
|
||||
"DELTA",
|
||||
Blockly.Arduino.ORDER_ADDITIVE
|
||||
) || "0";
|
||||
var varName = Blockly.Arduino.nameDB_.getName(
|
||||
block.getFieldValue("VAR"),
|
||||
Blockly.Variables.NAME_TYPE
|
||||
);
|
||||
var id = block.getFieldValue("VAR")
|
||||
const varName = Blockly.Variables.getVariable(
|
||||
Blockly.getMainWorkspace(),
|
||||
id
|
||||
).name;
|
||||
// var varName = Blockly.Arduino.nameDB_.getName(
|
||||
// block.getFieldValue("VAR"),
|
||||
// Blockly.Variables.NAME_TYPE
|
||||
// );
|
||||
return varName + " += " + argument0 + ";\n";
|
||||
};
|
||||
|
||||
|
19
src/components/Blockly/generator/sensebox-ntp.js
Normal file
19
src/components/Blockly/generator/sensebox-ntp.js
Normal file
@ -0,0 +1,19 @@
|
||||
import Blockly from "blockly";
|
||||
|
||||
Blockly.Arduino.sensebox_ntp_init = function () {
|
||||
Blockly.Arduino.libraries_["WiFiUdp"] = `#include <WiFiUdp.h>`;
|
||||
Blockly.Arduino.libraries_["NTPClient"] = `#include <NTPClient.h>`;
|
||||
Blockly.Arduino.definitions_["WiFiUDP"] = `WiFiUDP ntpUDP;`;
|
||||
Blockly.Arduino.definitions_["NTPClient"] = `NTPClient timeClient(ntpUDP);`;
|
||||
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||
Blockly.Arduino.setupCode_["timeclient.begin"] = `timeClient.begin();`;
|
||||
Blockly.Arduino.setupCode_["timeclient.update"] = `timeClient.update();`;
|
||||
var code = ``;
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Arduino.sensebox_ntp_get = function () {
|
||||
var format = this.getFieldValue("dropdown");
|
||||
var code = `timeClient.${format}()`;
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
@ -94,3 +94,46 @@ uint8_t sec, min, hour, day, month;
|
||||
var code = `getTimeStamp()`;
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Arduino.sensebox_internal_rtc_init = function () {
|
||||
Blockly.Arduino.libraries_["RTClib"] = `#include <RTCZero.h>`;
|
||||
Blockly.Arduino.definitions_["RTC"] = `RTCZero rtc;`;
|
||||
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||
Blockly.Arduino.setupCode_["rtc.begin"] = `rtc.begin();`;
|
||||
return "";
|
||||
};
|
||||
|
||||
Blockly.Arduino.sensebox_internal_rtc_set = function () {
|
||||
var branch =
|
||||
Blockly.Arduino.valueToCode(this, "time", Blockly.Arduino.ORDER_ATOMIC) ||
|
||||
"0";
|
||||
Blockly.Arduino.setupCode_["rtc.setEpoch"] = `rtc.setEpoch(${branch});`;
|
||||
var code = ``;
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Arduino.sensebox_internal_rtc_get = function () {
|
||||
var dropdown = this.getFieldValue("dropdown");
|
||||
var code = `rtc.get${dropdown}()`;
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Arduino.sensebox_internal_rtc_get_timestamp = function () {
|
||||
Blockly.Arduino.variables_["rtc_timestamp"] = `char timestamp[20];`;
|
||||
Blockly.Arduino.codeFunctions_["getTimeStamp"] = `
|
||||
char* getTimeStamp() {
|
||||
uint8_t sec, min, hour, day, month;
|
||||
uint16_t year;
|
||||
sec = rtc.getSeconds();
|
||||
min = rtc.getMinutes();
|
||||
hour = rtc.getHours();
|
||||
day = rtc.getDay();
|
||||
month = rtc.getMonth();
|
||||
year = rtc.getYear();
|
||||
sprintf(timestamp, "%02d-%02d-%02dT%02d:%02d:%02dZ", year, month, day, hour, min, sec);
|
||||
return timestamp;
|
||||
}
|
||||
`;
|
||||
var code = `getTimeStamp()`;
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
@ -434,6 +434,8 @@ Blockly.Arduino.sensebox_scd30 = function () {
|
||||
while (1)
|
||||
;
|
||||
}`;
|
||||
Blockly.Arduino.setupCode_["scd30_staleData"] =
|
||||
"airSensor.useStaleData(true);";
|
||||
var code = "";
|
||||
switch (dropdown) {
|
||||
case "temperature":
|
||||
@ -692,3 +694,57 @@ Blockly.Arduino.sensebox_sensor_dps310 = function () {
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
/**
|
||||
* Sensirion SPS30 Fine Particlar Matter
|
||||
*
|
||||
*/
|
||||
|
||||
Blockly.Arduino.sensebox_sensor_sps30 = function () {
|
||||
var dropdown_name = this.getFieldValue("value");
|
||||
Blockly.Arduino.libraries_["library_senseBoxIO"] = "#include <senseBoxIO.h>";
|
||||
Blockly.Arduino.libraries_[
|
||||
"sps30"
|
||||
] = `#include <sps30.h> // http://librarymanager/All#`;
|
||||
Blockly.Arduino.variables_["sps30_measurement"] =
|
||||
"struct sps30_measurement m;";
|
||||
Blockly.Arduino.variables_["sps30_auto_clean_days"] =
|
||||
"uint32_t auto_clean_days = 4;";
|
||||
Blockly.Arduino.variables_["sps30_interval_intervalsps"] =
|
||||
"const long intervalsps = 1000;";
|
||||
Blockly.Arduino.variables_["sps30_time_startsps"] =
|
||||
"unsigned long time_startsps = 0;";
|
||||
Blockly.Arduino.variables_["sps30_time_actualsps"] =
|
||||
"unsigned long time_actualsps = 0;";
|
||||
Blockly.Arduino.codeFunctions_["sps30_getData"] = `
|
||||
void getSPS30Data(){
|
||||
|
||||
uint16_t data_ready;
|
||||
int16_t ret;
|
||||
|
||||
do {
|
||||
ret = sps30_read_data_ready(&data_ready);
|
||||
if (ret < 0) {
|
||||
} else if (!data_ready) {}
|
||||
else
|
||||
break;
|
||||
delay(100); /* retry in 100ms */
|
||||
} while (1);
|
||||
ret = sps30_read_measurement(&m);
|
||||
}
|
||||
`;
|
||||
|
||||
Blockly.Arduino.setupCode_["sps30_begin"] = "sensirion_i2c_init();";
|
||||
Blockly.Arduino.setupCode_["sps30_setFanCleaningInterval"] =
|
||||
"sps30_set_fan_auto_cleaning_interval_days(auto_clean_days);";
|
||||
Blockly.Arduino.setupCode_["sps30_startMeasurement"] =
|
||||
"sps30_start_measurement();";
|
||||
Blockly.Arduino.loopCodeOnce_["getSPS30Data();"] = `
|
||||
time_startsps = millis();
|
||||
if (time_startsps > time_actualsps + intervalsps) {
|
||||
time_actualsps = millis();
|
||||
getSPS30Data();
|
||||
}`;
|
||||
var code = `m.mc_${dropdown_name}`;
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
@ -46,9 +46,13 @@ const sensebox_mcu = {
|
||||
["C6", "6"],
|
||||
],
|
||||
serial: [
|
||||
["serial", "SerialUSB"],
|
||||
["serial_1", "Serial1"],
|
||||
["serial_2", "Serial2"],
|
||||
["SerialUSB", "SerialUSB"],
|
||||
["Serial1", "Serial1"],
|
||||
["Serial2", "Serial2"],
|
||||
],
|
||||
serialSensors: [
|
||||
["Serial1", "Serial1"],
|
||||
["Serial2", "Serial2"],
|
||||
],
|
||||
serialPins: {
|
||||
SerialUSB: [
|
||||
@ -161,8 +165,11 @@ const sensebox_mini = {
|
||||
["IO2", "2"],
|
||||
],
|
||||
serial: [
|
||||
["serial", "SerialUSB"],
|
||||
["serial_1", "Serial1"],
|
||||
["SerialUSB", "SerialUSB"],
|
||||
["Serial1", "Serial1"],
|
||||
],
|
||||
serialSensors: [
|
||||
["Serial1", "Serial1"],
|
||||
],
|
||||
serialPins: {
|
||||
SerialUSB: [
|
||||
|
@ -21,8 +21,8 @@
|
||||
* @author samelh@google.com (Sam El-Husseini)
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import BlocklyComponent from './BlocklyComponent';
|
||||
import React from "react";
|
||||
import BlocklyComponent from "./BlocklyComponent";
|
||||
|
||||
export default BlocklyComponent;
|
||||
|
||||
@ -56,4 +56,16 @@ const Shadow = (p) => {
|
||||
return React.createElement("shadow", props, children);
|
||||
};
|
||||
|
||||
export { Block, Category, Value, Field, Shadow }
|
||||
const Sep = (p) => {
|
||||
const { children, ...props } = p;
|
||||
props.is = "blockly";
|
||||
return React.createElement("sep", props, children);
|
||||
};
|
||||
|
||||
const Label = (p) => {
|
||||
const { children, ...props } = p;
|
||||
props.is = "blockly";
|
||||
return React.createElement("label", props, children);
|
||||
};
|
||||
|
||||
export { Block, Category, Value, Field, Shadow, Sep, Label };
|
||||
|
@ -12,6 +12,7 @@ import { LED } from "./de/sensebox-led";
|
||||
import { LORA } from "./de/sensebox-lora";
|
||||
import { OSEM } from "./de/sensebox-osem";
|
||||
import { RTC } from "./de/sensebox-rtc";
|
||||
import { NTP } from "./de/sensebox-ntp";
|
||||
import { SD } from "./de/sensebox-sd";
|
||||
import { SENSORS } from "./de/sensebox-sensors";
|
||||
import { SENSEBOX } from "./de/sensebox";
|
||||
@ -40,6 +41,7 @@ export const De = {
|
||||
...LORA,
|
||||
...OSEM,
|
||||
...RTC,
|
||||
...NTP,
|
||||
...SD,
|
||||
...SENSORS,
|
||||
...SENSEBOX,
|
||||
|
11
src/components/Blockly/msg/de/sensebox-ntp.js
Normal file
11
src/components/Blockly/msg/de/sensebox-ntp.js
Normal file
@ -0,0 +1,11 @@
|
||||
export const NTP = {
|
||||
sensebox_ntp_init: "Initialisiere NTP",
|
||||
sensebox_ntp_init_tooltip: "Initialisiere den NTP Server.",
|
||||
sensebox_ntp_get: "Hole Zeit von NTP Server: ",
|
||||
sensebox_ntp_get_timestamp_tooltip:
|
||||
"Gibt dir einen in ISO 8601 formatierten Zeitstempel zurück. Bsp: 2021-12-24T18:21Z",
|
||||
sensebox_ntp_get_tooltip:
|
||||
"Gibt dir den ausgewählten Wert zurück. Unix Zeit entspricht der Anzahl der Sekunden seit dem 1.1.1970",
|
||||
sensebox_ntp_epochTime: "Unix Zeit",
|
||||
sensebox_ntp_formattedTimeStamp: "Zeitstempel (hh:mm:ss)",
|
||||
};
|
@ -1,14 +1,14 @@
|
||||
export const RTC = {
|
||||
sensebox_rtc_init: "Initialisiere RTC",
|
||||
sensebox_rtc_init: "Initialisiere externe RTC",
|
||||
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.",
|
||||
sensebox_rtc_set: "Setze Uhrzeit/Datum der RTC",
|
||||
sensebox_rtc_set: "Setze Uhrzeit/Datum der externen RTC",
|
||||
sensebox_rtc_set_tooltip:
|
||||
"Stellt die Uhrzeit der RTC ein. Beachte, dass du diesen Block im Setup ausführst.",
|
||||
sensebox_rtc_get_timestamp: "Zeitstempel (RFC 3339)",
|
||||
sensebox_rtc_get_timestamp: "Zeitstempel externe RTC (RFC 3339)",
|
||||
sensebox_rtc_get_timestamp_tooltip:
|
||||
"Gibt dir einen in ISO 8601 formatierten Zeitstempel zurück. Bsp: 2021-12-24T18:21Z",
|
||||
sensebox_rtc_get: "Wert: ",
|
||||
sensebox_rtc_get: "Wert (externe RTC): ",
|
||||
sensebox_rtc_get_tooltip: "Gibt dir den ausgewählten Wert zurück.",
|
||||
sensebox_rtc_second: "Sekunden",
|
||||
sensebox_rtc_minutes: "Minuten",
|
||||
@ -16,4 +16,22 @@ export const RTC = {
|
||||
sensebox_rtc_day: "Tag",
|
||||
sensebox_rtc_month: "Monat",
|
||||
sensebox_rtc_year: "Jahr",
|
||||
sensebox_internal_rtc_init: "Initialisiere interne RTC",
|
||||
sensebox_internal_rtc_init_tooltip:
|
||||
"Initialisieren der internen RTC. Diese RTC ist nicht batteriegepuffert und wird bei jedem Einschaltvorgang zurückgesetzt",
|
||||
sensebox_internal_rtc_set: "Setze interne RTC Zeit/Datum (Unix Time)",
|
||||
sensebox_internal_rtc_set_tooltip:
|
||||
"Setzt die Zeit der internen RTC. Führe den Block einmalig im Setup aus und setzte die Uhrzeit über die Unix Zeit.",
|
||||
sensebox_internal_rtc_get: "Wert (interne RTC): ",
|
||||
sensebox_internal_rtc_get_timestamp: "Zeitstempel interne RTC (RFC 3339)",
|
||||
sensebox_internal_rtc_get_timestamp_tooltip:
|
||||
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||
sensebox_internal_rtc_get_tooltip: "Gibt den ausgewählten Wert zurück",
|
||||
sensebox_internal_rtc_epoch: "Unix Zeit",
|
||||
sensebox_internal_rtc_year: "Jahr",
|
||||
sensebox_internal_rtc_month: "Monat",
|
||||
sensebox_internal_rtc_day: "Tag",
|
||||
sensebox_internal_rtc_hour: "Stunde",
|
||||
sensebox_internal_rtc_minutes: "Minute",
|
||||
sensebox_internal_rtc_seconds: "Sekunde",
|
||||
};
|
||||
|
@ -140,6 +140,7 @@ Wenn die maximale Distanz überschritten wird, wird ein Wert von **O** ausgegebe
|
||||
senseBox_bme_iaq: "Innenraumluftqualität (IAQ)",
|
||||
senseBox_bme_iaq_accuracy: "Kalibrierungswert",
|
||||
senseBox_bme_co2: "CO2 Äquivalent",
|
||||
senseBox_bme_pressure: "Luftdruck in Pa",
|
||||
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.
|
||||
Den Status der Kalibrierung kann über den Kalibrierungswert abgelesen werden. Er ist entweder 0, 1, 2 oder 3 und sagt folgendes aus:
|
||||
@ -175,7 +176,7 @@ Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt ver
|
||||
* Feinstaubsensor (SDS011)
|
||||
*/
|
||||
|
||||
senseBox_sds011: "Feinstaubsensor",
|
||||
senseBox_sds011: "Feinstaubsensor SDS011",
|
||||
senseBox_sds011_dimension: "in µg/m³ an",
|
||||
senseBox_sds011_pm25: "PM2.5",
|
||||
senseBox_sds011_pm10: "PM10",
|
||||
@ -200,4 +201,23 @@ Die Messwerte für Temperatur, Luftfeuchtigkeit und Luftdruck können direkt ver
|
||||
- "wurde gedrückt": Mit diesem Modus kannst du abfragen ob der Block gedrückt wurde. Erst wenn der Knopf gedrückt und wieder losgelassen wurde erhältst du TRUE zurück
|
||||
- "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: "",
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Feinstaubsensor Sensirion SPS30
|
||||
*/
|
||||
|
||||
senseBox_sps30: "Feinstaubsensor Sensirion SPS30",
|
||||
senseBox_sps30_dimension: "in µg/m³",
|
||||
senseBox_sps30_1p0: "PM1.0",
|
||||
senseBox_sps30_2p5: "PM2.5",
|
||||
senseBox_sps30_4p0: "PM4.0",
|
||||
senseBox_sps30_10p0: "PM10",
|
||||
senseBox_sps30_tooltip:"Dieser Block gibt dir den Messwert des Sensirion SPS30 Feinstaubsensor. Schließe den Feinstaubsensor an einen der 5 **I2C** Anschlüssen an. Im Dropdown Menü zwischen PM1.0, PM2.5, PM4.0 und PM10 auswählen. Der Messwert wird dir als **Kommazahl** in µg/m3",
|
||||
senseBox_sps30_helpurl:
|
||||
"https://docs.sensebox.de/hardware/sensoren-feinstaub/",
|
||||
|
||||
|
||||
|
||||
};
|
@ -8,11 +8,15 @@ export const UI = {
|
||||
toolbox_math: "Mathematik",
|
||||
toolbox_io: "Eingang/Ausgang",
|
||||
toolbox_time: "Zeit",
|
||||
toolbox_rtc: "RTC",
|
||||
toolbox_ntp: "NTP",
|
||||
toolbox_functions: "Funktionen",
|
||||
toolbox_variables: "Variablen",
|
||||
toolbox_serial: "Seriell",
|
||||
toolbox_advanced: "Erweitert",
|
||||
toolbox_motors: "Motoren",
|
||||
toolbox_label_externalRTC: "Externe RTC",
|
||||
toolbox_label_internalRTC: "Interne RTC",
|
||||
variable_NUMBER: "Zahl (int)",
|
||||
variable_SHORT_NUMBER: "char",
|
||||
variable_LONG: "große Zahl (long)",
|
||||
@ -312,7 +316,8 @@ export const UI = {
|
||||
* Device Selction
|
||||
* */
|
||||
deviceselection_head: "Welches Board benutzt du?",
|
||||
deviceselection_keep_selection: "Speichere meine Auswahl fürs nächste Mal (Du kannst das Board später in den Einstellungen wechseln)",
|
||||
deviceselection_keep_selection:
|
||||
"Speichere meine Auswahl fürs nächste Mal (Du kannst das Board später in den Einstellungen wechseln)",
|
||||
deviceselection_footnote: "Hier kommst du zur alten Blockly Version für den ",
|
||||
deviceselection_footnote_02: "oder die",
|
||||
|
||||
|
@ -13,6 +13,7 @@ import { LED } from "./en/sensebox-led";
|
||||
import { LORA } from "./en/sensebox-lora";
|
||||
import { OSEM } from "./en/sensebox-osem";
|
||||
import { RTC } from "./en/sensebox-rtc";
|
||||
import { NTP } from "./en/sensebox-ntp";
|
||||
import { SD } from "./en/sensebox-sd";
|
||||
import { SENSORS } from "./en/sensebox-sensors";
|
||||
import { TELEGRAM } from "./en/sensebox-telegram";
|
||||
@ -40,6 +41,7 @@ export const En = {
|
||||
...LORA,
|
||||
...OSEM,
|
||||
...RTC,
|
||||
...NTP,
|
||||
...SD,
|
||||
...SENSORS,
|
||||
...SENSEBOX,
|
||||
|
10
src/components/Blockly/msg/en/sensebox-ntp.js
Normal file
10
src/components/Blockly/msg/en/sensebox-ntp.js
Normal file
@ -0,0 +1,10 @@
|
||||
export const NTP = {
|
||||
sensebox_ntp_init: "Initialise NTP",
|
||||
sensebox_ntp_init_tooltip:
|
||||
"Initialisiere die RTC. Schließe diese an einen der 5 I2C/Wire Anschlüsse an und lege die Batterie ein. Bevor du die Uhrzeit auslesen kannst muss diese zunächst einmal gesetzt werden. Dieser Schritt muss normalerweise nur einmalig durchgeführt werden.",
|
||||
sensebox_ntp_get: "Get time from NTP Server: ",
|
||||
sensebox_ntp_get_tooltip:
|
||||
"Gibt dir den ausgewählten Wert zurück. Unix Zeit entspricht der Anzahl der Sekunden seit dem 1.1.1970",
|
||||
sensebox_ntp_epochTime: "Unix time",
|
||||
sensebox_ntp_formattedTimeStamp: "Timestamp (hh:mm:ss)",
|
||||
};
|
@ -1,11 +1,11 @@
|
||||
export const RTC = {
|
||||
sensebox_rtc_init: "Initialise RTC",
|
||||
sensebox_rtc_init: "Initialise external RTC",
|
||||
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.",
|
||||
sensebox_rtc_set: "Set RTC time/date:",
|
||||
sensebox_rtc_set_tooltip:
|
||||
"Sets the time of the RTC. Note that you execute this block in the setup.",
|
||||
sensebox_rtc_get_timestamp: "Get timestamp",
|
||||
sensebox_rtc_get_timestamp: "Timestamp external RTC (RFC 3339)",
|
||||
sensebox_rtc_get_timestamp_tooltip:
|
||||
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||
sensebox_rtc_get_tooltip: "Returns the selected value",
|
||||
@ -17,4 +17,22 @@ export const RTC = {
|
||||
sensebox_rtc_day: "day",
|
||||
sensebox_rtc_month: "month",
|
||||
sensebox_rtc_year: "year",
|
||||
sensebox_internal_rtc_init: "Initialise internal RTC",
|
||||
sensebox_internal_rtc_init_tooltip:
|
||||
"Initialise the internal RTC. This RTC is not battery backed and will be reset on every power cycle.",
|
||||
sensebox_internal_rtc_set: "Set internal RTC time/date:",
|
||||
sensebox_internal_rtc_set_tooltip:
|
||||
"Sets the time of the internal RTC. Note that you execute this block in the setup.",
|
||||
sensebox_internal_rtc_get: "Get: ",
|
||||
sensebox_internal_rtc_get_timestamp: "Timestamp internal RTC (RFC 3339)",
|
||||
sensebox_internal_rtc_get_timestamp_tooltip:
|
||||
"Returns a timestamp formatted in ISO 8601. Ex: 2021-12-24T18:21Z",
|
||||
sensebox_internal_rtc_get_tooltip: "Returns the selected value",
|
||||
sensebox_internal_rtc_epoch: "Unix Time",
|
||||
sensebox_internal_rtc_year: "year",
|
||||
sensebox_internal_rtc_month: "month",
|
||||
sensebox_internal_rtc_day: "day",
|
||||
sensebox_internal_rtc_hour: "hour",
|
||||
sensebox_internal_rtc_minutes: "minutes",
|
||||
sensebox_internal_rtc_seconds: "seconds",
|
||||
};
|
||||
|
@ -141,6 +141,7 @@ If the max distance is reached the a value of **O** will be returned`,
|
||||
senseBox_bme680: "Environmental sensor (BME680)",
|
||||
senseBox_bme_iaq: "Indoor Air Quality (IAQ)",
|
||||
senseBox_bme_iaq_accuracy: "Calibration Value",
|
||||
senseBox_bme_pressure: "Airpressure in Pa",
|
||||
senseBox_bme_co2: "CO2 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.
|
||||
@ -205,4 +206,23 @@ The measured values for temperature, humidity and air pressure can be used direc
|
||||
*
|
||||
*/
|
||||
senseBox_watertemperature: "Water Temperature",
|
||||
|
||||
|
||||
/**
|
||||
* Feinstaubsensor Sensirion SPS30
|
||||
*/
|
||||
|
||||
senseBox_sps30: "Particulate Matter Sensor (Sensirion SPS30)",
|
||||
senseBox_sps30_dimension: "in µg/m³",
|
||||
senseBox_sps30_1p0: "PM1.0",
|
||||
senseBox_sps30_2p5: "PM2.5",
|
||||
senseBox_sps30_4p0: "PM4.0",
|
||||
senseBox_sps30_10p0: "PM10",
|
||||
senseBox_sps30_tooltip:
|
||||
"This block gives you the measured value of the Sensirion SPS30 fine dust sensor. Connect the fine dust sensor to one of the 5 **I2C** connectors. Select between PM1.0, PM2.5, PM4.0 and PM10 in the dropdown menu. The measured value will be displayed as **decimal** in µg/m3",
|
||||
senseBox_sps30_helpurl:
|
||||
"https://docs.sensebox.de/hardware/sensoren-feinstaub/",
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
@ -8,11 +8,15 @@ export const UI = {
|
||||
toolbox_math: "Math",
|
||||
toolbox_io: "Input/Output",
|
||||
toolbox_time: "Time",
|
||||
toolbox_rtc: "RTC",
|
||||
toolbox_ntp: "NTP",
|
||||
toolbox_functions: "Functions",
|
||||
toolbox_variables: "Variables",
|
||||
toolbox_serial: "Serial",
|
||||
toolbox_advanced: "Erweitert",
|
||||
toolbox_motors: "Motors",
|
||||
toolbox_label_externalRTC: "External RTC",
|
||||
toolbox_label_internalRTC: "Internal RTC",
|
||||
variable_NUMBER: "Number (int)",
|
||||
variable_SHORT_NUMBER: "char",
|
||||
variable_LONG: "Big number (long)",
|
||||
@ -304,11 +308,14 @@ export const UI = {
|
||||
"Your code will now be compiled and then downloaded to your computer",
|
||||
|
||||
/**
|
||||
* Device Selction
|
||||
* Device Selection
|
||||
* */
|
||||
|
||||
deviceselection_head: "Which board are you using?",
|
||||
deviceselection_keep_selection: "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_keep_selection:
|
||||
"Save my choice (You can change the board later in the settings)",
|
||||
deviceselection_footnote:
|
||||
"Here you can access the old blockly Version for the",
|
||||
deviceselection_footnote_02: "or the",
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { Block, Value, Field, Shadow, Category } from "../";
|
||||
import { Block, Value, Field, Shadow, Category, Sep, Label } from "../";
|
||||
import { getColour } from "../helpers/colour";
|
||||
import "@blockly/block-plus-minus";
|
||||
import { TypedVariableModal } from "@blockly/plugin-typed-variable-modal";
|
||||
@ -61,6 +61,7 @@ class Toolbox extends React.Component {
|
||||
<Block type="sensebox_sensor_uv_light" />
|
||||
<Block type="sensebox_sensor_bmx055_accelerometer" />
|
||||
<Block type="sensebox_sensor_sds011" />
|
||||
<Block type="sensebox_sensor_sps30" />
|
||||
<Block type="sensebox_sensor_pressure" />
|
||||
<Block type="sensebox_sensor_dps310" />
|
||||
<Block type="sensebox_sensor_bme680_bsec" />
|
||||
@ -502,6 +503,12 @@ class Toolbox extends React.Component {
|
||||
<Block type="time_micros"></Block>
|
||||
<Block type="infinite_loop"></Block>
|
||||
<Block type="sensebox_interval_timer"></Block>
|
||||
<Category
|
||||
id="time"
|
||||
name={Blockly.Msg.toolbox_rtc}
|
||||
colour={getColour().time}
|
||||
>
|
||||
<Label text={Blockly.Msg.toolbox_label_externalRTC}></Label>
|
||||
<Block type="sensebox_rtc_init"></Block>
|
||||
<Block type="sensebox_rtc_set">
|
||||
<Value name="second">
|
||||
@ -538,6 +545,21 @@ class Toolbox extends React.Component {
|
||||
{/* <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
|
||||
id="math"
|
||||
@ -642,7 +664,10 @@ class Toolbox extends React.Component {
|
||||
</Value>
|
||||
</Block>
|
||||
</Category>
|
||||
<Category name={Blockly.Msg.toolbox_motors} colour={getColour().motors}>
|
||||
<Category
|
||||
name={Blockly.Msg.toolbox_motors}
|
||||
colour={getColour().motors}
|
||||
>
|
||||
<Block type="sensebox_motors_beginServoMotor" />
|
||||
<Block type="sensebox_motors_moveServoMotor">
|
||||
<Value name="degrees">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { connect } from "react-redux";
|
||||
import { visitPage } from "../../actions/generalActions";
|
||||
import { visitPage, setPlatform } from "../../actions/generalActions";
|
||||
|
||||
import { Route, Switch, withRouter } from "react-router-dom";
|
||||
|
||||
@ -27,6 +27,24 @@ import Faq from "../Faq";
|
||||
import CodeEditor from "../CodeEditor/CodeEditor";
|
||||
|
||||
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() {
|
||||
this.props.visitPage();
|
||||
}
|
||||
@ -105,6 +123,12 @@ class Routes extends Component {
|
||||
|
||||
Home.propTypes = {
|
||||
visitPage: PropTypes.func,
|
||||
platform: PropTypes.bool.isRequired,
|
||||
setPlatform: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { visitPage })(withRouter(Routes));
|
||||
const mapStateToProps = (state) => ({
|
||||
platform: state.general.platform,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { visitPage, setPlatform })(withRouter(Routes));
|
||||
|
@ -4,12 +4,22 @@
|
||||
"name": "senseBox MCU",
|
||||
"src": "senseboxmcu.png",
|
||||
"url": "https://docs.sensebox.de/hardware/allgemein-sensebox-mcu/",
|
||||
"category": "boards",
|
||||
"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",
|
||||
"name": "Breadboard",
|
||||
"src": "breadboard.png",
|
||||
"category": "misc",
|
||||
"url": ""
|
||||
},
|
||||
{
|
||||
@ -56,10 +66,16 @@
|
||||
},
|
||||
{
|
||||
"id": "feinstaub",
|
||||
"name": "Feinstaubsensor",
|
||||
"name": "Feinstaubsensor (SDS011)",
|
||||
"src": "feinstaub.png",
|
||||
"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",
|
||||
"name": "GPS-Modul",
|
||||
@ -140,8 +156,14 @@
|
||||
},
|
||||
{
|
||||
"id": "ds1820b",
|
||||
"name": "Wassertemperatur",
|
||||
"src": "ws2818.png",
|
||||
"name": "Wassertemperatur Sensor",
|
||||
"src": "wassertemp.png",
|
||||
"url": ""
|
||||
},
|
||||
{
|
||||
"id": "expander",
|
||||
"name": "I2C Expander",
|
||||
"src": "expander.png",
|
||||
"url": ""
|
||||
},
|
||||
{
|
||||
@ -162,6 +184,18 @@
|
||||
"src": "jst-jst.png",
|
||||
"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",
|
||||
"name": "Steckkabel",
|
||||
|
Loading…
x
Reference in New Issue
Block a user