Merge pull request #108 from sensebox/improve-sd-blocks
Improve sd blocks
This commit is contained in:
		
						commit
						abfa5d0bed
					
				| @ -1,57 +1,81 @@ | |||||||
| import * as Blockly from 'blockly/core'; | import * as Blockly from "blockly/core"; | ||||||
| import { getColour } from '../helpers/colour'; | import { getColour } from "../helpers/colour"; | ||||||
| 
 | 
 | ||||||
|  | var checkFileName = function (filename) { | ||||||
|  |   var length = filename.length; | ||||||
|  |   if (length > 8) { | ||||||
|  |     alert("dateiname sollte kleiner als 8 Zeichen sein"); | ||||||
|  |     return filename.slice(0, 8); | ||||||
|  |   } | ||||||
|  |   return filename; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks['sensebox_sd_open_file'] = { | Blockly.Blocks["sensebox_sd_open_file"] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_sd_open_file) |       .appendField(Blockly.Msg.senseBox_sd_open_file) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField( |       .appendField( | ||||||
|                 new Blockly.FieldTextInput('Data.txt'), |         new Blockly.FieldTextInput("Data", checkFileName), | ||||||
|                 'Filename'); |         "Filename" | ||||||
|         this.appendStatementInput('SD') |       ) | ||||||
|             .setCheck(null); |       .appendField(".") | ||||||
|  |       .appendField( | ||||||
|  |         new Blockly.FieldDropdown([ | ||||||
|  |           ["txt", "txt"], | ||||||
|  |           ["csv", "csv"], | ||||||
|  |         ]), | ||||||
|  |         "extension" | ||||||
|  |       ); | ||||||
|  |     this.appendStatementInput("SD").setCheck(null); | ||||||
|     this.setPreviousStatement(true, null); |     this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     this.setNextStatement(true, null); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_open_file_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_sd_open_file_tooltip); | ||||||
|         this.setHelpUrl('https://docs.sensebox.de/hardware/bee-sd/'); |     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||||
|     } |   }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks['sensebox_sd_create_file'] = { | Blockly.Blocks["sensebox_sd_create_file"] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_sd_create_file) |       .appendField(Blockly.Msg.senseBox_sd_create_file) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT) |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|       .appendField(Blockly.Msg.senseBox_output_filename) |       .appendField(Blockly.Msg.senseBox_output_filename) | ||||||
|       .appendField( |       .appendField( | ||||||
|                 new Blockly.FieldTextInput('Data.txt'), |         new Blockly.FieldTextInput("Data", checkFileName), | ||||||
|                 'Filename'); |         "Filename" | ||||||
|  |       ) | ||||||
|  |       .appendField(".") | ||||||
|  |       .appendField( | ||||||
|  |         new Blockly.FieldDropdown([ | ||||||
|  |           ["txt", "txt"], | ||||||
|  |           ["csv", "csv"], | ||||||
|  |         ]), | ||||||
|  |         "extension" | ||||||
|  |       ); | ||||||
|     this.setPreviousStatement(true, null); |     this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     this.setNextStatement(true, null); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_create_file_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_sd_create_file_tooltip); | ||||||
|         this.setHelpUrl('https://docs.sensebox.de/hardware/bee-sd/'); |     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||||
|     } |   }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Blocks['sensebox_sd_write_file'] = { | Blockly.Blocks["sensebox_sd_write_file"] = { | ||||||
|   init: function () { |   init: function () { | ||||||
|     this.appendDummyInput() |     this.appendDummyInput() | ||||||
|       .appendField(Blockly.Msg.senseBox_sd_write_file) |       .appendField(Blockly.Msg.senseBox_sd_write_file) | ||||||
|       .setAlign(Blockly.ALIGN_LEFT); |       .setAlign(Blockly.ALIGN_LEFT); | ||||||
|         this.appendValueInput('DATA') |     this.appendValueInput("DATA").setCheck(null); | ||||||
|             .setCheck(null); |     this.appendDummyInput("CheckboxText") | ||||||
|         this.appendDummyInput('CheckboxText') |  | ||||||
|       .appendField(Blockly.Msg.senseBox_output_linebreak) |       .appendField(Blockly.Msg.senseBox_output_linebreak) | ||||||
|             .appendField(new Blockly.FieldCheckbox('TRUE'), 'linebreak'); |       .appendField(new Blockly.FieldCheckbox("TRUE"), "linebreak"); | ||||||
|     this.setPreviousStatement(true, null); |     this.setPreviousStatement(true, null); | ||||||
|     this.setNextStatement(true, null); |     this.setNextStatement(true, null); | ||||||
|     this.setColour(getColour().sensebox); |     this.setColour(getColour().sensebox); | ||||||
|     this.setTooltip(Blockly.Msg.senseBox_sd_write_file_tooltip); |     this.setTooltip(Blockly.Msg.senseBox_sd_write_file_tooltip); | ||||||
|         this.setHelpUrl('https://docs.sensebox.de/hardware/bee-sd/'); |     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||||
|   }, |   }, | ||||||
|   /** |   /** | ||||||
|    * Called whenever anything on the workspace changes. |    * Called whenever anything on the workspace changes. | ||||||
| @ -76,5 +100,88 @@ Blockly.Blocks['sensebox_sd_write_file'] = { | |||||||
|       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); |       this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|     LOOP_TYPES: ['sensebox_sd_open_file'], |   LOOP_TYPES: ["sensebox_sd_open_file"], | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Blockly.Blocks["sensebox_sd_osem"] = { | ||||||
|  |   init: function () { | ||||||
|  |     this.setTooltip(Blockly.Msg.sensebox_sd_osem_tip); | ||||||
|  |     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||||
|  |     this.setColour(getColour().sensebox); | ||||||
|  |     this.appendDummyInput() | ||||||
|  |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|  |       .appendField(Blockly.Msg.sensebox_sd_osem); | ||||||
|  |     this.appendDummyInput() | ||||||
|  |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|  |       .appendField(Blockly.Msg.senseBox_osem_exposure) | ||||||
|  |       .appendField( | ||||||
|  |         new Blockly.FieldDropdown([ | ||||||
|  |           [Blockly.Msg.senseBox_osem_stationary, "Stationary"], | ||||||
|  |           [Blockly.Msg.senseBox_osem_mobile, "Mobile"], | ||||||
|  |         ]), | ||||||
|  |         "type" | ||||||
|  |       ); | ||||||
|  |     this.appendValueInput("timeStamp", "Number").appendField( | ||||||
|  |       Blockly.Msg.senseBox_gps_timeStamp | ||||||
|  |     ); | ||||||
|  |     this.appendStatementInput("DO") | ||||||
|  |       .appendField(Blockly.Msg.sensebox_sd_measurement) | ||||||
|  |       .setCheck(null); | ||||||
|  |     this.setPreviousStatement(true, null); | ||||||
|  |     this.setNextStatement(true, null); | ||||||
|  |   }, | ||||||
|  |   mutationToDom: function () { | ||||||
|  |     var container = document.createElement("mutation"); | ||||||
|  |     var input = this.getFieldValue("type"); | ||||||
|  |     this.updateShape_(input); | ||||||
|  |     container.setAttribute("type", input); | ||||||
|  |     return container; | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   domToMutation: function (xmlElement) { | ||||||
|  |     var connections = xmlElement.getAttribute("connections"); | ||||||
|  |     this.updateShape_(connections); | ||||||
|  |   }, | ||||||
|  |   /** | ||||||
|  |    * Modify this block to have the correct number of pins available. | ||||||
|  |    * @param {boolean} | ||||||
|  |    * @private | ||||||
|  |    * @this Blockly.Block | ||||||
|  |    */ | ||||||
|  |   updateShape_: function () { | ||||||
|  |     var extraFieldExist = this.getFieldValue("gps"); | ||||||
|  |     var input = this.getFieldValue("type"); | ||||||
|  |     if (input === "Mobile" && extraFieldExist === null) { | ||||||
|  |       this.appendValueInput("lat", "Number").appendField( | ||||||
|  |         Blockly.Msg.senseBox_gps_lat, | ||||||
|  |         "gps" | ||||||
|  |       ); | ||||||
|  |       this.appendValueInput("lng", "Number").appendField( | ||||||
|  |         Blockly.Msg.senseBox_gps_lng | ||||||
|  |       ); | ||||||
|  |       this.appendValueInput("altitude", "Number").appendField( | ||||||
|  |         Blockly.Msg.senseBox_gps_alt | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (input === "Stationary" && extraFieldExist !== null) { | ||||||
|  |       this.removeInput("lat"); | ||||||
|  |       this.removeInput("lng"); | ||||||
|  |       this.removeInput("altitude"); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | Blockly.Blocks["sensebox_sd_save_for_osem"] = { | ||||||
|  |   init: function () { | ||||||
|  |     this.setTooltip(Blockly.Msg.sensebox_sd_save_for_osem_tip); | ||||||
|  |     this.setHelpUrl(Blockly.Msg.sensebox_sd_helpurl); | ||||||
|  |     this.setColour(getColour().sensebox); | ||||||
|  |     this.appendDummyInput().appendField(Blockly.Msg.sensebox_sd_save_for_osem); | ||||||
|  |     this.appendValueInput("Value") | ||||||
|  |       .setAlign(Blockly.ALIGN_LEFT) | ||||||
|  |       .appendField(Blockly.Msg.sensebox_sd_save_for_osem_id) | ||||||
|  |       .appendField(new Blockly.FieldTextInput("sensorID"), "SensorID"); | ||||||
|  |     this.setPreviousStatement(true, null); | ||||||
|  |     this.setNextStatement(true, null); | ||||||
|  |   }, | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -412,8 +412,9 @@ Blockly.Blocks["sensebox_gps"] = { | |||||||
|       [Blockly.Msg.senseBox_gps_lat, "latitude"], |       [Blockly.Msg.senseBox_gps_lat, "latitude"], | ||||||
|       [Blockly.Msg.senseBox_gps_lng, "longitude"], |       [Blockly.Msg.senseBox_gps_lng, "longitude"], | ||||||
|       [Blockly.Msg.senseBox_gps_alt, "altitude"], |       [Blockly.Msg.senseBox_gps_alt, "altitude"], | ||||||
|  |       [Blockly.Msg.senseBox_gps_timeStamp, "timestamp"], | ||||||
|  |       [Blockly.Msg.senseBox_gps_speed, "speed"], | ||||||
|       ["pDOP", "pDOP"], |       ["pDOP", "pDOP"], | ||||||
|       ["Timestamp", "timestamp"], |  | ||||||
|       ["Fix Type", "fixType"], |       ["Fix Type", "fixType"], | ||||||
|     ]; |     ]; | ||||||
|     this.appendDummyInput().appendField("GPS Modul"); |     this.appendDummyInput().appendField("GPS Modul"); | ||||||
|  | |||||||
| @ -79,18 +79,16 @@ Blockly.Arduino.sensebox_rtc_get_timestamp = function () { | |||||||
|   Blockly.Arduino.setupCode_[ |   Blockly.Arduino.setupCode_[ | ||||||
|     "rtc.batterySwitchOver" |     "rtc.batterySwitchOver" | ||||||
|   ] = `rtc.batterySwitchOver(1);`; |   ] = `rtc.batterySwitchOver(1);`; | ||||||
|   Blockly.Arduino.loopCodeOnce_[ |  | ||||||
|     "rtc_variables" |  | ||||||
|   ] = `uint8_t sec, min, hour, day, month;\nuint16_t year;`; |  | ||||||
|   Blockly.Arduino.variables_["rtc_timestamp"] = `char timestamp[20];`; |   Blockly.Arduino.variables_["rtc_timestamp"] = `char timestamp[20];`; | ||||||
|   Blockly.Arduino.loopCodeOnce_[ |   Blockly.Arduino.codeFunctions_["getTimeStamp"] = ` | ||||||
|     "rtc_get" | char* getTimeStamp() { | ||||||
|   ] = `rtc.get(&sec, &min, &hour, &day, &month, &year);`; | uint8_t sec, min, hour, day, month; | ||||||
| 
 |  uint16_t year; | ||||||
|   Blockly.Arduino.loopCodeOnce_[ |  rtc.get(&sec, &min, &hour, &day, &month, &year); | ||||||
|     "" |  sprintf(timestamp, "%02d-%02d-%02dT%02d:%02d:%02dZ", year, month, day, hour, min, sec); | ||||||
|   ] = `sprintf(timestamp, "%02d-%02d-%02dT%02d:%02d:%02dZ", year, month, day, hour, min, sec);`; |  return timestamp; | ||||||
| 
 |  } | ||||||
|   var code = `timestamp`; |   `;
 | ||||||
|  |   var code = `getTimeStamp()`; | ||||||
|   return [code, Blockly.Arduino.ORDER_ATOMIC]; |   return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| import Blockly from 'blockly'; | import Blockly from "blockly"; | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| /* SD-Card Blocks using the Standard SD Library*/ | /* SD-Card Blocks using the Standard SD Library*/ | ||||||
| /** | /** | ||||||
| @ -10,45 +9,200 @@ import Blockly from 'blockly'; | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| Blockly.Arduino.sensebox_sd_create_file = function (block) { | Blockly.Arduino.sensebox_sd_create_file = function (block) { | ||||||
|     var filename = this.getFieldValue('Filename'); |   var filename = this.getFieldValue("Filename"); | ||||||
|     var res = filename.slice(0, 4); |   var extension = this.getFieldValue("extension"); | ||||||
|     Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>'; |   var newFileName = filename.concat(".", extension); | ||||||
|     Blockly.Arduino.libraries_['library_sd'] = '#include <SD.h>'; |   Blockly.Arduino.libraries_["library_spi"] = "#include <SPI.h>"; | ||||||
|     Blockly.Arduino.definitions_['define_' + res] = 'File dataFile' + res + ';'; |   Blockly.Arduino.libraries_["library_sd"] = "#include <SD.h>"; | ||||||
|     Blockly.Arduino.setupCode_['sensebox_sd'] = 'SD.begin(28);'; |   Blockly.Arduino.definitions_["define_" + filename] = `File ${filename};`; | ||||||
|     Blockly.Arduino.setupCode_['sensebox_sd' + filename] = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\ndataFile' + res + '.close();\n'; |   Blockly.Arduino.setupCode_["sensebox_sd"] = "SD.begin(28);\n"; | ||||||
|     var code = ''; |   Blockly.Arduino.setupCode_[ | ||||||
|  |     "sensebox_sd" + filename | ||||||
|  |   ] = `${filename} = SD.open("${newFileName}", FILE_WRITE);\n${filename}.close();\n`; | ||||||
|  |   var code = ""; | ||||||
|   return code; |   return code; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Arduino.sensebox_sd_open_file = function (block) { | Blockly.Arduino.sensebox_sd_open_file = function (block) { | ||||||
|     var filename = this.getFieldValue('Filename'); |   var filename = this.getFieldValue("Filename"); | ||||||
|     var res = filename.slice(0, 4); |   var extension = this.getFieldValue("extension"); | ||||||
|     var branch = Blockly.Arduino.statementToCode(block, 'SD'); |   var newFileName = filename.concat(".", extension); | ||||||
|     var code = 'dataFile' + res + ' = SD.open("' + filename + '", FILE_WRITE);\n' |   var branch = Blockly.Arduino.statementToCode(block, "SD"); | ||||||
|  |   var code = `${filename} = SD.open("${newFileName}", FILE_WRITE);\n`; | ||||||
|   code += branch; |   code += branch; | ||||||
|     code += 'dataFile' + res + '.close();\n' |   code += `${filename}.close();\n`; | ||||||
|   return code; |   return code; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Blockly.Arduino.sensebox_sd_write_file = function (block) { | Blockly.Arduino.sensebox_sd_write_file = function (block) { | ||||||
|   if (this.parentBlock_ != null) { |   if (this.parentBlock_ != null) { | ||||||
|         var filename = this.getSurroundParent().getFieldValue('Filename'); |     var filename = this.getSurroundParent().getFieldValue("Filename"); | ||||||
|   } |   } | ||||||
|     var res = filename.slice(0, 4); |   var branch = | ||||||
|     var text = Blockly.Arduino.valueToCode(this, 'DATA', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"'; |     Blockly.Arduino.valueToCode(this, "DATA", Blockly.Arduino.ORDER_ATOMIC) || | ||||||
|     var linebreak = this.getFieldValue('linebreak'); |     '"Keine Eingabe"'; | ||||||
|  |   var linebreak = this.getFieldValue("linebreak"); | ||||||
|   if (linebreak === "TRUE") { |   if (linebreak === "TRUE") { | ||||||
|     linebreak = "ln"; |     linebreak = "ln"; | ||||||
|   } else { |   } else { | ||||||
|     linebreak = ""; |     linebreak = ""; | ||||||
|   } |   } | ||||||
|     var code = ''; |   var code = ""; | ||||||
|     if (text === "gps.getLongitude()" || text === "gps.getLatitude()") { |   if (branch === "gps.getLongitude()" || branch === "gps.getLatitude()") { | ||||||
|         code = 'dataFile' + res + '.print' + linebreak + '(' + text + ',5);\n' |     code = `${filename}.print${linebreak}(${branch},5);\n`; | ||||||
|     } |   } else { | ||||||
|     else { |     code = `${filename}.print${linebreak}(${branch});\n`; | ||||||
|         code = 'dataFile' + res + '.print' + linebreak + '(' + text + ');\n' |  | ||||||
|   } |   } | ||||||
|   return code; |   return code; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | Blockly.Arduino.sensebox_sd_osem = function () { | ||||||
|  |   if (this.parentBlock_ != null) { | ||||||
|  |     var filename = this.getSurroundParent().getFieldValue("Filename"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   var type = this.getFieldValue("type"); | ||||||
|  |   var blocks = this.getDescendants(); | ||||||
|  |   var branch = Blockly.Arduino.statementToCode(this, "DO"); | ||||||
|  |   var count = 0; | ||||||
|  |   if (blocks !== undefined) { | ||||||
|  |     for (var i = 0; i < blocks.length; i++) { | ||||||
|  |       if (blocks[i].type === "sensebox_sd_save_for_osem") { | ||||||
|  |         count++; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   var num_sensors = count; | ||||||
|  |   var timestamp = Blockly.Arduino.valueToCode( | ||||||
|  |     this, | ||||||
|  |     "timeStamp", | ||||||
|  |     Blockly.Arduino.ORDER_ATOMIC | ||||||
|  |   ); | ||||||
|  |   Blockly.Arduino.definitions_["num_sensors"] = | ||||||
|  |     "static const uint8_t NUM_SENSORS = " + num_sensors + ";"; | ||||||
|  | 
 | ||||||
|  |   Blockly.Arduino.definitions_["measurement"] = `typedef struct measurement {
 | ||||||
|  |     const char *sensorId; | ||||||
|  |     float value; | ||||||
|  |   } measurement;`;
 | ||||||
|  |   Blockly.Arduino.definitions_["buffer"] = "char buffer[750];"; | ||||||
|  |   Blockly.Arduino.definitions_[ | ||||||
|  |     "num_measurement" | ||||||
|  |   ] = `measurement measurements[NUM_SENSORS];
 | ||||||
|  |   uint8_t num_measurements = 0;`;
 | ||||||
|  |   if (type === "Stationary") { | ||||||
|  |     Blockly.Arduino.functionNames_["addMeasurement"] = ` | ||||||
|  | void addMeasurement(const char *sensorId, float value) { | ||||||
|  |     measurements[num_measurements].sensorId = sensorId; | ||||||
|  |     measurements[num_measurements].value = value; | ||||||
|  |     num_measurements++; | ||||||
|  |     } | ||||||
|  | `;
 | ||||||
|  |     Blockly.Arduino.functionNames_["writeMeasurementsToSdCard"] = ` | ||||||
|  | void writeMeasurementsToSdCard(char* timeStamp) { | ||||||
|  |     // iterate throug the measurements array
 | ||||||
|  |     for (uint8_t i = 0; i < num_measurements; i++) { | ||||||
|  | sprintf_P(buffer, PSTR("%s,%9.2f,%s"), measurements[i].sensorId, measurements[i].value, timeStamp);          | ||||||
|  |       // transmit buffer to client
 | ||||||
|  |       ${filename}.println(buffer); | ||||||
|  |     } | ||||||
|  |     // reset num_measurements
 | ||||||
|  |     num_measurements = 0; | ||||||
|  | } | ||||||
|  | `;
 | ||||||
|  |     Blockly.Arduino.functionNames_["saveValues"] = ` | ||||||
|  | void saveValues() { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       // send measurements
 | ||||||
|  |       writeMeasurementsToSdCard(${timestamp});  | ||||||
|  |       num_measurements = 0; | ||||||
|  | }  | ||||||
|  | `;
 | ||||||
|  |     var code = ""; | ||||||
|  |     code += branch; | ||||||
|  |     code += "saveValues();"; | ||||||
|  |   } else if (type === "Mobile") { | ||||||
|  |     /** | ||||||
|  |      * add mobile functions here | ||||||
|  |      */ | ||||||
|  |     Blockly.Arduino.libraries_["dtostrf.h"] = "#include <avr/dtostrf.h>"; | ||||||
|  |     var lat = Blockly.Arduino.valueToCode( | ||||||
|  |       this, | ||||||
|  |       "lat", | ||||||
|  |       Blockly.Arduino.ORDER_ATOMIC | ||||||
|  |     ); | ||||||
|  |     var lng = Blockly.Arduino.valueToCode( | ||||||
|  |       this, | ||||||
|  |       "lng", | ||||||
|  |       Blockly.Arduino.ORDER_ATOMIC | ||||||
|  |     ); | ||||||
|  |     // var altitude = Blockly.Arduino.valueToCode(
 | ||||||
|  |     //   this,
 | ||||||
|  |     //   "altitude",
 | ||||||
|  |     //   Blockly.Arduino.ORDER_ATOMIC
 | ||||||
|  |     // );
 | ||||||
|  |     Blockly.Arduino.definitions_["num_sensors"] = | ||||||
|  |       "static const uint8_t NUM_SENSORS = " + num_sensors + ";"; | ||||||
|  | 
 | ||||||
|  |     Blockly.Arduino.definitions_["measurement"] = `typedef struct measurement {
 | ||||||
|  |         const char *sensorId; | ||||||
|  |         float value; | ||||||
|  |       } measurement;`;
 | ||||||
|  |     Blockly.Arduino.definitions_["buffer"] = "char buffer[750];"; | ||||||
|  |     Blockly.Arduino.definitions_[ | ||||||
|  |       "num_measurement" | ||||||
|  |     ] = `measurement measurements[NUM_SENSORS];
 | ||||||
|  |       uint8_t num_measurements = 0;`;
 | ||||||
|  |     Blockly.Arduino.functionNames_["addMeasurement"] = ` | ||||||
|  | void addMeasurement(const char *sensorId, float value) { | ||||||
|  |         measurements[num_measurements].sensorId = sensorId; | ||||||
|  |         measurements[num_measurements].value = value; | ||||||
|  |         num_measurements++; | ||||||
|  |         } | ||||||
|  |     `;
 | ||||||
|  |     Blockly.Arduino.functionNames_["writeMeasurementsToSdCard"] = ` | ||||||
|  | void writeMeasurementsToSdCard(char* timeStamp, uint32_t latitudes, uint32_t longitudes) { | ||||||
|  |     // iterate throug the measurements array
 | ||||||
|  |         for (uint8_t i = 0; i < num_measurements; i++) { | ||||||
|  |             char lng[20]; | ||||||
|  |             char lat[20]; | ||||||
|  |             float longitude = longitudes / (float)10000000; | ||||||
|  |             float latitude = latitudes / (float)10000000; | ||||||
|  |             dtostrf(longitude, 2, 7, lng); | ||||||
|  |             dtostrf(latitude, 1, 7, lat); | ||||||
|  |             sprintf_P(buffer, PSTR("%s,%9.2f,%s,%02s,%02s"),  measurements[i].sensorId, measurements[i].value, timeStamp, lng, lat); | ||||||
|  |             // transmit buffer to client
 | ||||||
|  |             ${filename}.print(buffer); | ||||||
|  |             } | ||||||
|  |             // reset num_measurements
 | ||||||
|  |             num_measurements = 0; | ||||||
|  |         } | ||||||
|  |     `;
 | ||||||
|  |     Blockly.Arduino.functionNames_["saveValues"] = ` | ||||||
|  |     void saveValues() { | ||||||
|  |           // send measurements
 | ||||||
|  |           writeMeasurementsToSdCard(${timestamp}, ${lat}, ${lng});  | ||||||
|  |           num_measurements = 0; | ||||||
|  |     }  | ||||||
|  |     `;
 | ||||||
|  |     code = ""; | ||||||
|  |     code += branch; | ||||||
|  |     code += "saveValues();\n"; | ||||||
|  |   } | ||||||
|  |   return code; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | Blockly.Arduino.sensebox_sd_save_for_osem = function (block) { | ||||||
|  |   var code = ""; | ||||||
|  |   var sensor_id = this.getFieldValue("SensorID"); | ||||||
|  |   var id = sensor_id.slice(-3).toUpperCase(); | ||||||
|  |   var sensor_value = | ||||||
|  |     Blockly.Arduino.valueToCode(block, "Value", Blockly.Arduino.ORDER_ATOMIC) || | ||||||
|  |     '"Keine Eingabe"'; | ||||||
|  |   Blockly.Arduino.definitions_["SENSOR_ID" + id + ""] = | ||||||
|  |     "const char SENSOR_ID" + id + '[] PROGMEM = "' + sensor_id + '";'; | ||||||
|  |   code += "addMeasurement(SENSOR_ID" + id + "," + sensor_value + ");\n"; | ||||||
|  |   console.log(code); | ||||||
|  |   return code; | ||||||
|  | }; | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ export const RTC = { | |||||||
|   sensebox_rtc_set: "Setze Uhrzeit/Datum der 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", |   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: ", |   sensebox_rtc_get: "Wert: ", | ||||||
|  | |||||||
| @ -3,11 +3,23 @@ export const SD = { | |||||||
|    * SD-Block |    * SD-Block | ||||||
|    */ |    */ | ||||||
|   senseBox_sd_create_file: "Erstelle Datei auf SD-Karte", |   senseBox_sd_create_file: "Erstelle Datei auf SD-Karte", | ||||||
|  |   sensebox_sd_helpurl: "https://docs.sensebox.de/hardware/bee-sd/", | ||||||
|   senseBox_sd_write_file: "Schreibe Daten auf SD-Karte", |   senseBox_sd_write_file: "Schreibe Daten auf SD-Karte", | ||||||
|   senseBox_sd_open_file: "Öffne eine Datei auf der SD-Karte", |   senseBox_sd_open_file: "Öffne eine Datei auf der SD-Karte", | ||||||
|     senseBox_sd_create_file_tooltip: "Erstellt eine Datei auf der Karte. Stecke das SD-Bee auf den Steckplatz **XBEE2**. Die **maximale** Länge des Dateinamen sind **8 Zeichen**. Die Datei sollte zuerst im *Setup()* erstellt werden", |   senseBox_sd_create_file_tooltip: | ||||||
|     senseBox_sd_write_file_tooptip: "Schreibe Daten auf die SD-Karte. Beachte, dass die Datei zuerst geöffnet werden muss.", |     "Erstellt eine Datei auf der Karte. Stecke das SD-Bee auf den Steckplatz **XBEE2**. Die **maximale** Länge des Dateinamen sind **8 Zeichen**. Die Datei sollte zuerst im *Setup()* erstellt werden", | ||||||
|     senseBox_sd_open_file_tooltip: "Öffne die Datei auf der SD-Karte, um Dateien zu speichern. Am Ende der Schleife wird die Datei automatisch wieder geschlossen.", |   senseBox_sd_write_file_tooptip: | ||||||
|  |     "Schreibe Daten auf die SD-Karte. Beachte, dass die Datei zuerst geöffnet werden muss.", | ||||||
|  |   senseBox_sd_open_file_tooltip: | ||||||
|  |     "Öffne die Datei auf der SD-Karte, um Dateien zu speichern. Am Ende der Schleife wird die Datei automatisch wieder geschlossen.", | ||||||
|   sensebox_sd_filename: "Daten", |   sensebox_sd_filename: "Daten", | ||||||
|   senseBox_sd_decimals: "Dezimalen", |   senseBox_sd_decimals: "Dezimalen", | ||||||
| } |   sensebox_sd_osem: "Erstelle CSV-Datei für openSenseMap", | ||||||
|  |   sensebox_sd_osem_tip: | ||||||
|  |     "Erstellt eine CSV-Datei, die später auf die openSenseMap hochgeladen werden kann. ", | ||||||
|  |   sensebox_sd_save_for_osem: "Speichere Messwert", | ||||||
|  |   sensebox_sd_save_for_osem_tip: | ||||||
|  |     "Füge eine Messung mit Sensor ID zur CSV-Datei hinzu", | ||||||
|  |   sensebox_sd_save_for_osem_id: "Sensor ID:", | ||||||
|  |   sensebox_sd_measurement: "Messwerte", | ||||||
|  | }; | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| export const TRANSLATIONS = { | export const TRANSLATIONS = { | ||||||
| 
 |  | ||||||
|   AUTH: "Bitte autorisiere diese App zum Aktivieren der Speicherung deiner Arbeit und zum Teilen.", |   AUTH: "Bitte autorisiere diese App zum Aktivieren der Speicherung deiner Arbeit und zum Teilen.", | ||||||
|   CHANGE_VALUE_TITLE: "Wert ändern:", |   CHANGE_VALUE_TITLE: "Wert ändern:", | ||||||
|   CHAT: "Chatte mit unserem Mitarbeiter durch Eingeben von Text in diesen Kasten!", |   CHAT: "Chatte mit unserem Mitarbeiter durch Eingeben von Text in diesen Kasten!", | ||||||
| @ -17,12 +16,15 @@ export const TRANSLATIONS = { | |||||||
|   EXTERNAL_INPUTS: "externe Eingänge", |   EXTERNAL_INPUTS: "externe Eingänge", | ||||||
|   HELP: "Hilfe", |   HELP: "Hilfe", | ||||||
|   INLINE_INPUTS: "interne Eingänge", |   INLINE_INPUTS: "interne Eingänge", | ||||||
|     LISTS_CREATE_EMPTY_HELPURL: "https://github.com/google/blockly/wiki/Lists#create-empty-list", |   LISTS_CREATE_EMPTY_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#create-empty-list", | ||||||
|   LISTS_CREATE_EMPTY_TITLE: "Erzeuge eine leere Liste", |   LISTS_CREATE_EMPTY_TITLE: "Erzeuge eine leere Liste", | ||||||
|   LISTS_CREATE_EMPTY_TOOLTIP: "Erzeugt eine leere Liste ohne Inhalt.", |   LISTS_CREATE_EMPTY_TOOLTIP: "Erzeugt eine leere Liste ohne Inhalt.", | ||||||
|   LISTS_CREATE_WITH_CONTAINER_TITLE_ADD: "Liste", |   LISTS_CREATE_WITH_CONTAINER_TITLE_ADD: "Liste", | ||||||
|     LISTS_CREATE_WITH_CONTAINER_TOOLTIP: "Hinzufügen, entfernen und sortieren von Elementen.", |   LISTS_CREATE_WITH_CONTAINER_TOOLTIP: | ||||||
|     LISTS_CREATE_WITH_HELPURL: "https://github.com/google/blockly/wiki/Lists#create-list-with", |     "Hinzufügen, entfernen und sortieren von Elementen.", | ||||||
|  |   LISTS_CREATE_WITH_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#create-list-with", | ||||||
|   LISTS_CREATE_WITH_INPUT_WITH: "Erzeuge Liste mit", |   LISTS_CREATE_WITH_INPUT_WITH: "Erzeuge Liste mit", | ||||||
|   LISTS_CREATE_WITH_ITEM_TOOLTIP: "Ein Element zur Liste hinzufügen.", |   LISTS_CREATE_WITH_ITEM_TOOLTIP: "Ein Element zur Liste hinzufügen.", | ||||||
|   LISTS_CREATE_WITH_TOOLTIP: "Erzeugt eine List mit konfigurierten Elementen.", |   LISTS_CREATE_WITH_TOOLTIP: "Erzeugt eine List mit konfigurierten Elementen.", | ||||||
| @ -35,59 +37,92 @@ export const TRANSLATIONS = { | |||||||
|   LISTS_GET_INDEX_RANDOM: "zufälliges", |   LISTS_GET_INDEX_RANDOM: "zufälliges", | ||||||
|   LISTS_GET_INDEX_REMOVE: "entferne", |   LISTS_GET_INDEX_REMOVE: "entferne", | ||||||
|   LISTS_GET_INDEX_TAIL: "", |   LISTS_GET_INDEX_TAIL: "", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_FIRST: "Extrahiere das erste Element aus der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_FIRST: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_FROM_END: "Extrahiere das #1te Element aus Ende der Liste.", |     "Extrahiere das erste Element aus der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_FROM_START: "Extrahiere das #1te Element aus der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_FROM_END: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_LAST: "Extrahiere das letzte Element aus der Liste.", |     "Extrahiere das #1te Element aus Ende der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_RANDOM: "Extrahiere ein zufälliges Element aus der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_FROM_START: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST: "Extrahiere und entfernt das erste Element aus der Liste.", |     "Extrahiere das #1te Element aus der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_END: "Extrahiere und entfernt das #1te Element aus Ende der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_LAST: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_START: "Extrahiere und entfernt das #1te Element aus der Liste.", |     "Extrahiere das letzte Element aus der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST: "Extrahiere und entfernt das letzte Element aus der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_RANDOM: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM: "Extrahiere und entfernt ein zufälliges Element aus der Liste.", |     "Extrahiere ein zufälliges Element aus der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST: "Entfernt das erste Element von der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_END: "Entfernt das #1te Element von Ende der Liste.", |     "Extrahiere und entfernt das erste Element aus der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_START: "Entfernt das #1te Element von der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_END: | ||||||
|     LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST: "Entfernt das letzte Element von der Liste.", |     "Extrahiere und entfernt das #1te Element aus Ende der Liste.", | ||||||
|     LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM: "Entfernt ein zufälliges Element von der Liste.", |   LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM_START: | ||||||
|  |     "Extrahiere und entfernt das #1te Element aus der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST: | ||||||
|  |     "Extrahiere und entfernt das letzte Element aus der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM: | ||||||
|  |     "Extrahiere und entfernt ein zufälliges Element aus der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST: | ||||||
|  |     "Entfernt das erste Element von der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_END: | ||||||
|  |     "Entfernt das #1te Element von Ende der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM_START: | ||||||
|  |     "Entfernt das #1te Element von der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST: | ||||||
|  |     "Entfernt das letzte Element von der Liste.", | ||||||
|  |   LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM: | ||||||
|  |     "Entfernt ein zufälliges Element von der Liste.", | ||||||
|   LISTS_GET_SUBLIST_END_FROM_END: "bis zu # von hinten", |   LISTS_GET_SUBLIST_END_FROM_END: "bis zu # von hinten", | ||||||
|   LISTS_GET_SUBLIST_END_FROM_START: "bis zu #", |   LISTS_GET_SUBLIST_END_FROM_START: "bis zu #", | ||||||
|   LISTS_GET_SUBLIST_END_LAST: "bis zum Ende", |   LISTS_GET_SUBLIST_END_LAST: "bis zum Ende", | ||||||
|     LISTS_GET_SUBLIST_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", |   LISTS_GET_SUBLIST_HELPURL: | ||||||
|  |     "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", | ||||||
|   LISTS_GET_SUBLIST_START_FIRST: "erhalte Unterliste vom Anfang", |   LISTS_GET_SUBLIST_START_FIRST: "erhalte Unterliste vom Anfang", | ||||||
|   LISTS_GET_SUBLIST_START_FROM_END: "erhalte Unterliste von # von hinten", |   LISTS_GET_SUBLIST_START_FROM_END: "erhalte Unterliste von # von hinten", | ||||||
|   LISTS_GET_SUBLIST_START_FROM_START: "erhalte Unterliste von #", |   LISTS_GET_SUBLIST_START_FROM_START: "erhalte Unterliste von #", | ||||||
|   LISTS_GET_SUBLIST_TAIL: "", |   LISTS_GET_SUBLIST_TAIL: "", | ||||||
|     LISTS_GET_SUBLIST_TOOLTIP: "Erstellt eine Kopie mit dem angegebenen Abschnitt der Liste.", |   LISTS_GET_SUBLIST_TOOLTIP: | ||||||
|  |     "Erstellt eine Kopie mit dem angegebenen Abschnitt der Liste.", | ||||||
|   LISTS_INDEX_OF_FIRST: "suche erstes Auftreten von", |   LISTS_INDEX_OF_FIRST: "suche erstes Auftreten von", | ||||||
|     LISTS_INDEX_OF_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", |   LISTS_INDEX_OF_HELPURL: | ||||||
|  |     "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", | ||||||
|   LISTS_INDEX_OF_LAST: "suche letztes Auftreten von", |   LISTS_INDEX_OF_LAST: "suche letztes Auftreten von", | ||||||
|     LISTS_INDEX_OF_TOOLTIP: "Sucht die Position (index) eines Elementes in der Liste. Gibt 0 zurück, falls kein Element gefunden wurde.", |   LISTS_INDEX_OF_TOOLTIP: | ||||||
|  |     "Sucht die Position (index) eines Elementes in der Liste. Gibt 0 zurück, falls kein Element gefunden wurde.", | ||||||
|   LISTS_INLIST: "von der Liste", |   LISTS_INLIST: "von der Liste", | ||||||
|     LISTS_ISEMPTY_HELPURL: "https://github.com/google/blockly/wiki/Lists#is-empty",  // untranslated
 |   LISTS_ISEMPTY_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#is-empty", // untranslated
 | ||||||
|   LISTS_ISEMPTY_TITLE: "%1 ist leer?", |   LISTS_ISEMPTY_TITLE: "%1 ist leer?", | ||||||
|   LISTS_ISEMPTY_TOOLTIP: "Ist wahr (true), wenn die Liste leer ist.", |   LISTS_ISEMPTY_TOOLTIP: "Ist wahr (true), wenn die Liste leer ist.", | ||||||
|     LISTS_LENGTH_HELPURL: "https://github.com/google/blockly/wiki/Lists#length-of",  // untranslated
 |   LISTS_LENGTH_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#length-of", // untranslated
 | ||||||
|   LISTS_LENGTH_TITLE: "Länge von %1", |   LISTS_LENGTH_TITLE: "Länge von %1", | ||||||
|   LISTS_LENGTH_TOOLTIP: "Die Anzahl von Elementen in der Liste.", |   LISTS_LENGTH_TOOLTIP: "Die Anzahl von Elementen in der Liste.", | ||||||
|     LISTS_REPEAT_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", |   LISTS_REPEAT_HELPURL: | ||||||
|  |     "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", | ||||||
|   LISTS_REPEAT_TITLE: "Erzeuge Liste mit Element %1 wiederhole es %2 mal", |   LISTS_REPEAT_TITLE: "Erzeuge Liste mit Element %1 wiederhole es %2 mal", | ||||||
|     LISTS_REPEAT_TOOLTIP: "Erzeugt eine Liste mit einer variablen Anzahl von Elementen", |   LISTS_REPEAT_TOOLTIP: | ||||||
|     LISTS_SET_INDEX_HELPURL: "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", |     "Erzeugt eine Liste mit einer variablen Anzahl von Elementen", | ||||||
|  |   LISTS_SET_INDEX_HELPURL: | ||||||
|  |     "http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic:%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Farsubex.htm", | ||||||
|   LISTS_SET_INDEX_INPUT_TO: "ein", |   LISTS_SET_INDEX_INPUT_TO: "ein", | ||||||
|   LISTS_SET_INDEX_INSERT: "füge", |   LISTS_SET_INDEX_INSERT: "füge", | ||||||
|   LISTS_SET_INDEX_SET: "setze", |   LISTS_SET_INDEX_SET: "setze", | ||||||
|     LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST: "Fügt das Element an den Anfang der Liste an.", |   LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST: | ||||||
|     LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_END: "Fügt das Element an der angegebenen Position in der Liste ein.  #1 ist das letzte Element.", |     "Fügt das Element an den Anfang der Liste an.", | ||||||
|     LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_START: "Fügt das Element an der angegebenen Position in der Liste ein.  #1 ist die erste Element.", |   LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_END: | ||||||
|     LISTS_SET_INDEX_TOOLTIP_INSERT_LAST: "Fügt das Element ans Ende der Liste an.", |     "Fügt das Element an der angegebenen Position in der Liste ein.  #1 ist das letzte Element.", | ||||||
|     LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM: "Fügt das Element zufällig in die Liste ein.", |   LISTS_SET_INDEX_TOOLTIP_INSERT_FROM_START: | ||||||
|  |     "Fügt das Element an der angegebenen Position in der Liste ein.  #1 ist die erste Element.", | ||||||
|  |   LISTS_SET_INDEX_TOOLTIP_INSERT_LAST: | ||||||
|  |     "Fügt das Element ans Ende der Liste an.", | ||||||
|  |   LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM: | ||||||
|  |     "Fügt das Element zufällig in die Liste ein.", | ||||||
|   LISTS_SET_INDEX_TOOLTIP_SET_FIRST: "Setzt das erste Element in der Liste.", |   LISTS_SET_INDEX_TOOLTIP_SET_FIRST: "Setzt das erste Element in der Liste.", | ||||||
|     LISTS_SET_INDEX_TOOLTIP_SET_FROM_END: "Setzt das Element an der angegebenen Position in der Liste.  #1 ist das letzte Element.", |   LISTS_SET_INDEX_TOOLTIP_SET_FROM_END: | ||||||
|     LISTS_SET_INDEX_TOOLTIP_SET_FROM_START: "Setzte das Element an der angegebenen Position in der Liste.  #1 ist das erste Element.", |     "Setzt das Element an der angegebenen Position in der Liste.  #1 ist das letzte Element.", | ||||||
|  |   LISTS_SET_INDEX_TOOLTIP_SET_FROM_START: | ||||||
|  |     "Setzte das Element an der angegebenen Position in der Liste.  #1 ist das erste Element.", | ||||||
|   LISTS_SET_INDEX_TOOLTIP_SET_LAST: "Setzt das letzte Element in der Liste.", |   LISTS_SET_INDEX_TOOLTIP_SET_LAST: "Setzt das letzte Element in der Liste.", | ||||||
|     LISTS_SET_INDEX_TOOLTIP_SET_RANDOM: "Setzt ein zufälliges Element in der Liste.", |   LISTS_SET_INDEX_TOOLTIP_SET_RANDOM: | ||||||
|     LISTS_SORT_HELPURL: "https://github.com/google/blockly/wiki/Lists#sorting-a-list", |     "Setzt ein zufälliges Element in der Liste.", | ||||||
|  |   LISTS_SORT_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#sorting-a-list", | ||||||
|   LISTS_SORT_ORDER_ASCENDING: "aufsteigend", |   LISTS_SORT_ORDER_ASCENDING: "aufsteigend", | ||||||
|   LISTS_SORT_ORDER_DESCENDING: "absteigend", |   LISTS_SORT_ORDER_DESCENDING: "absteigend", | ||||||
|   LISTS_SORT_TITLE: "%1 %2 %3 sortieren", |   LISTS_SORT_TITLE: "%1 %2 %3 sortieren", | ||||||
| @ -95,11 +130,14 @@ export const TRANSLATIONS = { | |||||||
|   LISTS_SORT_TYPE_IGNORECASE: "alphabetisch, Schreibung ignorieren", |   LISTS_SORT_TYPE_IGNORECASE: "alphabetisch, Schreibung ignorieren", | ||||||
|   LISTS_SORT_TYPE_NUMERIC: "numerisch", |   LISTS_SORT_TYPE_NUMERIC: "numerisch", | ||||||
|   LISTS_SORT_TYPE_TEXT: "alphabetisch", |   LISTS_SORT_TYPE_TEXT: "alphabetisch", | ||||||
|     LISTS_SPLIT_HELPURL: "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists", |   LISTS_SPLIT_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists", | ||||||
|   LISTS_SPLIT_LIST_FROM_TEXT: "Liste aus Text erstellen", |   LISTS_SPLIT_LIST_FROM_TEXT: "Liste aus Text erstellen", | ||||||
|   LISTS_SPLIT_TEXT_FROM_LIST: "Text aus Liste erstellen", |   LISTS_SPLIT_TEXT_FROM_LIST: "Text aus Liste erstellen", | ||||||
|     LISTS_SPLIT_TOOLTIP_JOIN: "Liste mit Texten in einen Text vereinen, getrennt durch ein Trennzeichen.", |   LISTS_SPLIT_TOOLTIP_JOIN: | ||||||
|     LISTS_SPLIT_TOOLTIP_SPLIT: "Text in eine Liste mit Texten aufteilen, unterbrochen bei jedem Trennzeichen.", |     "Liste mit Texten in einen Text vereinen, getrennt durch ein Trennzeichen.", | ||||||
|  |   LISTS_SPLIT_TOOLTIP_SPLIT: | ||||||
|  |     "Text in eine Liste mit Texten aufteilen, unterbrochen bei jedem Trennzeichen.", | ||||||
|   LISTS_SPLIT_WITH_DELIMITER: "mit Trennzeichen", |   LISTS_SPLIT_WITH_DELIMITER: "mit Trennzeichen", | ||||||
|   LOGIC_BOOLEAN_FALSE: "falsch", |   LOGIC_BOOLEAN_FALSE: "falsch", | ||||||
| 
 | 
 | ||||||
| @ -108,49 +146,61 @@ export const TRANSLATIONS = { | |||||||
|   NEW_VARIABLE_TITLE: "Name der neuen Variable:", |   NEW_VARIABLE_TITLE: "Name der neuen Variable:", | ||||||
|   ORDINAL_NUMBER_SUFFIX: "", |   ORDINAL_NUMBER_SUFFIX: "", | ||||||
|   PROCEDURES_ALLOW_STATEMENTS: "Aussagen erlauben", |   PROCEDURES_ALLOW_STATEMENTS: "Aussagen erlauben", | ||||||
|     PROCEDURES_CALLNORETURN_HELPURL: "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", |   PROCEDURES_CALLNORETURN_HELPURL: | ||||||
|     PROCEDURES_CALLNORETURN_TOOLTIP: "Rufe einen Funktionsblock ohne Rückgabewert auf.", |     "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", | ||||||
|     PROCEDURES_CALLRETURN_HELPURL: "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", |   PROCEDURES_CALLNORETURN_TOOLTIP: | ||||||
|     PROCEDURES_CALLRETURN_TOOLTIP: "Rufe einen Funktionsblock mit Rückgabewert auf.", |     "Rufe einen Funktionsblock ohne Rückgabewert auf.", | ||||||
|  |   PROCEDURES_CALLRETURN_HELPURL: | ||||||
|  |     "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", | ||||||
|  |   PROCEDURES_CALLRETURN_TOOLTIP: | ||||||
|  |     "Rufe einen Funktionsblock mit Rückgabewert auf.", | ||||||
|   PROCEDURES_CALL: "Rufe", |   PROCEDURES_CALL: "Rufe", | ||||||
|   PROCEDURES_CALL_END: "auf", |   PROCEDURES_CALL_END: "auf", | ||||||
|   PROCEDURES_DEFNORETURN: "Erstelle Funktion", |   PROCEDURES_DEFNORETURN: "Erstelle Funktion", | ||||||
|   PROCEDURES_BEFORE_PARAMS: "mit Eingabeparameter:", |   PROCEDURES_BEFORE_PARAMS: "mit Eingabeparameter:", | ||||||
|   PROCEDURES_DEFRETURN_RETURN_TYPE: "Rückgabetype", |   PROCEDURES_DEFRETURN_RETURN_TYPE: "Rückgabetype", | ||||||
|   PROCEDURES_CALL_BEFORE_PARAMS: "mit:", |   PROCEDURES_CALL_BEFORE_PARAMS: "mit:", | ||||||
|     PROCEDURES_CREATE_DO: "Erzeuge \"Aufruf %1\"", |   PROCEDURES_CREATE_DO: 'Erzeuge "Aufruf %1"', | ||||||
|   PROCEDURES_DEFNORETURN_COMMENT: "Beschreibe diese Funktion …", |   PROCEDURES_DEFNORETURN_COMMENT: "Beschreibe diese Funktion …", | ||||||
|   PROCEDURES_DEFNORETURN_DO: "", |   PROCEDURES_DEFNORETURN_DO: "", | ||||||
|     PROCEDURES_DEFNORETURN_HELPURL: "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", |   PROCEDURES_DEFNORETURN_HELPURL: | ||||||
|  |     "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", | ||||||
|   PROCEDURES_DEFNORETURN_PROCEDURE: "Funktionsblock", |   PROCEDURES_DEFNORETURN_PROCEDURE: "Funktionsblock", | ||||||
|   PROCEDURES_DEFNORETURN_TITLE: "zu", |   PROCEDURES_DEFNORETURN_TITLE: "zu", | ||||||
|   PROCEDURES_DEFNORETURN_TOOLTIP: "Ein Funktionsblock ohne Rückgabewert.", |   PROCEDURES_DEFNORETURN_TOOLTIP: "Ein Funktionsblock ohne Rückgabewert.", | ||||||
|     PROCEDURES_DEFRETURN_HELPURL: "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", |   PROCEDURES_DEFRETURN_HELPURL: | ||||||
|  |     "https://de.wikipedia.org/wiki/Prozedur_%28Programmierung%29", | ||||||
|   PROCEDURES_DEFRETURN_RETURN: "gebe zurück", |   PROCEDURES_DEFRETURN_RETURN: "gebe zurück", | ||||||
|   PROCEDURES_DEFRETURN_TOOLTIP: "Ein Funktionsblock mit Rückgabewert.", |   PROCEDURES_DEFRETURN_TOOLTIP: "Ein Funktionsblock mit Rückgabewert.", | ||||||
|     PROCEDURES_DEF_DUPLICATE_WARNING: "Warnung: dieser Funktionsblock hat zwei gleich benannte Parameter.", |   PROCEDURES_DEF_DUPLICATE_WARNING: | ||||||
|  |     "Warnung: dieser Funktionsblock hat zwei gleich benannte Parameter.", | ||||||
|   PROCEDURES_HIGHLIGHT_DEF: "Markiere Funktionsblock", |   PROCEDURES_HIGHLIGHT_DEF: "Markiere Funktionsblock", | ||||||
|   PROCEDURES_IFRETURN_HELPURL: "http://c2.com/cgi/wiki?GuardClause", |   PROCEDURES_IFRETURN_HELPURL: "http://c2.com/cgi/wiki?GuardClause", | ||||||
|     PROCEDURES_IFRETURN_TOOLTIP: "Wenn der erste Wert wahr (true) ist, Gebe den zweiten Wert zurück.", |   PROCEDURES_IFRETURN_TOOLTIP: | ||||||
|     PROCEDURES_IFRETURN_WARNING: "Warnung: Dieser Block darf nur innerhalb eines Funktionsblock genutzt werden.", |     "Wenn der erste Wert wahr (true) ist, Gebe den zweiten Wert zurück.", | ||||||
|  |   PROCEDURES_IFRETURN_WARNING: | ||||||
|  |     "Warnung: Dieser Block darf nur innerhalb eines Funktionsblock genutzt werden.", | ||||||
|   PROCEDURES_MUTATORARG_TITLE: "Variable:", |   PROCEDURES_MUTATORARG_TITLE: "Variable:", | ||||||
|   PROCEDURES_MUTATORARG_TOOLTIP: "Eine Eingabe zur Funktion hinzufügen.", |   PROCEDURES_MUTATORARG_TOOLTIP: "Eine Eingabe zur Funktion hinzufügen.", | ||||||
|   PROCEDURES_MUTATORCONTAINER_TITLE: "Parameter", |   PROCEDURES_MUTATORCONTAINER_TITLE: "Parameter", | ||||||
|     PROCEDURES_MUTATORCONTAINER_TOOLTIP: "Die Eingaben zu dieser Funktion hinzufügen, entfernen oder neu anordnen.", |   PROCEDURES_MUTATORCONTAINER_TOOLTIP: | ||||||
|  |     "Die Eingaben zu dieser Funktion hinzufügen, entfernen oder neu anordnen.", | ||||||
|   REDO: "Wiederholen", |   REDO: "Wiederholen", | ||||||
|   REMOVE_COMMENT: "Kommentar entfernen", |   REMOVE_COMMENT: "Kommentar entfernen", | ||||||
|   RENAME_VARIABLE: "Variable umbenennen...", |   RENAME_VARIABLE: "Variable umbenennen...", | ||||||
|     RENAME_VARIABLE_TITLE: "Alle \"%1\" Variablen umbenennen in:", |   RENAME_VARIABLE_TITLE: 'Alle "%1" Variablen umbenennen in:', | ||||||
| 
 | 
 | ||||||
|   TODAY: "Heute", |   TODAY: "Heute", | ||||||
|   UNDO: "Rückgängig", |   UNDO: "Rückgängig", | ||||||
|   VARIABLES_DEFAULT_NAME: "Element", |   VARIABLES_DEFAULT_NAME: "Element", | ||||||
|     VARIABLES_GET_CREATE_SET: "Erzeuge \"Schreibe %1\"", |   VARIABLES_GET_CREATE_SET: 'Erzeuge "Schreibe %1"', | ||||||
|     VARIABLES_GET_HELPURL: "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29", |   VARIABLES_GET_HELPURL: | ||||||
|  |     "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29", | ||||||
|   VARIABLES_GET_TOOLTIP: "Gibt den Wert der Variable zurück.", |   VARIABLES_GET_TOOLTIP: "Gibt den Wert der Variable zurück.", | ||||||
|   VARIABLES_SET: "Schreibe %1 %2", |   VARIABLES_SET: "Schreibe %1 %2", | ||||||
|     VARIABLES_SET_CREATE_GET: "Erzeuge \"Lese %1\"", |   VARIABLES_SET_CREATE_GET: 'Erzeuge "Lese %1"', | ||||||
|     VARIABLES_SET_HELPURL: "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29", |   VARIABLES_SET_HELPURL: | ||||||
|  |     "https://de.wikipedia.org/wiki/Variable_%28Programmierung%29", | ||||||
|   VARIABLES_SET_TOOLTIP: "Setzt den Wert einer Variable.", |   VARIABLES_SET_TOOLTIP: "Setzt den Wert einer Variable.", | ||||||
|   MATH_CHANGE_TITLE_ITEM: "Element", |   MATH_CHANGE_TITLE_ITEM: "Element", | ||||||
|   PROCEDURES_DEFRETURN_TITLE: "zu", |   PROCEDURES_DEFRETURN_TITLE: "zu", | ||||||
| @ -163,7 +213,8 @@ export const TRANSLATIONS = { | |||||||
|   LISTS_GET_INDEX_INPUT_IN_LIST: "in der Liste", |   LISTS_GET_INDEX_INPUT_IN_LIST: "in der Liste", | ||||||
|   PROCEDURES_DEFRETURN_DO: "", |   PROCEDURES_DEFRETURN_DO: "", | ||||||
|   CONTROLS_IF_ELSEIF_TITLE_ELSEIF: "sonst wenn", |   CONTROLS_IF_ELSEIF_TITLE_ELSEIF: "sonst wenn", | ||||||
|     LISTS_GET_INDEX_HELPURL: "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list", |   LISTS_GET_INDEX_HELPURL: | ||||||
|  |     "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list", | ||||||
|   CONTROLS_FOREACH_INPUT_DO: "mache", |   CONTROLS_FOREACH_INPUT_DO: "mache", | ||||||
|   LISTS_SET_INDEX_INPUT_IN_LIST: "in der Liste", |   LISTS_SET_INDEX_INPUT_IN_LIST: "in der Liste", | ||||||
|   CONTROLS_FOR_INPUT_DO: "mache", |   CONTROLS_FOR_INPUT_DO: "mache", | ||||||
| @ -190,12 +241,15 @@ export const TRANSLATIONS = { | |||||||
|   senseBox_output_safetosd: "Auf SD Karte speichern", |   senseBox_output_safetosd: "Auf SD Karte speichern", | ||||||
|   senseBox_output_safetosd_tip: "Speichert Messwerte auf SD Karte", |   senseBox_output_safetosd_tip: "Speichert Messwerte auf SD Karte", | ||||||
|   senseBox_output_serialprint: "Auf Kommandozeile ausgeben", |   senseBox_output_serialprint: "Auf Kommandozeile ausgeben", | ||||||
|     senseBox_serial_tip: "Gibt Messwerte oder Daten auf dem Seriellen Monitor der Arduino IDE aus. Praktisch um ohne Display zu arbeiten", |   senseBox_serial_tip: | ||||||
|     senseBox_output_timestamp: "Zeitstempel", |     "Gibt Messwerte oder Daten auf dem Seriellen Monitor der Arduino IDE aus. Praktisch um ohne Display zu arbeiten", | ||||||
|  |   senseBox_output_timestamp: "Zeitstempel (RFC 3339)", | ||||||
|   senseBox_led: "LED an digitalen", |   senseBox_led: "LED an digitalen", | ||||||
|     senseBox_led_tip: "Einfache LED. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden", |   senseBox_led_tip: | ||||||
|  |     "Einfache LED. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden", | ||||||
|   senseBox_piezo: "Piezo an digital", |   senseBox_piezo: "Piezo an digital", | ||||||
|     senseBox_piezo_tip: "Piezo an digital PIN. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden", |   senseBox_piezo_tip: | ||||||
|  |     "Piezo an digital PIN. Beim Anschluss sollte immer ein Vorwiderstand verwendet werden", | ||||||
|   senseBox_foto: "Fotowiderstand", |   senseBox_foto: "Fotowiderstand", | ||||||
|   senseBox_foto_tip: "Fotowiderstand", |   senseBox_foto_tip: "Fotowiderstand", | ||||||
|   senseBox_hum: "Luftfeuchtigkeit in %", |   senseBox_hum: "Luftfeuchtigkeit in %", | ||||||
| @ -208,5 +262,4 @@ export const TRANSLATIONS = { | |||||||
|   senseBox_poti_tip: "Potenziometer", |   senseBox_poti_tip: "Potenziometer", | ||||||
|   senseBox_soil: "Bodenfeuchte", |   senseBox_soil: "Bodenfeuchte", | ||||||
|   senseBox_watertemperature: "Wassertemperatur", |   senseBox_watertemperature: "Wassertemperatur", | ||||||
| 
 | }; | ||||||
| } |  | ||||||
|  | |||||||
| @ -726,7 +726,7 @@ Blockly.Msg.senseBox_output_safetosd_tip = "Speichert Messwerte auf SD Karte"; | |||||||
| Blockly.Msg.senseBox_output_serialprint = "Auf Kommandozeile ausgeben"; | Blockly.Msg.senseBox_output_serialprint = "Auf Kommandozeile ausgeben"; | ||||||
| Blockly.Msg.senseBox_serial_tip = | Blockly.Msg.senseBox_serial_tip = | ||||||
|   "Gibt Messwerte oder Daten auf dem Seriellen Monitor der Arduino IDE aus. Praktisch um ohne Display zu arbeiten"; |   "Gibt Messwerte oder Daten auf dem Seriellen Monitor der Arduino IDE aus. Praktisch um ohne Display zu arbeiten"; | ||||||
| Blockly.Msg.senseBox_output_timestamp = "Zeitstempel"; | Blockly.Msg.senseBox_output_timestamp = "Zeitstempel (RFC 3339)"; | ||||||
| 
 | 
 | ||||||
| Blockly.Msg.senseBox_led = "LED an digitalen"; | Blockly.Msg.senseBox_led = "LED an digitalen"; | ||||||
| Blockly.Msg.senseBox_led_tip = | Blockly.Msg.senseBox_led_tip = | ||||||
|  | |||||||
| @ -5,11 +5,19 @@ export const SD = { | |||||||
|   senseBox_sd_create_file: "Create file on SD-Card", |   senseBox_sd_create_file: "Create file on SD-Card", | ||||||
|   senseBox_sd_write_file: " Write Data to SD-Card", |   senseBox_sd_write_file: " Write Data to SD-Card", | ||||||
|   senseBox_sd_open_file: "Open a file from SD-Card", |   senseBox_sd_open_file: "Open a file from SD-Card", | ||||||
|     senseBox_sd_create_file_tooltip: "Creates a file on the card. Plug the SD-Bee into the **XBEE2** slot. The **maximum** length of the file name is **8 characters**. The file should be created first in *Setup()*", |   senseBox_sd_create_file_tooltip: | ||||||
|     senseBox_sd_write_file_tooptip: "Write data to the SD card. Note that the file must be opened first.", |     "Creates a file on the card. Plug the SD-Bee into the **XBEE2** slot. The **maximum** length of the file name is **8 characters**. The file should be created first in *Setup()*", | ||||||
|     senseBox_sd_open_file_tooltip: "Open the file on the SD card to save files. At the end of the loop, the file will be closed again automatically.", |   senseBox_sd_write_file_tooptip: | ||||||
|     sensebox_sd_filename: "Data.txt", |     "Write data to the SD card. Note that the file must be opened first.", | ||||||
|  |   senseBox_sd_open_file_tooltip: | ||||||
|  |     "Open the file on the SD card to save files. At the end of the loop, the file will be closed again automatically.", | ||||||
|  |   sensebox_sd_filename: "Data.csv", | ||||||
|   senseBox_sd_decimals: "decimals", |   senseBox_sd_decimals: "decimals", | ||||||
| 
 |   sensebox_sd_osem: "Create CSV-file for openSenseMap", | ||||||
| } |   sensebox_sd_osem_tip: "Creates a CSV-file for openSenseMap upload", | ||||||
| 
 |   sensebox_sd_save_for_osem: "Save measurement", | ||||||
|  |   sensebox_sd_save_for_osem_tip: | ||||||
|  |     "Adds a measurement witht the corresponding Sensor ID to the CSV-file", | ||||||
|  |   sensebox_sd_save_for_osem_id: "Sensor ID:", | ||||||
|  |   sensebox_sd_measurement: "measurements", | ||||||
|  | }; | ||||||
|  | |||||||
| @ -102,6 +102,17 @@ class Toolbox extends React.Component { | |||||||
|             </Value> |             </Value> | ||||||
|           </Block> |           </Block> | ||||||
|           <Block type="sensebox_sd_write_file" /> |           <Block type="sensebox_sd_write_file" /> | ||||||
|  |           <Block type="sensebox_sd_open_file"> | ||||||
|  |             <Value name="SD"> | ||||||
|  |               <Block type="sensebox_sd_osem"> | ||||||
|  |                 <Value name="DO"> | ||||||
|  |                   <Block type="sensebox_sd_save_for_osem"></Block> | ||||||
|  |                 </Value> | ||||||
|  |               </Block> | ||||||
|  |             </Value> | ||||||
|  |           </Block> | ||||||
|  |           <Block type="sensebox_sd_osem" /> | ||||||
|  |           <Block type="sensebox_sd_save_for_osem" /> | ||||||
|         </Category> |         </Category> | ||||||
|         <Category name="LED" colour={getColour().sensebox}> |         <Category name="LED" colour={getColour().sensebox}> | ||||||
|           <Block type="sensebox_rgb_led"></Block> |           <Block type="sensebox_rgb_led"></Block> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user