commit
						c009674c46
					
				
							
								
								
									
										2
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| REACT_APP_COMPILER_URL=https://compiler.sensebox.de | ||||
| REACT_APP_BOARD=sensebox-mcu | ||||
| @ -17,6 +17,7 @@ const theme = createMuiTheme({ | ||||
|   palette: { | ||||
|     primary: { | ||||
|       main: '#4EAF47', | ||||
|       contrastText: '#ffffff' | ||||
|     }, | ||||
|     secondary: { | ||||
|       main: '#DDDDDD' | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| #blocklyDiv { | ||||
|   height: 100%; | ||||
|   min-height: 500px; | ||||
|   min-height: 700px; | ||||
|   width: 100%; | ||||
|   border: 1px solid #4EAF47; | ||||
|   /* border: 1px solid #4EAF47; */ | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| @ -25,10 +25,14 @@ import React from 'react'; | ||||
| import './BlocklyComponent.css'; | ||||
| 
 | ||||
| import Blockly from 'blockly/core'; | ||||
| //import locale from 'blockly/msg/en'; | ||||
| import locale from 'blockly/msg/en'; | ||||
| import 'blockly/blocks'; | ||||
| import Toolbox from './toolbox/Toolbox'; | ||||
| 
 | ||||
| //Blockly.setLocale(locale); | ||||
| import { Card } from '@material-ui/core'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.setLocale(locale); | ||||
| 
 | ||||
| class BlocklyComponent extends React.Component { | ||||
|     constructor(props) { | ||||
| @ -61,13 +65,11 @@ class BlocklyComponent extends React.Component { | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         const { children } = this.props; | ||||
| 
 | ||||
| 
 | ||||
|         return <React.Fragment> | ||||
|             <div ref={this.blocklyDiv} id="blocklyDiv" /> | ||||
|             <xml xmlns="https://developers.google.com/blockly/xml" is="blockly" style={{ display: 'none' }} ref={this.toolbox}> | ||||
|                 {children} | ||||
|             </xml> | ||||
|             <Card ref={this.blocklyDiv} id="blocklyDiv" /> | ||||
|             <Toolbox toolbox={this.toolbox} /> | ||||
|         </React.Fragment>; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,20 +2,20 @@ import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { onChangeWorkspace } from '../../actions/workspaceActions'; | ||||
| 
 | ||||
| import BlocklyComponent, { Block, Value, Field, Shadow, Category } from './'; | ||||
| import * as De from './msg/de'; | ||||
| import BlocklyComponent from './'; | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import * as De from './msg/de'; // de locale files
 | ||||
| //import * as En from './Blockly/msg/en'; // de locale files
 | ||||
| import './blocks/index'; | ||||
| import './generator/index'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class BlocklyWindow extends Component { | ||||
| 
 | ||||
|   constructor(props) { | ||||
|     super(props); | ||||
|     this.simpleWorkspace = React.createRef(); | ||||
|     Blockly.setLocale(De); | ||||
|   } | ||||
| 
 | ||||
|   componentDidMount() { | ||||
| @ -23,6 +23,7 @@ class BlocklyWindow extends Component { | ||||
|     this.props.onChangeWorkspace({}); | ||||
|     workspace.addChangeListener((event) => { | ||||
|       this.props.onChangeWorkspace(event); | ||||
|       Blockly.Events.disableOrphans(event); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -31,10 +32,11 @@ class BlocklyWindow extends Component { | ||||
|       <BlocklyComponent ref={this.simpleWorkspace} | ||||
|         readOnly={false} | ||||
|         trashcan={true} | ||||
|         renderer='zelos' | ||||
|         zoom={{ // https://developers.google.com/blockly/guides/configure/web/zoom
 | ||||
|           controls: true, | ||||
|           wheel: true, | ||||
|           startScale: 1.0, | ||||
|           wheel: false, | ||||
|           startScale: 0.8, | ||||
|           maxScale: 3, | ||||
|           minScale: 0.3, | ||||
|           scaleSpeed: 1.2 | ||||
| @ -51,27 +53,10 @@ class BlocklyWindow extends Component { | ||||
|           drag: true, | ||||
|           wheel: false | ||||
|         }} | ||||
|         initialXml={''} | ||||
|         initialXml={`<xml xmlns="https://developers.google.com/blockly/xml">
 | ||||
|           <block type="arduino_functions" id="QWW|$jB8+*EL;}|#uA" x="27" y="16"></block></xml>`} | ||||
|       > | ||||
|         <Category name="loops" > | ||||
|           <Block type="controls_for" /> | ||||
|           <Block type="controls_repeat_ext" /> | ||||
|           <Block type="controls_whileUntil" /> | ||||
|         </Category> | ||||
|         <Category name="senseBox" colour="120" > | ||||
|           <Category name="Sensoren" colour="120" > | ||||
|             <Block type="sensebox_sensor_temp_hum"></Block> | ||||
|           </Category> | ||||
|           <Block type="sensebox_telegram" /> | ||||
|         </Category> | ||||
|         <Category name="Logic" colour="#b063c5"> | ||||
|           <Block type="control_if"></Block> | ||||
|           <Block type="controls_ifelse"></Block> | ||||
|           <Block type="logic_compare"></Block> | ||||
|           <Block type="logic_operation"></Block> | ||||
|           <Block type="logic_negate"></Block> | ||||
|           <Block type="logic_boolean"></Block> | ||||
|         </Category> | ||||
| 
 | ||||
|       </BlocklyComponent > | ||||
|     ); | ||||
|   }; | ||||
|  | ||||
| @ -2,3 +2,16 @@ import './loops'; | ||||
| import './sensebox'; | ||||
| import './logic'; | ||||
| import './sensebox-sensors'; | ||||
| import './sensebox-telegram'; | ||||
| import './sensebox-osem'; | ||||
| import './sensebox-web'; | ||||
| import './sensebox-display'; | ||||
| import './sensebox-lora'; | ||||
| import './io'; | ||||
| import './math'; | ||||
| import './map'; | ||||
| import './procedures'; | ||||
| import './time'; | ||||
| 
 | ||||
| 
 | ||||
| import '../helpers/types' | ||||
							
								
								
									
										257
									
								
								src/components/Blockly/blocks/io.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								src/components/Blockly/blocks/io.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,257 @@ | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Blocks for Arduino Digital and Analogue input and output | ||||
|  *     functions. The Arduino function syntax can be found at | ||||
|  *     http://arduino.cc/en/Reference/HomePage
 | ||||
|  * | ||||
|  * TODO: maybe change this to a "PIN" BlocklyType | ||||
|  */ | ||||
| import Blockly from 'blockly/core'; | ||||
| import { selectedBoard } from '../helpers/board' | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['io_digitalwrite'] = { | ||||
|     /** | ||||
|      * Block for creating a 'set pin' to a state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('STATE') | ||||
|             .appendField(Blockly.Msg.ARD_DIGITALWRITE) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().digitalPins), 'PIN') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.BOOLEAN.checkList); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'PIN', 'digitalPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_digitalread'] = { | ||||
|     /** | ||||
|      * Block for creating a 'read pin'. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalRead'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_DIGITALREAD) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().digitalPins), 'PIN'); | ||||
|         this.setOutput(true, Types.BOOLEAN); | ||||
|         this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'PIN', 'digitalPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_builtin_led'] = { | ||||
|     /** | ||||
|      * Block for setting built-in LED to a state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('STATE') | ||||
|             .appendField(Blockly.Msg.ARD_BUILTIN_LED) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().builtinLed), 'BUILT_IN_LED') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.BOOLEAN.compatibleTypes); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown( | ||||
|             this, 'BUILT_IN_LED', 'builtinLed'); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_analogwrite'] = { | ||||
|     /** | ||||
|      * Block for creating a 'set pin' to an analogue value. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogWrite'); | ||||
|         this.setColour(250); | ||||
|         this.appendValueInput('NUM') | ||||
|             .appendField(Blockly.Msg.ARD_ANALOGWRITE) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().pwmPins), 'PIN') | ||||
|             .appendField(Blockly.Msg.ARD_WRITE_TO) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'pwmPins'); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER; | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_analogread'] = { | ||||
|     /** | ||||
|      * Block for reading an analogue input. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/AnalogRead'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_ANALOGREAD) | ||||
|             .appendField(new Blockly.FieldDropdown( | ||||
|                 selectedBoard().analogPins), 'PIN'); | ||||
|         this.setOutput(true, Types.NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_ANALOGREAD_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     }, | ||||
|     /** | ||||
|      * Updates the content of the the pin related fields. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     updateFields: function () { | ||||
|         Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'analogPins'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_highlow'] = { | ||||
|     /** | ||||
|      * Block for creating a pin state. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Constants'); | ||||
|         this.setColour(250); | ||||
|         this.appendDummyInput() | ||||
|             .appendField( | ||||
|                 new Blockly.FieldDropdown([[Blockly.Msg.ARD_HIGH, 'HIGH'], [Blockly.Msg.ARD_LOW, 'LOW']]), | ||||
|                 'STATE'); | ||||
|         this.setOutput(true, Types.BOOLEAN.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP); | ||||
|     }, | ||||
|     /** @return {!string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.BOOLEAN; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_pulsein'] = { | ||||
|     /** | ||||
|      * Block for measuring the duration of a pulse in an input pin. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.jsonInit({ | ||||
|             "type": "math_foo", | ||||
|             "message0": Blockly.Msg.ARD_PULSE_READ, | ||||
|             "args0": [{ | ||||
|                 "type": "input_value", | ||||
|                 "name": "PULSETYPE", | ||||
|                 "check": Types.BOOLEAN.compatibleTypes | ||||
|             }, { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "PULSEPIN", | ||||
|                 "options": selectedBoard().digitalPins, | ||||
|             } | ||||
|             ], | ||||
|             "output": Types.NUMBER.typeId, | ||||
|             "inputsInline": true, | ||||
|             "colour": 250, | ||||
|             "tooltip": Blockly.Msg.ARD_PULSE_TIP, | ||||
|             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||
|         }); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['io_pulsetimeout'] = { | ||||
|     /** | ||||
|      * Block for measuring (with a time-out) the duration of a pulse in an input | ||||
|      * pin. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.jsonInit({ | ||||
|             "type": "math_foo", | ||||
|             "message0": Blockly.Msg.ARD_PULSE_READ_TIMEOUT, | ||||
|             "args0": [{ | ||||
|                 "type": "input_value", | ||||
|                 "name": "PULSETYPE", | ||||
|                 "check": Types.BOOLEAN.compatibleTypes | ||||
|             }, { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "PULSEPIN", | ||||
|                 "options": selectedBoard().digitalPins, | ||||
|             }, { | ||||
|                 "type": "input_value", | ||||
|                 "name": "TIMEOUT", | ||||
|                 "check": Types.NUMBER.compatibleTypes | ||||
|             } | ||||
|             ], | ||||
|             "output": Types.NUMBER.typeId, | ||||
|             "inputsInline": true, | ||||
|             "colour": 250, | ||||
|             "tooltip": Blockly.Msg.ARD_PULSETIMEOUT_TIP, | ||||
|             "helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn' | ||||
|         }); | ||||
|     }, | ||||
|     /** @return {!string} The type of input value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
| @ -1,61 +1,235 @@ | ||||
| import { defineBlocksWithJsonArray } from 'blockly'; | ||||
| import Blockly from 'blockly/core'; | ||||
| 
 | ||||
| defineBlocksWithJsonArray([ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Blockly.defineBlocksWithJsonArray([  // BEGIN JSON EXTRACT
 | ||||
|     // Block for boolean data type: true and false.
 | ||||
|     { | ||||
|         "type": "logic_boolean", | ||||
|         "message0": "%1", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "BOOL", | ||||
|                 "options": [ | ||||
|                     ["%{BKY_LOGIC_BOOLEAN_TRUE}", "TRUE"], | ||||
|                     ["%{BKY_LOGIC_BOOLEAN_FALSE}", "FALSE"] | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         "output": "Boolean", | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_LOGIC_BOOLEAN_TOOLTIP}", | ||||
|         "helpUrl": "%{BKY_LOGIC_BOOLEAN_HELPURL}" | ||||
|     }, | ||||
|     // Block for if/elseif/else condition.
 | ||||
|     { | ||||
|         "type": "controls_if", | ||||
|         "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "IF0", | ||||
|                 "check": "Boolean" | ||||
|             } | ||||
|         ], | ||||
|         "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1", | ||||
|         "args1": [ | ||||
|             { | ||||
|                 "type": "input_statement", | ||||
|                 "name": "DO0" | ||||
|             } | ||||
|         ], | ||||
|         "previousStatement": null, | ||||
|         "nextStatement": null, | ||||
|         "style": "logic_blocks", | ||||
|         "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}", | ||||
|         "mutator": "controls_if_mutator", | ||||
|         "extensions": ["controls_if_tooltip"] | ||||
|     }, | ||||
|     // If/else block that does not use a mutator.
 | ||||
|     { | ||||
|         type: 'control_if', | ||||
|         message0: '%{BKY_CONTROLS_IF_MSG_IF} %1', | ||||
|         args0: [ | ||||
|         "type": "controls_ifelse", | ||||
|         "message0": "%{BKY_CONTROLS_IF_MSG_IF} %1", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 type: 'input_value', | ||||
|                 name: 'IF0', | ||||
|                 check: 'Boolean' | ||||
|                 "type": "input_value", | ||||
|                 "name": "IF0", | ||||
|                 "check": "Boolean" | ||||
|             } | ||||
|         ], | ||||
|         message1: '%{BKY_CONTROLS_IF_MSG_THEN} %1', | ||||
|         args1: [ | ||||
|         "message1": "%{BKY_CONTROLS_IF_MSG_THEN} %1", | ||||
|         "args1": [ | ||||
|             { | ||||
|                 type: 'input_statement', | ||||
|                 name: 'DO0' | ||||
|                 "type": "input_statement", | ||||
|                 "name": "DO0" | ||||
|             } | ||||
|         ], | ||||
|         previousStatement: null, | ||||
|         nextStatement: null, | ||||
|         colour: '#b063c5', | ||||
|         tooltip: '%{BKYCONTROLS_IF_TOOLTIP_2}', | ||||
|         helpUrl: '%{BKY_CONTROLS_IF_HELPURL}', | ||||
|         extensions: ['controls_if_tooltip'] | ||||
|         "message2": "%{BKY_CONTROLS_IF_MSG_ELSE} %1", | ||||
|         "args2": [ | ||||
|             { | ||||
|                 "type": "input_statement", | ||||
|                 "name": "ELSE" | ||||
|             } | ||||
|         ], | ||||
|         "previousStatement": null, | ||||
|         "nextStatement": null, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKYCONTROLS_IF_TOOLTIP_2}", | ||||
|         "helpUrl": "%{BKY_CONTROLS_IF_HELPURL}", | ||||
|         "extensions": ["controls_if_tooltip"] | ||||
|     }, | ||||
|     // Block for comparison operator.
 | ||||
|     { | ||||
|         "type": "logic_compare", | ||||
|         "message0": "%1 %2 %3", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "A" | ||||
|             }, | ||||
|             { | ||||
|         type: 'controls_ifelse', | ||||
|         message0: '%{BKY_CONTROLS_IF_MSG_IF} %1', | ||||
|         args0: [ | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "OP", | ||||
|                 "options": [ | ||||
|                     ["=", "EQ"], | ||||
|                     ["\u2260", "NEQ"], | ||||
|                     ["\u200F<", "LT"], | ||||
|                     ["\u200F\u2264", "LTE"], | ||||
|                     ["\u200F>", "GT"], | ||||
|                     ["\u200F\u2265", "GTE"] | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 type: 'input_value', | ||||
|                 name: 'IF0', | ||||
|                 check: 'Boolean' | ||||
|                 "type": "input_value", | ||||
|                 "name": "B" | ||||
|             } | ||||
|         ], | ||||
|         message1: '%{BKY_CONTROLS_IF_MSG_THEN} %1', | ||||
|         args1: [ | ||||
|         "inputsInline": true, | ||||
|         "output": "Boolean", | ||||
|         "style": "logic_blocks", | ||||
|         "helpUrl": "%{BKY_LOGIC_COMPARE_HELPURL}", | ||||
|         "extensions": ["logic_compare", "logic_op_tooltip"] | ||||
|     }, | ||||
|     // Block for logical operations: 'and', 'or'.
 | ||||
|     { | ||||
|                 type: 'input_statement', | ||||
|                 name: 'DO0' | ||||
|         "type": "logic_operation", | ||||
|         "message0": "%1 %2 %3", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "A", | ||||
|                 "check": "Boolean" | ||||
|             }, | ||||
|             { | ||||
|                 "type": "field_dropdown", | ||||
|                 "name": "OP", | ||||
|                 "options": [ | ||||
|                     ["%{BKY_LOGIC_OPERATION_AND}", "AND"], | ||||
|                     ["%{BKY_LOGIC_OPERATION_OR}", "OR"] | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "B", | ||||
|                 "check": "Boolean" | ||||
|             } | ||||
|         ], | ||||
|         message2: '%{BKY_CONTROLS_IF_MSG_ELSE} %1', | ||||
|         args2: [ | ||||
|         "inputsInline": true, | ||||
|         "output": "Boolean", | ||||
|         "style": "logic_blocks", | ||||
|         "helpUrl": "%{BKY_LOGIC_OPERATION_HELPURL}", | ||||
|         "extensions": ["logic_op_tooltip"] | ||||
|     }, | ||||
|     // Block for negation.
 | ||||
|     { | ||||
|                 type: 'input_statement', | ||||
|                 name: 'ELSE' | ||||
|         "type": "logic_negate", | ||||
|         "message0": "%{BKY_LOGIC_NEGATE_TITLE}", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "BOOL", | ||||
|                 "check": "Boolean" | ||||
|             } | ||||
|         ], | ||||
|         previousStatement: null, | ||||
|         nextStatement: null, | ||||
|         colour: '#b063c5', | ||||
|         tooltip: '%{BKYCONTROLS_IF_TOOLTIP_2}', | ||||
|         helpUrl: '%{BKY_CONTROLS_IF_HELPURL}', | ||||
|         extensions: ['controls_if_tooltip'] | ||||
|         "output": "Boolean", | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_LOGIC_NEGATE_TOOLTIP}", | ||||
|         "helpUrl": "%{BKY_LOGIC_NEGATE_HELPURL}" | ||||
|     }, | ||||
|     // Block for null data type.
 | ||||
|     { | ||||
|         "type": "logic_null", | ||||
|         "message0": "%{BKY_LOGIC_NULL}", | ||||
|         "output": null, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_LOGIC_NULL_TOOLTIP}", | ||||
|         "helpUrl": "%{BKY_LOGIC_NULL_HELPURL}" | ||||
|     }, | ||||
|     // Block for ternary operator.
 | ||||
|     { | ||||
|         "type": "logic_ternary", | ||||
|         "message0": "%{BKY_LOGIC_TERNARY_CONDITION} %1", | ||||
|         "args0": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "IF", | ||||
|                 "check": "Boolean" | ||||
|             } | ||||
|         ], | ||||
|         "message1": "%{BKY_LOGIC_TERNARY_IF_TRUE} %1", | ||||
|         "args1": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "THEN" | ||||
|             } | ||||
|         ], | ||||
|         "message2": "%{BKY_LOGIC_TERNARY_IF_FALSE} %1", | ||||
|         "args2": [ | ||||
|             { | ||||
|                 "type": "input_value", | ||||
|                 "name": "ELSE" | ||||
|             } | ||||
|         ], | ||||
|         "output": null, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_LOGIC_TERNARY_TOOLTIP}", | ||||
|         "helpUrl": "%{BKY_LOGIC_TERNARY_HELPURL}", | ||||
|         "extensions": ["logic_ternary"] | ||||
|     } | ||||
| ]);  // END JSON EXTRACT (Do not delete this comment.)
 | ||||
| 
 | ||||
| Blockly.defineBlocksWithJsonArray([ // Mutator blocks. Do not extract.
 | ||||
|     // Block representing the if statement in the controls_if mutator.
 | ||||
|     { | ||||
|         "type": "controls_if_if", | ||||
|         "message0": "%{BKY_CONTROLS_IF_IF_TITLE_IF}", | ||||
|         "nextStatement": null, | ||||
|         "enableContextMenu": false, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_CONTROLS_IF_IF_TOOLTIP}" | ||||
|     }, | ||||
|     // Block representing the else-if statement in the controls_if mutator.
 | ||||
|     { | ||||
|         "type": "controls_if_elseif", | ||||
|         "message0": "%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}", | ||||
|         "previousStatement": null, | ||||
|         "nextStatement": null, | ||||
|         "enableContextMenu": false, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}" | ||||
|     }, | ||||
|     // Block representing the else statement in the controls_if mutator.
 | ||||
|     { | ||||
|         "type": "controls_if_else", | ||||
|         "message0": "%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}", | ||||
|         "previousStatement": null, | ||||
|         "enableContextMenu": false, | ||||
|         "style": "logic_blocks", | ||||
|         "tooltip": "%{BKY_CONTROLS_IF_ELSE_TOOLTIP}" | ||||
|     } | ||||
| ]); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| 
 | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| Blockly.defineBlocksWithJsonArray([ | ||||
|     { | ||||
| @ -44,6 +45,7 @@ Blockly.defineBlocksWithJsonArray([ | ||||
|         inputsInline: false, | ||||
|         previousStatement: null, | ||||
|         nextStatement: null, | ||||
|         colour: getColour().loops, | ||||
|         helpUrl: '%{BKY_CONTROLS_FOR_HELPURL}', | ||||
|         extensions: ['contextMenu_newGetVariableBlock', 'controls_for_tooltip'], | ||||
|     }, | ||||
|  | ||||
							
								
								
									
										50
									
								
								src/components/Blockly/blocks/map.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/components/Blockly/blocks/map.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Block for the Arduino map functionality. | ||||
|  *     The Arduino built in functions syntax can be found at: | ||||
|  *     http://arduino.cc/en/Reference/HomePage
 | ||||
|  * | ||||
|  * TODO: This block can be improved to set the new range properly. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| Blockly.Blocks['base_map'] = { | ||||
|     /** | ||||
|      * Block for creating a the map function. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/map'); | ||||
|         this.setColour(getColour().math); | ||||
|         this.appendValueInput('NUM') | ||||
|             .appendField(Blockly.Msg.ARD_MAP) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('FMIN') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_FROMMIN) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('FMAX') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_FROMMAX) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('DMIN') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_TOMIN) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('DMAX') | ||||
|             .appendField(Blockly.Msg.ARD_MAP_TOMAX) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.setOutput(true); | ||||
|         this.setInputsInline(false); | ||||
|         this.setTooltip(Blockly.Msg.ARD_MAP_TIP); | ||||
|     }, | ||||
|     /** @return {string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Types.NUMBER.typeId; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										0
									
								
								src/components/Blockly/blocks/math.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/components/Blockly/blocks/math.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										38
									
								
								src/components/Blockly/blocks/procedures.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/components/Blockly/blocks/procedures.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Block for the Arduino functions. | ||||
|  *     The Arduino built in functions syntax can be found at: | ||||
|  *     https://arduino.cc/en/Reference/HomePage
 | ||||
|  */ | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['arduino_functions'] = { | ||||
|     /** | ||||
|      * Block for defining the Arduino setup() and loop() functions. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_FUN_RUN_SETUP); | ||||
|         this.appendStatementInput('SETUP_FUNC'); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_FUN_RUN_LOOP); | ||||
|         this.appendStatementInput('LOOP_FUNC'); | ||||
|         this.setInputsInline(false); | ||||
|         this.setColour(getColour().procedures); | ||||
|         this.setTooltip(Blockly.Msg.ARD_FUN_RUN_TIP); | ||||
|         this.setHelpUrl('https://arduino.cc/en/Reference/Loop'); | ||||
|         this.contextMenu = false; | ||||
|     }, | ||||
|     /** @return {!boolean} True if the block instance is in the workspace. */ | ||||
|     getArduinoLoopsInstance: function () { | ||||
|         return true; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										248
									
								
								src/components/Blockly/blocks/sensebox-display.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								src/components/Blockly/blocks/sensebox-display.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,248 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_beginDisplay'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_beginDisplay) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_beginDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_clearDisplay'] = { | ||||
|     init: function () { | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_clearDisplay) | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_clearDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_printDisplay'] = { | ||||
|     init: function (block) { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_color) | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_display_white, "WHITE,BLACK"], [Blockly.Msg.senseBox_display_black, "BLACK,WHITE"]]), "COLOR"); | ||||
|         this.appendValueInput("SIZE", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_setSize); | ||||
|         this.appendValueInput("X", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x); | ||||
|         this.appendValueInput("Y", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y); | ||||
|         this.appendValueInput('printDisplay') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_plotDisplay'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotDisplay) | ||||
|         this.appendValueInput("Title", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotTitle); | ||||
|         this.appendValueInput("YLabel", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYLabel); | ||||
|         this.appendValueInput("XLabel", 'Text') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXLabel); | ||||
|         this.appendValueInput("XRange1", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXRange1); | ||||
|         this.appendValueInput("XRange2", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXRange2) | ||||
|         this.appendValueInput("YRange1", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYRange1); | ||||
|         this.appendValueInput("YRange2", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYRange2); | ||||
|         this.setInputsInline(false); | ||||
|         this.appendValueInput("XTick", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotXTick); | ||||
|         this.appendValueInput("YTick", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotYTick); | ||||
|         this.appendValueInput("TimeFrame", 'Number') | ||||
|             .appendField(Blockly.Msg.senseBox_display_plotTimeFrame); | ||||
|         this.appendValueInput('plotDisplay') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_value) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.senseBox_display_printDisplay_tip); | ||||
|         this.setHelpUrl('https://sensebox.de/books'); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_show'] = { | ||||
|     init: function () { | ||||
| 
 | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_show); | ||||
|         this.appendStatementInput('SHOW'); | ||||
|         this.setTooltip(Blockly.Msg.sensebox_display_show_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_fillCircle'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_fillCircle); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Radius') | ||||
|             .appendField(Blockly.Msg.sensebox_display_fillCircle_radius) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendDummyInput('fill') | ||||
|             .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_display_drawRectangle'] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_x) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_display_printDisplay_y) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('width') | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle_width) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendValueInput('height') | ||||
|             .appendField(Blockly.Msg.sensebox_display_drawRectangle_height) | ||||
|             .setCheck(Types.NUMBER.compatibleTypes); | ||||
|         this.appendDummyInput('fill') | ||||
|             .appendField(Blockly.Msg.senseBox_display_filled) | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "FILL"); | ||||
|         this.setInputsInline(false); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|    * Called whenever anything on the workspace changes. | ||||
|    * Add warning if block is not nested inside a the correct loop. | ||||
|    * @param {!Blockly.Events.Abstract} e Change event. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_display_show'], | ||||
| }; | ||||
							
								
								
									
										253
									
								
								src/components/Blockly/blocks/sensebox-lora.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/components/Blockly/blocks/sensebox-lora.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,253 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
| ----------------------------------LoRa-------------------------------------------------- | ||||
| */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_lora_initialize_otaa'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_otaa_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("Initialize LoRa (OTAA)"); | ||||
| 
 | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_device_id) | ||||
|             .appendField(new Blockly.FieldTextInput("DEVICE ID"), "DEVICEID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_app_id) | ||||
|             .appendField(new Blockly.FieldTextInput("APP ID"), "APPID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_app_key) | ||||
|             .appendField(new Blockly.FieldTextInput("APP KEY"), "APPKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_lora_initialize_abp'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_init_abp_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField("Initialize LoRa (ABP)"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_nwskey_id) | ||||
|             .appendField(new Blockly.FieldTextInput("NWSKEY"), "NWSKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_appskey_id) | ||||
|             .appendField(new Blockly.FieldTextInput("APPSKEY"), "APPSKEY"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_devaddr_id) | ||||
|             .appendField(new Blockly.FieldTextInput("DEVADDR"), "DEVADDR"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_interval) | ||||
|             .appendField(new Blockly.FieldTextInput("5"), "INTERVAL"); | ||||
|         // this.appendStatementInput('DO')
 | ||||
|         //     .appendField(Blockly.Msg.senseBox_measurements)
 | ||||
|         //     .setCheck(null);
 | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_lora_message_send'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_message_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_send_message) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_send_lora_sensor_value'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_sensor_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_measurement) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("Bytes") | ||||
|             .appendField(new Blockly.FieldTextInput("2"), "MESSAGE_BYTES"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|      * Called whenever anything on the workspace changes. | ||||
|      * Add warning if block is not nested inside a the correct loop. | ||||
|      * @param {!Blockly.Events.Abstract} e Change event. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_message_send'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_lora_cayenne_send'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_send_cayenne) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_temperature'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_temperature_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_temperature) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_humidity'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_humidity_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_humidity) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_pressure'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_pressure_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_pressure) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_luminosity'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_luminosity_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_luminosity) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_sensor'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_analog_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('Value') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_analog) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_accelerometer'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gyros_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('X') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_x) | ||||
|         this.appendValueInput('Y') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_y) | ||||
|         this.appendValueInput('Z') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_z) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
| Blockly.Blocks['sensebox_lora_cayenne_gps'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_LoRa_cayenne_gps_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendValueInput('LAT') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lat) | ||||
|         this.appendValueInput('LNG') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_lng) | ||||
|         this.appendValueInput('ALT') | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_alt) | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_LoRa_cayenne_channel) | ||||
|             .appendField(new Blockly.FieldTextInput("1"), "CHANNEL"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_lora_cayenne_send'], | ||||
| }; | ||||
							
								
								
									
										112
									
								
								src/components/Blockly/blocks/sensebox-osem.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/components/Blockly/blocks/sensebox-osem.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { getColour } from '../helpers/colour'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_osem_connection'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_osem_connection_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_osem_connection) | ||||
|             .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_osem_host, '"ingress.opensensemap.org"'], [Blockly.Msg.senseBox_osem_host_workshop, '"ingress.workshop.opensensemap.org"']]), "host") | ||||
|             .appendField('SSL') | ||||
|             .appendField(new Blockly.FieldCheckbox("TRUE"), "SSL"); | ||||
|         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.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("senseBox ID") | ||||
|             .appendField(new Blockly.FieldTextInput("senseBox ID"), "BoxID"); | ||||
|         this.appendStatementInput('DO') | ||||
|             .appendField(Blockly.Msg.senseBox_sensor) | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
| 
 | ||||
|         //Blockly.Blocks.sensebox.getDescendants = blocks;
 | ||||
| 
 | ||||
|     }, | ||||
|     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); | ||||
|             this.appendValueInput('timeStamp', 'Number') | ||||
|                 .appendField(Blockly.Msg.senseBox_gps_timeStamp); | ||||
|         } | ||||
| 
 | ||||
|         if (input === 'Stationary' && extraFieldExist !== null) { | ||||
|             this.removeInput('lat'); | ||||
|             this.removeInput('lng'); | ||||
|             this.removeInput('altitude'); | ||||
|             this.removeInput('timeStamp'); | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
| Blockly.Blocks['sensebox_send_to_osem'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_send_to_osem_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_send_to_osem); | ||||
|         this.appendValueInput('Value') | ||||
|             .setCheck(null) | ||||
|             .appendField('Sensor ID') | ||||
|             .appendField(new Blockly.FieldTextInput('Sensor ID'), 'SensorID'); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     /** | ||||
|   * Called whenever anything on the workspace changes. | ||||
|   * Add warning if block is not nested inside a the correct loop. | ||||
|   * @param {!Blockly.Events.Abstract} e Change event. | ||||
|   * @this Blockly.Block | ||||
|   */ | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['sensebox_osem_connection'], | ||||
| }; | ||||
| @ -1,5 +1,12 @@ | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| import * as Types from '../helpers/types' | ||||
| import { selectedBoard } from '../helpers/board' | ||||
| 
 | ||||
| /** | ||||
|  * HDC1080 Temperature and Humidity Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_temp_hum'] = { | ||||
|   init: function () { | ||||
| @ -9,8 +16,8 @@ Blockly.Blocks['sensebox_sensor_temp_hum'] = { | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_hum, "Humidity"]]), "NAME"); | ||||
|     this.setOutput(true, "Number"); | ||||
|     this.setColour(120); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_temp_hum_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   }, | ||||
| @ -18,3 +25,290 @@ Blockly.Blocks['sensebox_sensor_temp_hum'] = { | ||||
|     return Blockly.Types.DECIMAL; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * VEML6070 and TSL4513  | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_uv_light'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_uv_light); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_light, "Illuminance"], [Blockly.Msg.senseBox_uv, "UvIntensity"]]), "NAME"); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_uv_light_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     return Blockly.Types.DECIMAL; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /* | ||||
| BMX055 Three differen Blocks for Accelerometer, Gyroscope, Compass | ||||
| */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_bmx055_accelerometer'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_direction) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_direction_x, "X"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_y, "Y"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_z, "Z"], [Blockly.Msg.senseBox_bmx055_accelerometer_direction_total, "Total"]]), "VALUE"); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_LEFT) | ||||
|       .appendField(Blockly.Msg.senseBox_bmx055_accelerometer_range) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_bmx055_accelerometer_range_2g, "0x3"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_4g, "0x5"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_8g, "0x8"], [Blockly.Msg.senseBox_bmx055_accelerometer_range_16g, "0x0C"]]), "RANGE"); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bmx055_accelerometer_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeId; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * SDS011 Fine Particular Matter Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_sds011'] = { | ||||
|   init: function () { | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sds011); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_pm25, "Pm25"], [Blockly.Msg.senseBox_sds011_pm10, "Pm10"]]), "NAME") | ||||
|       .appendField(Blockly.Msg.senseBox_sds011_dimension) | ||||
|       .appendField(new Blockly.FieldDropdown([[Blockly.Msg.senseBox_sds011_serial1, "Serial1"], [Blockly.Msg.senseBox_sds011_serial2, "Serial2"]]), "SERIAL"); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_sds011_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/temp_und_luftfeuchte.html'); | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     return Blockly.Types.DECIMAL; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BMP280 Pressure Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_pressure'] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_pressure, "Pressure"], [Blockly.Msg.senseBox_temp, "Temperature"], [Blockly.Msg.senseBox_gps_alt, "Altitude"]]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function (option) { | ||||
|       var input = (option === 'Pressure') || (option === 'Temperature') || (option === 'Altitude'); | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_pressure_sensor); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(dropdown, "NAME"); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_pressure_tip); | ||||
|     this.setHelpUrl('https://edu.books.sensebox.de/de/projekte/diy_umweltstation/luftdruck.html'); | ||||
|   }, | ||||
|   /** | ||||
|    * Parse XML to restore the number of pins available. | ||||
|    * @param {!Element} xmlElement XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
| 
 | ||||
|   domToMutation: function (xmlElement) { | ||||
|     (xmlElement.getAttribute('port')); | ||||
| 
 | ||||
|   }, | ||||
|   /** | ||||
|    * Create XML to represent number of pins selection. | ||||
|    * @return {!Element} XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   mutationToDom: function () { | ||||
|     var container = document.createElement('mutation'); | ||||
|     var input = this.getFieldValue('NAME'); | ||||
|     this.updateShape_(input); | ||||
|     container.setAttribute('NAME', input); | ||||
|     return container; | ||||
|   }, | ||||
|   /** | ||||
|    * Modify this block to have the correct number of pins available. | ||||
|    * @param {boolean} | ||||
|    * @private | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateShape_: function () { | ||||
|     var extraFieldExist = this.getFieldValue('referencePressure'); | ||||
|     var input = this.getFieldValue('NAME'); | ||||
|     if (input === 'Altitude' && extraFieldExist === null) { | ||||
|       this.appendDummyInput('extraField') | ||||
|         .setAlign(Blockly.ALIGN_RIGHT) | ||||
|         .appendField(Blockly.Msg.senseBox_pressure_referencePressure) | ||||
|         .appendField(new Blockly.FieldTextInput("1013"), "referencePressure") | ||||
|         .appendField(Blockly.Msg.senseBox_pressure_referencePressure_dim); | ||||
|     } | ||||
| 
 | ||||
|     if ((input === 'Pressure' || input === 'Temperature') && extraFieldExist !== null) { | ||||
|       this.removeInput('extraField'); | ||||
|     } | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     var input = this.getFieldValue('NAME'); | ||||
|     if (input === 'Temperature') { | ||||
|       return Types.DECIMAL.typeId; | ||||
|     } else { | ||||
|       return Types.LARGE_NUMBER.typeId; | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BME680 Environmental Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_bme680_bsec'] = { | ||||
|   init: function () { | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_temp, "temperature"], [Blockly.Msg.senseBox_hum, "humidity"], [Blockly.Msg.senseBox_pressure, "pressure"], [Blockly.Msg.senseBox_bme_iaq, "IAQ"], [Blockly.Msg.senseBox_bme_iaq_accuracy, "IAQAccuracy"], [Blockly.Msg.senseBox_bme_co2, "CO2"], [Blockly.Msg.senseBox_bme_breatheVocEquivalent, "breathVocEquivalent"]]; | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_bme680); | ||||
|     this.appendDummyInput() | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_value) | ||||
|       .appendField(new Blockly.FieldDropdown(dropdownOptions), "dropdown") | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_bme_tip); | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     return Types.DECIMAL.typeId; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Ultrasonic Sensor | ||||
|  *  | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_ultrasonic_ranger'] = { | ||||
|   init: function () { | ||||
| 
 | ||||
|     var dropdownOptions = [[Blockly.Msg.senseBox_ultrasonic_port_A, 'A'], | ||||
|     [Blockly.Msg.senseBox_ultrasonic_port_B, 'B'], [Blockly.Msg.senseBox_ultrasonic_port_C, 'C']]; | ||||
|     var dropdown = new Blockly.FieldDropdown(dropdownOptions, function (option) { | ||||
|       var input = (option === 'A') || (option === 'B') || (option === 'C'); | ||||
|       this.sourceBlock_.updateShape_(input); | ||||
|     }); | ||||
| 
 | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic) | ||||
|       .appendField(dropdown, "port"); | ||||
|     this.appendDummyInput('TrigEcho') | ||||
|       .setAlign(Blockly.ALIGN_RIGHT) | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_trigger) | ||||
|       .appendField(new Blockly.FieldDropdown( | ||||
|         selectedBoard().digitalPins), 'ultrasonic_trigger') | ||||
|       .appendField(Blockly.Msg.senseBox_ultrasonic_echo) | ||||
|       .appendField(new Blockly.FieldDropdown( | ||||
|         selectedBoard().digitalPins), 'ultrasonic_echo'); | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setTooltip(Blockly.Msg.senseBox_ultrasonic_tip); | ||||
|     this.setHelpUrl('https://sensebox.de/books'); | ||||
|   }, | ||||
|   /** | ||||
|    * Parse XML to restore the number of pins available. | ||||
|    * @param {!Element} xmlElement XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   domToMutation: function (xmlElement) { | ||||
|     (xmlElement.getAttribute('port')); | ||||
| 
 | ||||
|   }, | ||||
|   /** | ||||
|    * Create XML to represent number of pins selection. | ||||
|    * @return {!Element} XML storage element. | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   mutationToDom: function () { | ||||
|     var container = document.createElement('mutation'); | ||||
|     var input = this.getFieldValue('port'); | ||||
|     this.updateShape_(input); | ||||
|     container.setAttribute("port", input); | ||||
|     return container; | ||||
|   }, | ||||
|   /** | ||||
|    * Modify this block to have the correct number of pins available. | ||||
|    * @param {boolean} | ||||
|    * @private | ||||
|    * @this Blockly.Block | ||||
|    */ | ||||
|   updateShape_: function () { | ||||
|     var input = this.getFieldValue('port'); | ||||
|     switch (input) { | ||||
|       case 'A': | ||||
|         this.setFieldValue('1', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('2', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       case 'B': | ||||
|         this.setFieldValue('3', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('4', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       case 'C': | ||||
|         this.setFieldValue('5', 'ultrasonic_trigger'); | ||||
|         this.setFieldValue('6', 'ultrasonic_echo'); | ||||
|         break; | ||||
|       default: | ||||
|         break; | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   getBlockType: function () { | ||||
|     return Blockly.Types.NUMBER; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Microphone | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_sensor_sound'] = { | ||||
|   init: function () { | ||||
|     this.setColour(getColour().sensebox); | ||||
|     this.appendDummyInput() | ||||
|       .appendField(Blockly.Msg.senseBox_sound) | ||||
|       .appendField("Pin:") | ||||
|       .appendField(new Blockly.FieldDropdown(selectedBoard().analogPins), "PIN") | ||||
|     this.setOutput(true, Types.NUMBER.typeId); | ||||
|     this.setHelpUrl(Blockly.Msg.senseBox_sound_tip); | ||||
|     this.setTooltip('Dieser Sensor mist den Geräuschpegel.'); | ||||
|   }, | ||||
|   getBlockType: function () { | ||||
|     return Types.NUMBER.typeId; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										53
									
								
								src/components/Blockly/blocks/sensebox-telegram.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/components/Blockly/blocks/sensebox-telegram.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_telegram"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_telegram_init); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("telegram") | ||||
|             .appendField(new Blockly.FieldTextInput("token"), "telegram_token"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_telegram_do"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_do); | ||||
|         this.appendStatementInput("telegram_do"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_telegram_do_on_message"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_do_on_message); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_telegram_message) | ||||
|             .appendField(new Blockly.FieldTextInput("/message"), 'telegram_message'); | ||||
|         this.appendStatementInput("telegram_do_on_message").setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_telegram_send"] = { | ||||
|     init: function () { | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput().appendField(Blockly.Msg.senseBox_telegram_send); | ||||
|         this.appendValueInput("telegram_text_to_send").setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     LOOP_TYPES: ["sensebox_telegram_do_on_message"] | ||||
| }; | ||||
							
								
								
									
										58
									
								
								src/components/Blockly/blocks/sensebox-web.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/components/Blockly/blocks/sensebox-web.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_wifi'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_wifi_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_connect); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|             .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_output_password) | ||||
|             .appendField(new Blockly.FieldTextInput("Password"), "Password"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     }, | ||||
|     onchange: function (e) { | ||||
|         var legal = false; | ||||
|         // Is the block nested in a loop?
 | ||||
|         var block = this; | ||||
|         do { | ||||
|             if (this.LOOP_TYPES.indexOf(block.type) !== -1) { | ||||
|                 legal = true; | ||||
|                 break; | ||||
|             } | ||||
|             block = block.getSurroundParent(); | ||||
|         } while (block); | ||||
|         if (legal) { | ||||
|             this.setWarningText(null); | ||||
| 
 | ||||
|         } else { | ||||
|             this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING); | ||||
| 
 | ||||
|         } | ||||
|     }, | ||||
|     LOOP_TYPES: ['arduino_functions'], | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_startap'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_wifi_tip); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().sensebox); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_startap); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(Blockly.Msg.senseBox_wifi_ssid) | ||||
|             .appendField(new Blockly.FieldTextInput("SSID"), "SSID"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| @ -1,16 +1,4 @@ | ||||
| import Blockly from 'blockly'; | ||||
| 
 | ||||
| Blockly.Blocks["sensebox_telegram"] = { | ||||
|     init: function () { | ||||
|         this.setColour(120); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_telegram_init); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField("telegram") | ||||
|             .appendField(new Blockly.FieldTextInput("token"), "telegram_token"); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										130
									
								
								src/components/Blockly/blocks/time.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/components/Blockly/blocks/time.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Blocks for Arduino Time functions. | ||||
|  *     The arduino built in functions syntax can be found in | ||||
|  *     http://arduino.cc/en/Reference/HomePage
 | ||||
|  */ | ||||
| import Blockly from 'blockly'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| import * as Types from '../helpers/types' | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Blocks['time_delay'] = { | ||||
|     /** | ||||
|      * Delay block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Delay'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendValueInput('DELAY_TIME_MILI') | ||||
|             .setCheck(Types.NUMBER.checkList) | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MS); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['time_delaymicros'] = { | ||||
|     /** | ||||
|      * delayMicroseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/DelayMicroseconds'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendValueInput('DELAY_TIME_MICRO') | ||||
|             .setCheck(Types.NUMBER.checkList) | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_DELAY_MICROS); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_DELAY_MICRO_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['time_millis'] = { | ||||
|     /** | ||||
|      * Elapsed time in milliseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Millis'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MILLIS); | ||||
|         this.setOutput(true, Types.LARGE_NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_MILLIS_TIP); | ||||
|     }, | ||||
|     /** @return {string} The type of return value for the block, an integer. */ | ||||
|     getBlockType: function () { | ||||
|         return Blockly.Types.LARGE_NUMBER; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['time_micros'] = { | ||||
|     /** | ||||
|      * Elapsed time in microseconds block definition | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl('http://arduino.cc/en/Reference/Micros'); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_MICROS); | ||||
|         this.setOutput(true, Types.LARGE_NUMBER.typeId); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_MICROS_TIP); | ||||
|     }, | ||||
|     /** | ||||
|      * Should be a long (32bit), but  for for now an int. | ||||
|      * @return {string} The type of return value for the block, an integer. | ||||
|      */ | ||||
|     getBlockType: function () { | ||||
|         return Types.LARGE_NUMBER; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['infinite_loop'] = { | ||||
|     /** | ||||
|      * Waits forever, end of program. | ||||
|      * @this Blockly.Block | ||||
|      */ | ||||
|     init: function () { | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.ARD_TIME_INF); | ||||
|         this.setInputsInline(true); | ||||
|         this.setPreviousStatement(true); | ||||
|         this.setTooltip(Blockly.Msg.ARD_TIME_INF_TIP); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| Blockly.Blocks['sensebox_interval_timer'] = { | ||||
|     init: function () { | ||||
|         this.setTooltip(Blockly.Msg.senseBox_interval_timer_tip); | ||||
|         this.setInputsInline(true); | ||||
|         this.setHelpUrl(''); | ||||
|         this.setColour(getColour().time); | ||||
|         this.appendDummyInput() | ||||
|             .appendField(Blockly.Msg.senseBox_interval_timer); | ||||
|         this.appendDummyInput() | ||||
|             .setAlign(Blockly.ALIGN_LEFT) | ||||
|             .appendField(new Blockly.FieldTextInput("10000"), "interval") | ||||
|             .appendField(Blockly.Msg.senseBox_interval); | ||||
|         this.appendStatementInput('DO') | ||||
|             .setCheck(null); | ||||
|         this.setPreviousStatement(true, null); | ||||
|         this.setNextStatement(true, null); | ||||
|     } | ||||
| }; | ||||
| @ -25,7 +25,6 @@ | ||||
| // https://developers.google.com/blockly/guides/create-custom-blocks/generating-code
 | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import * as _ from 'lodash'; | ||||
| 
 | ||||
| /** | ||||
|  * Arduino code generator. | ||||
| @ -81,6 +80,19 @@ Blockly['Arduino'].ORDER_ASSIGNMENT = 14; // = *= /= ~/= %= += -= <<= >>= &= ^= | ||||
| Blockly['Arduino'].ORDER_COMMA = 18; // ,
 | ||||
| Blockly['Arduino'].ORDER_NONE = 99; // (...)
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @param {} workspace  | ||||
|  *  | ||||
|  * Blockly Types | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Initialise the database of variable names. | ||||
|  * @param {!Blockly.Workspace} workspace Workspace to generate code from. | ||||
| @ -89,9 +101,20 @@ Blockly['Arduino'].init = function (workspace) { | ||||
|     // Create a dictionary of definitions to be printed before the code.
 | ||||
|     Blockly['Arduino'].libraries_ = Object.create(null); | ||||
| 
 | ||||
|     Blockly['Arduino'].definitions_ = Object.create(null); | ||||
| 
 | ||||
|     // creates a list of code to be setup before the setup block
 | ||||
|     Blockly['Arduino'].setupCode_ = Object.create(null); | ||||
| 
 | ||||
|     // creates a list of code for the loop to be runned once
 | ||||
|     Blockly['Arduino'].loopCodeOnce_ = Object.create(null) | ||||
| 
 | ||||
|     // creates a list of code for the loop to be runned once
 | ||||
|     Blockly['Arduino'].codeFunctions_ = Object.create(null) | ||||
| 
 | ||||
|     // creates a list of code variables  
 | ||||
|     Blockly['Arduino'].variables_ = Object.create(null) | ||||
| 
 | ||||
|     // Create a dictionary mapping desired function names in definitions_
 | ||||
|     // to actual function names (to avoid collisions with user functions).
 | ||||
|     Blockly['Arduino'].functionNames_ = Object.create(null); | ||||
| @ -172,39 +195,47 @@ Blockly['Arduino'].init = function (workspace) { | ||||
|  */ | ||||
| Blockly['Arduino'].finish = function (code) { | ||||
|     let libraryCode = ''; | ||||
|     let variablesCode = ''; | ||||
|     let codeFunctions = ''; | ||||
|     let functionsCode = ''; | ||||
|     let definitionsCode = ''; | ||||
|     let loopCodeOnce = ''; | ||||
|     let setupCode = ''; | ||||
|     let preSetupCode = ''; | ||||
|     let devVariables = '\n'; | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].libraries_) { | ||||
|         libraryCode += Blockly['Arduino'].libraries_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].variables_) { | ||||
|         variablesCode += Blockly['Arduino'].variables_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].definitions_) { | ||||
|         definitionsCode += Blockly['Arduino'].definitions_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].loopCodeOnce_) { | ||||
|         loopCodeOnce += Blockly['Arduino'].loopCodeOnce_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].codeFunctions_) { | ||||
|         codeFunctions += Blockly['Arduino'].codeFunctions_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].functionNames_) { | ||||
|         functionsCode += Blockly['Arduino'].functionNames_[key] + '\n'; | ||||
|     } | ||||
| 
 | ||||
|     if (!_.isEmpty(Blockly['Arduino'].setupCode_['bluetooth_setup'])) { | ||||
|         devVariables += 'String bluetoothMessageDEV = ""; \n'; | ||||
|     } | ||||
| 
 | ||||
|     if (!_.isEmpty(Blockly['Arduino'].setupCode_['serial_begin'])) { | ||||
|         devVariables += 'String serialMessageDEV = ""; \n'; | ||||
|     } | ||||
| 
 | ||||
|     if (!_.isEmpty(Blockly['Arduino'].functionNames_['double_to_string_debug'])) { | ||||
|         devVariables += 'boolean stopDebugging = false; \n'; | ||||
|     } | ||||
| 
 | ||||
|     let setupCode = ''; | ||||
| 
 | ||||
|     let preSetupCode = ''; | ||||
| 
 | ||||
|     for (const key in Blockly['Arduino'].setupCode_) { | ||||
|         preSetupCode += Blockly['Arduino'].setupCode_[key] || ''; | ||||
|     } | ||||
|     setupCode = '\nvoid setup() { \n' + preSetupCode + '\n}\n'; | ||||
| 
 | ||||
|     let loopCode = '\nvoid loop() { \n' + code + '\n}\n'; | ||||
|     let loopCode = '\nvoid loop() { \n' + loopCodeOnce + code + '\n}\n'; | ||||
| 
 | ||||
| 
 | ||||
|     // Convert the definitions dictionary into a list.
 | ||||
| @ -213,6 +244,12 @@ Blockly['Arduino'].finish = function (code) { | ||||
|         '\n' + | ||||
|         libraryCode + | ||||
|         '\n' + | ||||
|         variablesCode + | ||||
|         '\n' + | ||||
|         definitionsCode + | ||||
|         '\n' + | ||||
|         codeFunctions + | ||||
|         '\n' + | ||||
|         Blockly['Arduino'].variablesInitCode_ + | ||||
|         '\n' + | ||||
|         functionsCode + | ||||
| @ -225,6 +262,7 @@ Blockly['Arduino'].finish = function (code) { | ||||
|     // Clean up temporary data.
 | ||||
|     delete Blockly['Arduino'].definitions_; | ||||
|     delete Blockly['Arduino'].functionNames_; | ||||
|     delete Blockly['Arduino'].loopCodeOnce_; | ||||
|     delete Blockly['Arduino'].variablesInitCode_; | ||||
|     delete Blockly['Arduino'].libraries_; | ||||
|     Blockly['Arduino'].variableDB_.reset(); | ||||
|  | ||||
| @ -1,5 +1,16 @@ | ||||
| import './generator'; | ||||
| import './loops'; | ||||
| import './sensebox'; | ||||
| import './sensebox-sensors'; | ||||
| import './sensebox-telegram'; | ||||
| import './sensebox-osem'; | ||||
| import './sensebox-web'; | ||||
| import './sensebox-display'; | ||||
| import './sensebox-lora'; | ||||
| import './logic'; | ||||
| import './math'; | ||||
| import './map'; | ||||
| import './io'; | ||||
| import './procedures'; | ||||
| import './time'; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										114
									
								
								src/components/Blockly/generator/io.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/components/Blockly/generator/io.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| /** | ||||
|  * Function for 'set pin' (X) to a state (Y). | ||||
|  * Arduino code: setup { pinMode(X, OUTPUT); } | ||||
|  *               loop  { digitalWrite(X, Y); } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['io_digitalwrite'] = function (block) { | ||||
|     var pin = block.getFieldValue('PIN'); | ||||
|     var stateOutput = Blockly.Arduino.valueToCode( | ||||
|         block, 'STATE', Blockly['Arduino'].ORDER_ATOMIC) || 'LOW'; | ||||
|     Blockly['Arduino'].setupCode_['pinMode'] = 'pinMode(' + pin + ', OUTPUT);'; | ||||
|     var code = 'digitalWrite(' + pin + ', ' + stateOutput + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Function for reading a digital pin (X). | ||||
|  * Arduino code: setup { pinMode(X, INPUT); } | ||||
|  *               loop  { digitalRead(X)     } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['io_digitalread'] = function (block) { | ||||
|     var pin = block.getFieldValue('PIN'); | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', INPUT);' | ||||
|     var code = 'digitalRead(' + pin + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Function for setting the state (Y) of a built-in LED (X). | ||||
|  * Arduino code: setup { pinMode(X, OUTPUT); } | ||||
|  *               loop  { digitalWrite(X, Y); } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['io_builtin_led'] = function (block) { | ||||
|     var pin = block.getFieldValue('BUILT_IN_LED'); | ||||
|     var stateOutput = Blockly.Arduino.valueToCode( | ||||
|         block, 'STATE', Blockly.Arduino.ORDER_ATOMIC) || 'LOW'; | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pindMode(' + pin + 'OUTPUT);' | ||||
|     var code = 'digitalWrite(' + pin + ', ' + stateOutput + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Function for setting the state (Y) of an analogue output (X). | ||||
|  * Arduino code: setup { pinMode(X, OUTPUT); } | ||||
|  *               loop  { analogWrite(X, Y);  } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['io_analogwrite'] = function (block) { | ||||
|     var pin = block.getFieldValue('PIN'); | ||||
|     var stateOutput = Blockly.Arduino.valueToCode( | ||||
|         block, 'NUM', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', OUTPUT);'; | ||||
|     // Warn if the input value is out of range
 | ||||
|     if ((stateOutput < 0) || (stateOutput > 255)) { | ||||
|         block.setWarningText('The analogue value set must be between 0 and 255', | ||||
|             'pwm_value'); | ||||
|     } else { | ||||
|         block.setWarningText(null, 'pwm_value'); | ||||
|     } | ||||
|     var code = 'analogWrite(' + pin + ', ' + stateOutput + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Function for reading an analogue pin value (X). | ||||
|  * Arduino code: setup { pinMode(X, INPUT); } | ||||
|  *               loop  { analogRead(X)      } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['io_analogread'] = function (block) { | ||||
|     var pin = block.getFieldValue('PIN'); | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', INPUT);'; | ||||
|     var code = 'analogRead(' + pin + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Value for defining a digital pin state. | ||||
|  * Arduino code: loop { HIGH / LOW } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['io_highlow'] = function (block) { | ||||
|     var code = block.getFieldValue('STATE'); | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino['io_pulsein'] = function (block) { | ||||
|     var pin = block.getFieldValue("PULSEPIN"); | ||||
|     var type = Blockly.Arduino.valueToCode(block, "PULSETYPE", Blockly.Arduino.ORDER_ATOMIC); | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', INPUT);'; | ||||
|     var code = 'pulseIn(' + pin + ', ' + type + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino['io_pulsetimeout'] = function (block) { | ||||
|     var pin = block.getFieldValue("PULSEPIN"); | ||||
|     var type = Blockly.Arduino.valueToCode(block, "PULSETYPE", Blockly.Arduino.ORDER_ATOMIC); | ||||
|     var timeout = Blockly.Arduino.valueToCode(block, "TIMEOUT", Blockly.Arduino.ORDER_ATOMIC); | ||||
|     Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', INPUT);'; | ||||
|     var code = 'pulseIn(' + pin + ', ' + type + ', ' + timeout + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| @ -1,5 +1,4 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { Block } from 'blockly'; | ||||
| 
 | ||||
| Blockly.Arduino['logic_boolean'] = function (Block) { | ||||
|     // Boolean values true and false.
 | ||||
| @ -55,7 +54,7 @@ Blockly.Arduino['logic_operation'] = function (Block) { | ||||
|     return [code, order]; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino['control_if'] = function (Block) { | ||||
| Blockly.Arduino['controls_if'] = function (Block) { | ||||
|     // If/elseif/else condition.
 | ||||
|     let n = 0; | ||||
|     let code = '', | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { Block } from 'blockly'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly['Arduino']['controls_repeat_ext'] = function (Block) { | ||||
|     // Repeat n times.
 | ||||
| @ -111,6 +111,8 @@ Blockly['Arduino']['controls_flow_statements'] = function (Block) { | ||||
|             return 'break;\n'; | ||||
|         case 'CONTINUE': | ||||
|             return 'continue;\n'; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     throw Error('Unknown flow statement.'); | ||||
| }; | ||||
							
								
								
									
										24
									
								
								src/components/Blockly/generator/map.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/components/Blockly/generator/map.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the map block. | ||||
|  * Arduino code: loop { map(x, 0, 1024, 0, y) } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['base_map'] = function (block) { | ||||
|     var valueNum = Blockly.Arduino.valueToCode( | ||||
|         block, 'NUM', Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var fromMin = Blockly.Arduino.valueToCode( | ||||
|         block, 'FMIN', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     var fromMax = Blockly.Arduino.valueToCode( | ||||
|         block, 'FMAX', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     var valueDmin = Blockly.Arduino.valueToCode( | ||||
|         block, 'DMIN', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     var valueDmax = Blockly.Arduino.valueToCode( | ||||
|         block, 'DMAX', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
| 
 | ||||
|     var code = 'map(' + valueNum + ',' + fromMin + ',' + fromMax + ',' + valueDmin + ',' + valueDmax + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_NONE]; | ||||
| }; | ||||
							
								
								
									
										347
									
								
								src/components/Blockly/generator/math.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								src/components/Blockly/generator/math.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,347 @@ | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Generating Arduino code for the Math blocks. | ||||
|  * | ||||
|  * TODO: Math on list needs lists to be implemented. | ||||
|  *       math_constant and math_change needs to be tested in compiler. | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * Generator for a numeric value (X). | ||||
|  * Arduino code: loop { X } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_number'] = function (block) { | ||||
|     // Numeric value.
 | ||||
|     var code = parseFloat(block.getFieldValue('NUM')); | ||||
|     if (code === Infinity) { | ||||
|         code = 'INFINITY'; | ||||
|     } else if (code === -Infinity) { | ||||
|         code = '-INFINITY'; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for a basic arithmetic operators (X and Y) and power function | ||||
|  * (X ^ Y). | ||||
|  * Arduino code: loop { X operator Y } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_arithmetic'] = function (block) { | ||||
|     var OPERATORS = { | ||||
|         ADD: [' + ', Blockly.Arduino.ORDER_ADDITIVE], | ||||
|         MINUS: [' - ', Blockly.Arduino.ORDER_ADDITIVE], | ||||
|         MULTIPLY: [' * ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         DIVIDE: [' / ', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         POWER: [null, Blockly.Arduino.ORDER_NONE]  // Handle power separately.
 | ||||
|     }; | ||||
|     var tuple = OPERATORS[block.getFieldValue('OP')]; | ||||
|     var operator = tuple[0]; | ||||
|     var order = tuple[1]; | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'A', order) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'B', order) || '0'; | ||||
|     var code; | ||||
|     // Power in C++ requires a special case since it has no operator.
 | ||||
|     if (!operator) { | ||||
|         code = 'Math.pow(' + argument0 + ', ' + argument1 + ')'; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     code = argument0 + operator + argument1; | ||||
|     return [code, order]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for math operators that contain a single operand (X). | ||||
|  * Arduino code: loop { operator(X) } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_single'] = function (block) { | ||||
|     var operator = block.getFieldValue('OP'); | ||||
|     var code; | ||||
|     var arg; | ||||
|     if (operator === 'NEG') { | ||||
|         // Negation is a special case given its different operator precedents.
 | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_UNARY_PREFIX) || '0'; | ||||
|         if (arg[0] === '-') { | ||||
|             // --3 is not legal in C++ in this context.
 | ||||
|             arg = ' ' + arg; | ||||
|         } | ||||
|         code = '-' + arg; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_PREFIX]; | ||||
|     } | ||||
|     if (operator === 'ABS' || operator.substring(0, 5) === 'ROUND') { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_UNARY_POSTFIX) || '0'; | ||||
|     } else if (operator === 'SIN' || operator === 'COS' || operator === 'TAN') { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     } else { | ||||
|         arg = Blockly.Arduino.valueToCode(block, 'NUM', | ||||
|             Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     } | ||||
|     // First, handle cases which generate values that don't need parentheses.
 | ||||
|     switch (operator) { | ||||
|         case 'ABS': | ||||
|             code = 'abs(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROOT': | ||||
|             code = 'sqrt(' + arg + ')'; | ||||
|             break; | ||||
|         case 'LN': | ||||
|             code = 'log(' + arg + ')'; | ||||
|             break; | ||||
|         case 'EXP': | ||||
|             code = 'exp(' + arg + ')'; | ||||
|             break; | ||||
|         case 'POW10': | ||||
|             code = 'pow(10,' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUND': | ||||
|             code = 'round(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUNDUP': | ||||
|             code = 'ceil(' + arg + ')'; | ||||
|             break; | ||||
|         case 'ROUNDDOWN': | ||||
|             code = 'floor(' + arg + ')'; | ||||
|             break; | ||||
|         case 'SIN': | ||||
|             code = 'sin(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         case 'COS': | ||||
|             code = 'cos(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         case 'TAN': | ||||
|             code = 'tan(' + arg + ' / 180 * Math.PI)'; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     if (code) { | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     // Second, handle cases which generate values that may need parentheses.
 | ||||
|     switch (operator) { | ||||
|         case 'LOG10': | ||||
|             code = 'log(' + arg + ') / log(10)'; | ||||
|             break; | ||||
|         case 'ASIN': | ||||
|             code = 'asin(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         case 'ACOS': | ||||
|             code = 'acos(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         case 'ATAN': | ||||
|             code = 'atan(' + arg + ') / M_PI * 180'; | ||||
|             break; | ||||
|         default: | ||||
|             throw new Error('Unknown math operator: ' + operator); | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for math constants (PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), | ||||
|  * INFINITY). | ||||
|  * Arduino code: loop { constant } | ||||
|  * TODO: Might need to include "#define _USE_MATH_DEFINES" | ||||
|  *       The arduino header file already includes math.h | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['math_constant'] = function (block) { | ||||
|     var CONSTANTS = { | ||||
|         'PI': ['M_PI', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'E': ['M_E', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.Arduino.ORDER_MULTIPLICATIVE], | ||||
|         'SQRT2': ['M_SQRT2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'SQRT1_2': ['M_SQRT1_2', Blockly.Arduino.ORDER_UNARY_POSTFIX], | ||||
|         'INFINITY': ['INFINITY', Blockly.Arduino.ORDER_ATOMIC] | ||||
|     }; | ||||
|     return CONSTANTS[block.getFieldValue('CONSTANT')]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for math checks: if a number is even, odd, prime, whole, positive, | ||||
|  * negative, or if it is divisible by certain number. Returns true or false. | ||||
|  * Arduino code: complex code, can create external functions. | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_number_property'] = function (block) { | ||||
|     var number_to_check = Blockly.Arduino.valueToCode(block, 'NUMBER_TO_CHECK', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var dropdown_property = block.getFieldValue('PROPERTY'); | ||||
|     var code; | ||||
|     if (dropdown_property === 'PRIME') { | ||||
|         var func = [ | ||||
|             'boolean ' + Blockly.Arduino.DEF_FUNC_NAME + '(int n) {', | ||||
|             '  // https://en.wikipedia.org/wiki/Primality_test#Naive_methods', | ||||
|             '  if (n == 2 || n == 3) {', | ||||
|             '    return true;', | ||||
|             '  }', | ||||
|             '  // False if n is NaN, negative, is 1.', | ||||
|             '  // And false if n is divisible by 2 or 3.', | ||||
|             '  if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || ' + | ||||
|             '(n % 3 == 0)) {', | ||||
|             '    return false;', | ||||
|             '  }', | ||||
|             '  // Check all the numbers of form 6k +/- 1, up to sqrt(n).', | ||||
|             '  for (int x = 6; x <= sqrt(n) + 1; x += 6) {', | ||||
|             '    if (n % (x - 1) == 0 || n % (x + 1) == 0) {', | ||||
|             '      return false;', | ||||
|             '    }', | ||||
|             '  }', | ||||
|             '  return true;', | ||||
|             '}']; | ||||
|         var funcName = Blockly.Arduino.addFunction('mathIsPrime', func.join('\n')); | ||||
|         Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||
|         code = funcName + '(' + number_to_check + ')'; | ||||
|         return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
|     } | ||||
|     switch (dropdown_property) { | ||||
|         case 'EVEN': | ||||
|             code = number_to_check + ' % 2 == 0'; | ||||
|             break; | ||||
|         case 'ODD': | ||||
|             code = number_to_check + ' % 2 == 1'; | ||||
|             break; | ||||
|         case 'WHOLE': | ||||
|             Blockly.Arduino.addInclude('math', '#include <math.h>'); | ||||
|             code = '(floor(' + number_to_check + ') == ' + number_to_check + ')'; | ||||
|             break; | ||||
|         case 'POSITIVE': | ||||
|             code = number_to_check + ' > 0'; | ||||
|             break; | ||||
|         case 'NEGATIVE': | ||||
|             code = number_to_check + ' < 0'; | ||||
|             break; | ||||
|         case 'DIVISIBLE_BY': | ||||
|             var divisor = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||
|                 Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|             code = number_to_check + ' % ' + divisor + ' == 0'; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_EQUALITY]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator to add (Y) to a variable (X). | ||||
|  * If variable X has not been declared before this block it will be declared as | ||||
|  * a (not initialised) global int, however globals are 0 initialised in C/C++. | ||||
|  * Arduino code: loop { X += Y; } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_change'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'DELTA', | ||||
|         Blockly.Arduino.ORDER_ADDITIVE) || '0'; | ||||
|     var varName = Blockly.Arduino.variableDB_.getName( | ||||
|         block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE); | ||||
|     return varName + ' += ' + argument0 + ';\n'; | ||||
| }; | ||||
| 
 | ||||
| /** Rounding functions have a single operand. */ | ||||
| Blockly.Arduino['math_round'] = Blockly.Arduino['math_single']; | ||||
| 
 | ||||
| /** Trigonometry functions have a single operand. */ | ||||
| Blockly.Arduino['math_trig'] = Blockly.Arduino['math_single']; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for the math function to a list. | ||||
|  * Arduino code: ??? | ||||
|  * TODO: List have to be implemented first. Removed from toolbox for now. | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_on_list'] = Blockly.Arduino.noGeneratorCodeInline; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for the math modulo function (calculates remainder of X/Y). | ||||
|  * Arduino code: loop { X % Y } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_modulo'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'DIVIDEND', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'DIVISOR', | ||||
|         Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0'; | ||||
|     var code = argument0 + ' % ' + argument1; | ||||
|     return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for clipping a number(X) between two limits (Y and Z). | ||||
|  * Arduino code: loop { (X < Y ? Y : ( X > Z ? Z : X)) } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_constrain'] = function (block) { | ||||
|     // Constrain a number between two limits.
 | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'VALUE', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'LOW', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument2 = Blockly.Arduino.valueToCode(block, 'HIGH', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var code = '(' + argument0 + ' < ' + argument1 + ' ? ' + argument1 + | ||||
|         ' : ( ' + argument0 + ' > ' + argument2 + ' ? ' + argument2 + ' : ' + | ||||
|         argument0 + '))'; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for a random integer between two numbers (X and Y). | ||||
|  * Arduino code: loop { math_random_int(X, Y); } | ||||
|  *               and an aditional math_random_int function | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['math_random_int'] = function (block) { | ||||
|     var argument0 = Blockly.Arduino.valueToCode(block, 'FROM', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var argument1 = Blockly.Arduino.valueToCode(block, 'TO', | ||||
|         Blockly.Arduino.ORDER_NONE) || '0'; | ||||
|     var functionName = Blockly.Arduino.variableDB_.getDistinctName( | ||||
|         'math_random_int', Blockly.Generator.NAME_TYPE); | ||||
|     Blockly.Arduino.setups_['init_rand'] = 'randomSeed(analogRead(0));'; | ||||
|     Blockly.Arduino.math_random_int.random_function = functionName; | ||||
|     var func = [ | ||||
|         'int ' + Blockly.Arduino.DEF_FUNC_NAME + '(int min, int max) {', | ||||
|         '  if (min > max) {', | ||||
|         '    // Swap min and max to ensure min is smaller.', | ||||
|         '    int temp = min;', | ||||
|         '    min = max;', | ||||
|         '    max = temp;', | ||||
|         '  }', | ||||
|         '  return min + (rand() % (max - min + 1));', | ||||
|         '}']; | ||||
|     var funcName = Blockly.Arduino.addFunction('mathRandomInt', func.join('\n')); | ||||
|     var code = funcName + '(' + argument0 + ', ' + argument1 + ')'; | ||||
|     return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Generator for a random float from 0 to 1. | ||||
|  * Arduino code: loop { (rand() / RAND_MAX) } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['math_random_float'] = function (block) { | ||||
|     return ['(rand() / RAND_MAX)', Blockly.Arduino.ORDER_UNARY_POSTFIX]; | ||||
| }; | ||||
							
								
								
									
										30
									
								
								src/components/Blockly/generator/procedures.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/components/Blockly/generator/procedures.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Code generator to add code into the setup() and loop() functions. | ||||
|  * Its use is not mandatory, but necessary to add manual code to setup(). | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['arduino_functions'] = function (block) { | ||||
|     // Edited version of Blockly.Generator.prototype.statementToCode
 | ||||
|     function statementToCodeNoTab(block, name) { | ||||
|         var targetBlock = block.getInputTargetBlock(name); | ||||
|         var code = Blockly.Arduino.blockToCode(targetBlock); | ||||
|         if (typeof code != 'string') { | ||||
|             throw new Error('Expecting code from statement block "' + targetBlock.type + '".'); | ||||
|         } | ||||
|         return code; | ||||
|     } | ||||
| 
 | ||||
|     var setupBranch = Blockly.Arduino.statementToCode(block, 'SETUP_FUNC'); | ||||
|     //var setupCode = Blockly.Arduino.scrub_(block, setupBranch); No comment block
 | ||||
|     if (setupBranch) { | ||||
|         Blockly.Arduino.setupCode_('userSetupCode', setupBranch, true); | ||||
|     } | ||||
| 
 | ||||
|     var loopBranch = statementToCodeNoTab(block, 'LOOP_FUNC'); | ||||
|     //var loopcode = Blockly.Arduino.scrub_(block, loopBranch); No comment block
 | ||||
|     return loopBranch; | ||||
| }; | ||||
							
								
								
									
										92
									
								
								src/components/Blockly/generator/sensebox-display.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/components/Blockly/generator/sensebox-display.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| /*Display Blocks*/ | ||||
| Blockly.Arduino.sensebox_display_beginDisplay = function () { | ||||
|     Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>'; | ||||
|     Blockly.Arduino.libraries_['library_wire'] = '#include <Wire.h>'; | ||||
|     Blockly.Arduino.libraries_['library_AdafruitGFX'] = '#include <Adafruit_GFX.h>'; | ||||
|     Blockly.Arduino.libraries_['library_AdafruitSSD1306'] = '#include <Adafruit_SSD1306.h>'; | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_display'] = '#define OLED_RESET 4\nAdafruit_SSD1306 display(OLED_RESET);'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_display_begin'] = 'senseBoxIO.powerI2C(true);\ndelay(2000);\ndisplay.begin(SSD1306_SWITCHCAPVCC, 0x3D);\ndisplay.display();\ndelay(100);\ndisplay.clearDisplay();'; | ||||
|     var code = ''; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_display_clearDisplay = function () { | ||||
|     var code = 'display.clearDisplay();\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_display_printDisplay = function () { | ||||
|     var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var printDisplay = Blockly.Arduino.valueToCode(this, 'printDisplay', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"'; | ||||
|     var size = Blockly.Arduino.valueToCode(this, 'SIZE', Blockly.Arduino.ORDER_ATOMIC) || '1' | ||||
|     var color = this.getFieldValue('COLOR'); | ||||
|     var code = 'display.setCursor(' + x + ',' + y + ');\n'; | ||||
|     code += 'display.setTextSize(' + size + ');\n'; | ||||
|     code += 'display.setTextColor(' + color + ');\n'; | ||||
|     code += 'display.println(' + printDisplay + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_display_show = function (block) { | ||||
|     var show = Blockly.Arduino.statementToCode(block, 'SHOW'); | ||||
|     var code = ''; | ||||
|     code += show; | ||||
|     code += 'display.display();\n'; | ||||
|     return code; | ||||
| }; | ||||
| Blockly.Arduino.sensebox_display_plotDisplay = function () { | ||||
|     var YLabel = Blockly.Arduino.valueToCode(this, 'YLabel', Blockly.Arduino.ORDER_ATOMIC) || 'Y' | ||||
|     var XLabel = Blockly.Arduino.valueToCode(this, 'XLabel', Blockly.Arduino.ORDER_ATOMIC) || 'X' | ||||
|     var Title = Blockly.Arduino.valueToCode(this, 'Title', Blockly.Arduino.ORDER_ATOMIC) || 'Title' | ||||
|     var XRange1 = Blockly.Arduino.valueToCode(this, 'XRange1', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var XRange2 = Blockly.Arduino.valueToCode(this, 'XRange2', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var YRange1 = Blockly.Arduino.valueToCode(this, 'YRange1', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var YRange2 = Blockly.Arduino.valueToCode(this, 'YRange2', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var XTick = Blockly.Arduino.valueToCode(this, 'XTick', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var YTick = Blockly.Arduino.valueToCode(this, 'YTick', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var TimeFrame = Blockly.Arduino.valueToCode(this, 'TimeFrame', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var plotDisplay = Blockly.Arduino.valueToCode(this, 'plotDisplay', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"'; | ||||
|     Blockly.Arduino.libraries_['library_plot'] = '#include <Plot.h>'; | ||||
|     Blockly.Arduino.definitions_['define_plot_class'] = 'Plot DataPlot(&display);\n'; | ||||
|     Blockly.Arduino.variables_['define_plot_class'] = 'const double TIMEFRAME = ' + TimeFrame + ';\n'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_plot_setup'] = 'DataPlot.setTitle(' + Title + ');\nDataPlot.setXLabel(' + XLabel + ');\nDataPlot.setYLabel(' + YLabel + ');\nDataPlot.setXRange(' + XRange1 + ',' + XRange2 + ');\nDataPlot.setYRange(' + YRange1 + ',' + YRange2 + ');\nDataPlot.setXTick(' + XTick + ');\nDataPlot.setYTick(' + YTick + ');\nDataPlot.setXPrecision(0);\nDataPlot.setYPrecision(0);\n'; | ||||
|     var code = 'DataPlot.clear();' | ||||
|     code += 'double starttime = millis();\ndouble t = 0;\nwhile (t <= TIMEFRAME) {\nt = (millis() - starttime) / 1000.0;\nfloat value = ' + plotDisplay + ';\n'; | ||||
|     code += 'DataPlot.addDataPoint(t,value);\n}\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_display_fillCircle = function () { | ||||
|     let code = ''; | ||||
|     var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var radius = Blockly.Arduino.valueToCode(this, 'Radius', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var fill = this.getFieldValue('FILL'); | ||||
|     if (fill === 'TRUE') { | ||||
|         code = 'display.fillCircle(' + x + ',' + y + ',' + radius + ',1);\n'; | ||||
|     } | ||||
|     else { | ||||
|         code = 'display.drawCircle(' + x + ',' + y + ',' + radius + ',1);\n'; | ||||
|     } | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_display_drawRectangle = function () { | ||||
|     let code = ''; | ||||
|     var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var width = Blockly.Arduino.valueToCode(this, 'width', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var height = Blockly.Arduino.valueToCode(this, 'height', Blockly.Arduino.ORDER_ATOMIC) || '0' | ||||
|     var fill = this.getFieldValue('FILL'); | ||||
|     if (fill === 'TRUE') { | ||||
|         code = 'display.fillRect(' + x + ',' + y + ',' + width + ',' + height + ',1);\n'; | ||||
|     } | ||||
|     else { | ||||
|         code = 'display.drawRect(' + x + ',' + y + ',' + width + ',' + height + ',1);\n'; | ||||
|     } | ||||
|     return code; | ||||
| } | ||||
							
								
								
									
										431
									
								
								src/components/Blockly/generator/sensebox-lora.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								src/components/Blockly/generator/sensebox-lora.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,431 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_initialize_otaa = function (block) { | ||||
|     var deivceID = this.getFieldValue('DEVICEID'); | ||||
|     var appID = this.getFieldValue('APPID'); | ||||
|     var appKey = this.getFieldValue('APPKEY'); | ||||
|     var interval = this.getFieldValue('INTERVAL'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>'; | ||||
|     Blockly.Arduino.libraries_['library_lmic'] = '#include <lmic.h>'; | ||||
|     Blockly.Arduino.libraries_['library_hal'] = '#include <hal/hal.h>'; | ||||
|     Blockly.Arduino.definitions_['define_LoRaVariablesOTAA'] = ` | ||||
|     static const u1_t PROGMEM APPEUI[8]= `+ appID + ` ; | ||||
|     void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI , 8);} | ||||
|    | ||||
|     static const u1_t PROGMEM DEVEUI[8]= `+ deivceID + `; | ||||
|     void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI , 8);} | ||||
|    | ||||
|     // This key should be in big endian format (or, since it is not really a
 | ||||
|     // number but a block of memory, endianness does not really apply). In
 | ||||
|     // practice, a key taken from ttnctl can be copied as-is.
 | ||||
|     // The key shown here is the semtech default key.
 | ||||
|     static const u1_t PROGMEM APPKEY[16] = `+ appKey + `; | ||||
|     void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY , 16);} | ||||
|    | ||||
|     static osjob_t sendjob; | ||||
|    | ||||
|     // Schedule TX every this many seconds (might become longer due to duty
 | ||||
|     // cycle limitations).
 | ||||
|     const unsigned TX_INTERVAL = ${interval * 60}; | ||||
|    | ||||
|     // Pin mapping
 | ||||
|     const lmic_pinmap lmic_pins = { | ||||
|         .nss = PIN_XB1_CS, | ||||
|         .rxtx = LMIC_UNUSED_PIN, | ||||
|         .rst = LMIC_UNUSED_PIN, | ||||
|         .dio = {PIN_XB1_INT, PIN_XB1_INT, LMIC_UNUSED_PIN}, | ||||
|     };`;
 | ||||
| 
 | ||||
|     Blockly.Arduino.codeFunctions_['functions_initLora'] = ` | ||||
|     void initLora() { | ||||
|       delay(2000); | ||||
|       // LMIC init
 | ||||
|       os_init(); | ||||
|       // Reset the MAC state. Session and pending data transfers will be discarded.
 | ||||
|       LMIC_reset(); | ||||
|      | ||||
|       // Start job (sending automatically starts OTAA too)
 | ||||
|       do_send(&sendjob); | ||||
|     }` | ||||
| 
 | ||||
|     Blockly.Arduino.codeFunctions_['functions_onEvent'] = ` | ||||
|     void onEvent (ev_t ev) { | ||||
|       Serial.print(os_getTime()); | ||||
|       Serial.print(": "); | ||||
|       switch(ev) { | ||||
|           case EV_SCAN_TIMEOUT: | ||||
|               Serial.println(F("EV_SCAN_TIMEOUT")); | ||||
|               break; | ||||
|           case EV_BEACON_FOUND: | ||||
|               Serial.println(F("EV_BEACON_FOUND")); | ||||
|               break; | ||||
|           case EV_BEACON_MISSED: | ||||
|               Serial.println(F("EV_BEACON_MISSED")); | ||||
|               break; | ||||
|           case EV_BEACON_TRACKED: | ||||
|               Serial.println(F("EV_BEACON_TRACKED")); | ||||
|               break; | ||||
|           case EV_JOINING: | ||||
|               Serial.println(F("EV_JOINING")); | ||||
|               break; | ||||
|           case EV_JOINED: | ||||
|               Serial.println(F("EV_JOINED")); | ||||
|    | ||||
|               // Disable link check validation (automatically enabled
 | ||||
|               // during join, but not supported by TTN at this time).
 | ||||
|               LMIC_setLinkCheckMode(0); | ||||
|               break; | ||||
|           case EV_RFU1: | ||||
|               Serial.println(F("EV_RFU1")); | ||||
|               break; | ||||
|           case EV_JOIN_FAILED: | ||||
|               Serial.println(F("EV_JOIN_FAILED")); | ||||
|               break; | ||||
|           case EV_REJOIN_FAILED: | ||||
|               Serial.println(F("EV_REJOIN_FAILED")); | ||||
|               break; | ||||
|               break; | ||||
|           case EV_TXCOMPLETE: | ||||
|               Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); | ||||
|               if (LMIC.txrxFlags & TXRX_ACK) | ||||
|                 Serial.println(F("Received ack")); | ||||
|               if (LMIC.dataLen) { | ||||
|                 Serial.println(F("Received ")); | ||||
|                 Serial.println(LMIC.dataLen); | ||||
|                 Serial.println(F(" bytes of payload")); | ||||
|               } | ||||
|               // Schedule next transmission
 | ||||
|               os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); | ||||
|               break; | ||||
|           case EV_LOST_TSYNC: | ||||
|               Serial.println(F("EV_LOST_TSYNC")); | ||||
|               break; | ||||
|           case EV_RESET: | ||||
|               Serial.println(F("EV_RESET")); | ||||
|               break; | ||||
|           case EV_RXCOMPLETE: | ||||
|               // data received in ping slot
 | ||||
|               Serial.println(F("EV_RXCOMPLETE")); | ||||
|               break; | ||||
|           case EV_LINK_DEAD: | ||||
|               Serial.println(F("EV_LINK_DEAD")); | ||||
|               break; | ||||
|           case EV_LINK_ALIVE: | ||||
|               Serial.println(F("EV_LINK_ALIVE")); | ||||
|               break; | ||||
|            default: | ||||
|               Serial.println(F("Unknown event")); | ||||
|               break; | ||||
|       } | ||||
|   }`;
 | ||||
|     Blockly.Arduino.setupCode_['initLora'] = 'initLora();'; | ||||
|     Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);'; | ||||
|     var code = '' | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_message_send = function (block) { | ||||
|     Blockly.Arduino.libraries_['library_lora_message'] = '#include <LoraMessage.h>'; | ||||
|     var lora_sensor_values = Blockly.Arduino.statementToCode(block, 'DO'); | ||||
|     Blockly.Arduino.functionNames_['functions_do_send'] = ` | ||||
|   void do_send(osjob_t* j){ | ||||
|       // Check if there is not a current TX/RX job running
 | ||||
|       if (LMIC.opmode & OP_TXRXPEND) { | ||||
|           Serial.println(F("OP_TXRXPEND, not sending")); | ||||
|       } else { | ||||
|         LoraMessage message; | ||||
|         ${lora_sensor_values} | ||||
|    | ||||
|         // Prepare upstream data transmission at the next possible time.
 | ||||
|         LMIC_setTxData2(1, message.getBytes(), message.getLength(), 0); | ||||
|         Serial.println(F("Packet queued")); | ||||
|       } | ||||
|       // Next TX is scheduled after TX_COMPLETE event.
 | ||||
|   }`;
 | ||||
|     Blockly.Arduino.loopCodeOnce_['os_runloop'] = 'os_runloop_once();' | ||||
|     return '' | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Block send Data to TTN | ||||
|  */ | ||||
| Blockly.Arduino.sensebox_send_lora_sensor_value = function (block) { | ||||
|     const reading = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"'; | ||||
|     var messageBytes = this.getFieldValue('MESSAGE_BYTES'); | ||||
|     var code = '' | ||||
|     switch (Number(messageBytes)) { | ||||
|         case 1: | ||||
|             code = `message.addUint8(${reading});\n` | ||||
|             break; | ||||
|         case 2: | ||||
|             code = `message.addUint16(${reading});\n` | ||||
|             break; | ||||
|         case 3: | ||||
|             code = `message.addUint8(${reading});
 | ||||
|         message.addUint16(${reading} >> 8);\n` | ||||
|             break; | ||||
|         default: | ||||
|             code = `message.addUint16(${reading});\n` | ||||
|     } | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_send = function (block) { | ||||
|     Blockly.Arduino.libraries_['library_cayene'] = '#include <CayenneLPP.h>'; | ||||
|     Blockly.Arduino.variables_['variable_cayenne'] = 'CayenneLPP lpp(51);' | ||||
|     var lora_sensor_values = Blockly.Arduino.statementToCode(block, 'DO'); | ||||
|     Blockly.Arduino.functionNames_['functions_do_send'] = ` | ||||
|   void do_send(osjob_t* j){ | ||||
|       // Check if there is not a current TX/RX job running
 | ||||
|       if (LMIC.opmode & OP_TXRXPEND) { | ||||
|           Serial.println(F("OP_TXRXPEND, not sending")); | ||||
|       } else { | ||||
|           lpp.reset(); | ||||
|           ${lora_sensor_values} | ||||
|    | ||||
|           // Prepare upstream data transmission at the next possible time.
 | ||||
|           LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0); | ||||
|           Serial.println(F("Packet queued")); | ||||
|       } | ||||
|       // Next TX is scheduled after TX_COMPLETE event.
 | ||||
|   }`;
 | ||||
|     Blockly.Arduino.loopCodeOnce_['os_runloop'] = 'os_runloop_once();' | ||||
|     return ''; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_initialize_abp = function (block) { | ||||
|     var nwskey = this.getFieldValue('NWSKEY'); | ||||
|     var appskey = this.getFieldValue('APPSKEY'); | ||||
|     var devaddr = this.getFieldValue('DEVADDR'); | ||||
|     var interval = this.getFieldValue('INTERVAL'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.libraries_['library_spi'] = '#include <SPI.h>'; | ||||
|     Blockly.Arduino.libraries_['library_lmic'] = '#include <lmic.h>'; | ||||
|     Blockly.Arduino.libraries_['library_hal'] = '#include <hal/hal.h>'; | ||||
|     Blockly.Arduino.definitions_['define_LoRaVariablesABP'] = ` | ||||
|     // LoRaWAN NwkSKey, network session key
 | ||||
|     // This is the default Semtech key, which is used by the early prototype TTN
 | ||||
|     // network.
 | ||||
|     static const PROGMEM u1_t NWKSKEY[16] = ${nwskey}; | ||||
|      | ||||
|     // LoRaWAN AppSKey, application session key
 | ||||
|     // This is the default Semtech key, which is used by the early prototype TTN
 | ||||
|     // network.
 | ||||
|     static const u1_t PROGMEM APPSKEY[16] = ${appskey}; | ||||
|      | ||||
|     // LoRaWAN end-device address (DevAddr)
 | ||||
|     static const u4_t DEVADDR = 0x${devaddr}; | ||||
|      | ||||
|     // These callbacks are only used in over-the-air activation, so they are
 | ||||
|     // left empty here (we cannot leave them out completely unless
 | ||||
|     // DISABLE_JOIN is set in config.h, otherwise the linker will complain).
 | ||||
|     void os_getArtEui (u1_t* buf) { } | ||||
|     void os_getDevEui (u1_t* buf) { } | ||||
|     void os_getDevKey (u1_t* buf) { } | ||||
|      | ||||
|     static osjob_t sendjob; | ||||
|      | ||||
|     // Schedule TX every this many seconds (might become longer due to duty
 | ||||
|     // cycle limitations).
 | ||||
|     const unsigned TX_INTERVAL = ${interval * 60}; | ||||
|      | ||||
|     // Pin mapping
 | ||||
|     const lmic_pinmap lmic_pins = { | ||||
|         .nss = PIN_XB1_CS, | ||||
|         .rxtx = LMIC_UNUSED_PIN, | ||||
|         .rst = LMIC_UNUSED_PIN, | ||||
|         .dio = {PIN_XB1_INT, PIN_XB1_INT, LMIC_UNUSED_PIN}, | ||||
|     };`;
 | ||||
| 
 | ||||
|     Blockly.Arduino.codeFunctions_['functions_initLora'] = ` | ||||
|     void initLora() { | ||||
|       delay(2000); | ||||
|       // LMIC init
 | ||||
|       os_init(); | ||||
|       // Reset the MAC state. Session and pending data transfers will be discarded.
 | ||||
|       LMIC_reset(); | ||||
|    | ||||
|       // Set static session parameters. Instead of dynamically establishing a session
 | ||||
|       // by joining the network, precomputed session parameters are be provided.
 | ||||
|       #ifdef PROGMEM | ||||
|       // On AVR, these values are stored in flash and only copied to RAM
 | ||||
|       // once. Copy them to a temporary buffer here, LMIC_setSession will
 | ||||
|       // copy them into a buffer of its own again.
 | ||||
|       uint8_t appskey[sizeof(APPSKEY)]; | ||||
|       uint8_t nwkskey[sizeof(NWKSKEY)]; | ||||
|       memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); | ||||
|       memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); | ||||
|       LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); | ||||
|       #else | ||||
|       // If not running an AVR with PROGMEM, just use the arrays directly
 | ||||
|       LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); | ||||
|       #endif | ||||
|    | ||||
|       #if defined(CFG_eu868) | ||||
|       // Set up the channels used by the Things Network, which corresponds
 | ||||
|       // to the defaults of most gateways. Without this, only three base
 | ||||
|       // channels from the LoRaWAN specification are used, which certainly
 | ||||
|       // works, so it is good for debugging, but can overload those
 | ||||
|       // frequencies, so be sure to configure the full frequency range of
 | ||||
|       // your network here (unless your network autoconfigures them).
 | ||||
|       // Setting up channels should happen after LMIC_setSession, as that
 | ||||
|       // configures the minimal channel set.
 | ||||
|       // NA-US channels 0-71 are configured automatically
 | ||||
|       LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
 | ||||
|       LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK,  DR_FSK),  BAND_MILLI);      // g2-band
 | ||||
|       // TTN defines an additional channel at 869.525Mhz using SF9 for class B
 | ||||
|       // devices' ping slots. LMIC does not have an easy way to define set this
 | ||||
|       // frequency and support for class B is spotty and untested, so this
 | ||||
|       // frequency is not configured here.
 | ||||
|       #elif defined(CFG_us915) | ||||
|       // NA-US channels 0-71 are configured automatically
 | ||||
|       // but only one group of 8 should (a subband) should be active
 | ||||
|       // TTN recommends the second sub band, 1 in a zero based count.
 | ||||
|       // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
 | ||||
|       LMIC_selectSubBand(1); | ||||
|       #endif | ||||
|    | ||||
|       // Disable link check validation
 | ||||
|       LMIC_setLinkCheckMode(0); | ||||
|    | ||||
|       // TTN uses SF9 for its RX2 window.
 | ||||
|       LMIC.dn2Dr = DR_SF9; | ||||
|    | ||||
|       // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
 | ||||
|       LMIC_setDrTxpow(DR_SF7,14); | ||||
|    | ||||
|       // Start job
 | ||||
|       do_send(&sendjob); | ||||
|     }` | ||||
| 
 | ||||
|     Blockly.Arduino.codeFunctions_['functions_onEvent'] = ` | ||||
|     void onEvent (ev_t ev) { | ||||
|       Serial.print(os_getTime()); | ||||
|       Serial.print(": "); | ||||
|       switch(ev) { | ||||
|           case EV_SCAN_TIMEOUT: | ||||
|               Serial.println(F("EV_SCAN_TIMEOUT")); | ||||
|               break; | ||||
|           case EV_BEACON_FOUND: | ||||
|               Serial.println(F("EV_BEACON_FOUND")); | ||||
|               break; | ||||
|           case EV_BEACON_MISSED: | ||||
|               Serial.println(F("EV_BEACON_MISSED")); | ||||
|               break; | ||||
|           case EV_BEACON_TRACKED: | ||||
|               Serial.println(F("EV_BEACON_TRACKED")); | ||||
|               break; | ||||
|           case EV_JOINING: | ||||
|               Serial.println(F("EV_JOINING")); | ||||
|               break; | ||||
|           case EV_JOINED: | ||||
|               Serial.println(F("EV_JOINED")); | ||||
|               break; | ||||
|           case EV_RFU1: | ||||
|               Serial.println(F("EV_RFU1")); | ||||
|               break; | ||||
|           case EV_JOIN_FAILED: | ||||
|               Serial.println(F("EV_JOIN_FAILED")); | ||||
|               break; | ||||
|           case EV_REJOIN_FAILED: | ||||
|               Serial.println(F("EV_REJOIN_FAILED")); | ||||
|               break; | ||||
|           case EV_TXCOMPLETE: | ||||
|               Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); | ||||
|               if (LMIC.txrxFlags & TXRX_ACK) | ||||
|                 Serial.println(F("Received ack")); | ||||
|               if (LMIC.dataLen) { | ||||
|                 Serial.println(F("Received ")); | ||||
|                 Serial.println(LMIC.dataLen); | ||||
|                 Serial.println(F(" bytes of payload")); | ||||
|               } | ||||
|               // Schedule next transmission
 | ||||
|               os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); | ||||
|               break; | ||||
|           case EV_LOST_TSYNC: | ||||
|               Serial.println(F("EV_LOST_TSYNC")); | ||||
|               break; | ||||
|           case EV_RESET: | ||||
|               Serial.println(F("EV_RESET")); | ||||
|               break; | ||||
|           case EV_RXCOMPLETE: | ||||
|               // data received in ping slot
 | ||||
|               Serial.println(F("EV_RXCOMPLETE")); | ||||
|               break; | ||||
|           case EV_LINK_DEAD: | ||||
|               Serial.println(F("EV_LINK_DEAD")); | ||||
|               break; | ||||
|           case EV_LINK_ALIVE: | ||||
|               Serial.println(F("EV_LINK_ALIVE")); | ||||
|               break; | ||||
|            default: | ||||
|               Serial.println(F("Unknown event")); | ||||
|               break; | ||||
|       } | ||||
|   }`;
 | ||||
|     Blockly.Arduino.setupCode_['initLora'] = 'initLora();'; | ||||
|     Blockly.Arduino.setupCode_['serial.begin'] = 'Serial.begin(9600);'; | ||||
|     return ''; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_temperature = function (block) { | ||||
|     var temperature = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addTemperature(${channel}, ${temperature});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_humidity = function (block) { | ||||
|     var humidity = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addRelativeHumidity(${channel}, ${humidity});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_pressure = function (block) { | ||||
|     var pressure = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addBarometricPressure(${channel}, ${pressure});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_luminosity = function (block) { | ||||
|     var luminosity = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addLuminosity(${channel}, ${luminosity});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_sensor = function (block) { | ||||
|     var sensorValue = Blockly.Arduino.valueToCode(this, 'Value', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addAnalogInput(${channel}, ${sensorValue});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_accelerometer = function (block) { | ||||
|     var x = Blockly.Arduino.valueToCode(this, 'X', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var y = Blockly.Arduino.valueToCode(this, 'Y', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var z = Blockly.Arduino.valueToCode(this, 'Z', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addAccelerometer(${channel}, ${x}, ${y}, ${z});\n`; | ||||
|     return code; | ||||
| } | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_lora_cayenne_gps = function (block) { | ||||
|     var lat = Blockly.Arduino.valueToCode(this, 'LAT', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var lng = Blockly.Arduino.valueToCode(this, 'LNG', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var alt = Blockly.Arduino.valueToCode(this, 'ALT', Blockly.Arduino.ORDER_ATOMIC) || 0 | ||||
|     var channel = this.getFieldValue('CHANNEL'); | ||||
|     var code = `lpp.addGPS(${channel}, ${lat}, ${lng}, ${alt});\n` | ||||
|     return code; | ||||
| } | ||||
							
								
								
									
										176
									
								
								src/components/Blockly/generator/sensebox-osem.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								src/components/Blockly/generator/sensebox-osem.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | ||||
| import Blockly from 'blockly'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
| * Block send Data to the openSenseMap | ||||
| */ | ||||
| Blockly.Arduino.sensebox_send_to_osem = function (block) { | ||||
|   var code = ''; | ||||
|   var sensor_id = this.getFieldValue('SensorID'); | ||||
|   var id = sensor_id.slice(-3).toUpperCase(); | ||||
|   var sensor_value = Blockly.Arduino.valueToCode(this, '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'; | ||||
|   return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_osem_connection = function (Block) { | ||||
|   var box_id = this.getFieldValue('BoxID'); | ||||
|   var host = this.getFieldValue('host'); | ||||
|   var branch = Blockly.Arduino.statementToCode(Block, 'DO'); | ||||
|   //var blocks = Blockly.Block.getDescendants;
 | ||||
|   var type = this.getFieldValue('type'); | ||||
|   var ssl = this.getFieldValue('SSL'); | ||||
|   var port = 0; | ||||
|   var count = 0; | ||||
|   // for (var i = 0; i < blocks.length; i++) {
 | ||||
|   //     if (blocks[i].type === 'sensebox_send_to_osem') {
 | ||||
|   //         count++;
 | ||||
| 
 | ||||
|   //     }
 | ||||
|   // }
 | ||||
|   var num_sensors = count; | ||||
|   Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|   Blockly.Arduino.definitions_['num_sensors'] = 'static const uint8_t NUM_SENSORS = ' + num_sensors + ';' | ||||
|   Blockly.Arduino.definitions_['SenseBoxID'] = 'const char SENSEBOX_ID [] PROGMEM = "' + box_id + '";'; | ||||
|   Blockly.Arduino.definitions_['host'] = 'const char server [] PROGMEM =' + host + ';'; | ||||
|   if (ssl === 'TRUE') { | ||||
|     Blockly.Arduino.definitions_['WiFiSSLClient'] = 'WiFiSSLClient client;'; | ||||
|     port = 443; | ||||
|   } else if (ssl === 'FALSE') { | ||||
|     Blockly.Arduino.definitions_['WiFiClient'] = 'WiFiClient client;'; | ||||
|     port = 80; | ||||
|   } | ||||
| 
 | ||||
|   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.definitions_['lengthMultiplikator'] = 'const int lengthMultiplikator = 35;'; | ||||
|   Blockly.Arduino.functionNames_['addMeasurement'] = ` | ||||
|     void addMeasurement(const char *sensorId, float value) { | ||||
|     measurements[num_measurements].sensorId = sensorId; | ||||
|     measurements[num_measurements].value = value; | ||||
|     num_measurements++; | ||||
|     }`;
 | ||||
|   if (type === 'Stationary') { | ||||
|     Blockly.Arduino.functionNames_['writeMeasurementsToClient'] = ` | ||||
|     void writeMeasurementsToClient() { | ||||
|     // iterate throug the measurements array
 | ||||
|     for (uint8_t i = 0; i < num_measurements; i++) { | ||||
|       sprintf_P(buffer, PSTR("%s,%9.2f\\n"), measurements[i].sensorId, | ||||
|                 measurements[i].value); | ||||
|       // transmit buffer to client
 | ||||
|       client.print(buffer); | ||||
|     } | ||||
|     // reset num_measurements
 | ||||
|     num_measurements = 0; | ||||
|   }`;
 | ||||
|     Blockly.Arduino.functionNames_['submitValues'] = ` | ||||
|     void submitValues() { | ||||
|   if (client.connected()) { | ||||
|     client.stop(); | ||||
|     delay(10); | ||||
|   } | ||||
|   bool connected = false; | ||||
|   char _server[strlen_P(server)]; | ||||
|   strcpy_P(_server, server); | ||||
|   for (uint8_t timeout = 2; timeout != 0; timeout--) { | ||||
|     Serial.println(F("connecting...")); | ||||
|     connected = client.connect(_server, `+ port + `); | ||||
|     if (connected == true) { | ||||
|       // construct the HTTP POST request:
 | ||||
|       sprintf_P(buffer, | ||||
|                 PSTR("POST /boxes/%s/data HTTP/1.1\\nHost: %s\\nContent-Type: " | ||||
|                      "text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"), | ||||
|                 SENSEBOX_ID, server, num_measurements * lengthMultiplikator); | ||||
|       // send the HTTP POST request:
 | ||||
|       client.print(buffer); | ||||
|       // send measurements
 | ||||
|       writeMeasurementsToClient(); | ||||
|       // send empty line to end the request
 | ||||
|       client.println(); | ||||
|       uint16_t timeout = 0; | ||||
|       // allow the response to be computed
 | ||||
|       while (timeout <= 5000) { | ||||
|         delay(10); | ||||
|         timeout = timeout + 10; | ||||
|         if (client.available()) { | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       num_measurements = 0; | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   }`;
 | ||||
|     var code = ''; | ||||
|     code += branch; | ||||
|     code += "submitValues();\n"; | ||||
|   } | ||||
|   else if (type === 'Mobile') { | ||||
|     var lat = Blockly.Arduino.valueToCode(Block, 'lat', Blockly.Arduino.ORDER_ATOMIC); | ||||
|     var lng = Blockly.Arduino.valueToCode(Block, 'lng', Blockly.Arduino.ORDER_ATOMIC); | ||||
|     var timestamp = Blockly.Arduino.valueToCode(Block, 'timeStamp', Blockly.Arduino.ORDER_ATOMIC); | ||||
|     var altitude = Blockly.Arduino.valueToCode(Block, 'altitude', Blockly.Arduino.ORDER_ATOMIC); | ||||
|     Blockly.Arduino.definitions_['lengthMultiplikator'] = 'const int lengthMultiplikator = 77;'; | ||||
|     Blockly.Arduino.functionNames_['writeMeasurementsToClient'] = ` | ||||
|       void writeMeasurementsToClient(float lat, float lng, float altitude, char* timeStamp) { | ||||
|       // iterate throug the measurements array
 | ||||
|       for (uint8_t i = 0; i < num_measurements; i++) { | ||||
|       sprintf_P(buffer, PSTR("%s,%9.2f,%s,%3.6f,%3.6f,%5.2f\\n"), measurements[i].sensorId, | ||||
|                 measurements[i].value, timeStamp, lng, lat, altitude); | ||||
|       // transmit buffer to client
 | ||||
|       client.print(buffer); | ||||
|       } | ||||
|       // reset num_measurements
 | ||||
|       num_measurements = 0; | ||||
|       }`;
 | ||||
|     Blockly.Arduino.functionNames_['submitValues'] = ` | ||||
|       void submitValues(float lat, float lng, float altitude, char* timeStamp) { | ||||
|     if (client.connected()) { | ||||
|       client.stop(); | ||||
|       delay(10); | ||||
|     } | ||||
|     bool connected = false; | ||||
|     char _server[strlen_P(server)]; | ||||
|     strcpy_P(_server, server); | ||||
|     for (uint8_t timeout = 2; timeout != 0; timeout--) { | ||||
|       Serial.println(F("connecting...")); | ||||
|       connected = client.connect(_server, `+ port + `); | ||||
|       if (connected == true) { | ||||
|         // construct the HTTP POST request:
 | ||||
|         sprintf_P(buffer, | ||||
|                   PSTR("POST /boxes/%s/data HTTP/1.1\\nHost: %s\\nContent-Type: " | ||||
|                        "text/csv\\nConnection: close\\nContent-Length: %i\\n\\n"), | ||||
|                   SENSEBOX_ID, server, num_measurements * lengthMultiplikator); | ||||
|         // send the HTTP POST request:
 | ||||
|         client.print(buffer); | ||||
|         // send measurements
 | ||||
|         writeMeasurementsToClient(lat, lng, altitude, timeStamp); | ||||
|         // send empty line to end the request
 | ||||
|         client.println(); | ||||
|         uint16_t timeout = 0; | ||||
|         // allow the response to be computed
 | ||||
|         while (timeout <= 5000) { | ||||
|           delay(10); | ||||
|           timeout = timeout + 10; | ||||
|           if (client.available()) { | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|      | ||||
|         num_measurements = 0; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   }` | ||||
|     code = ''; | ||||
|     code += branch; | ||||
|     code += 'submitValues(' + lat + ',' + lng + ',' + altitude + ',' + timestamp + ');\n'; | ||||
|   } | ||||
|   return code; | ||||
| }; | ||||
| @ -1,6 +1,228 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { Block } from 'blockly'; | ||||
| import Blockly from 'blockly'; | ||||
| 
 | ||||
| Blockly.Arduino['sensebox_telegram'] = function (Block) { | ||||
| /** | ||||
|  * HDC1080 Temperature and Humidity Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_temp_hum = function () { | ||||
|     var dropdown_name = this.getFieldValue('NAME'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_hdc'] = 'HDC1080 hdc;'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_sensor_temp_hum'] = 'hdc.begin();'; | ||||
|     var code = 'hdc.get' + dropdown_name + '()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * VEML 6070 and TSL4513 UV-Light/Illuminance Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_uv_light = function () { | ||||
|     var dropdown_name = this.getFieldValue('NAME'); | ||||
|     let code = ''; | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     if (dropdown_name === 'UvIntensity') { | ||||
|         Blockly.Arduino.definitions_['define_veml'] = 'VEML6070 veml;' | ||||
|         Blockly.Arduino.setupCode_['sensebox_sensor_uv_light'] = 'veml.begin();' | ||||
|         code = 'veml.get' + dropdown_name + '()'; | ||||
|     } | ||||
|     if (dropdown_name === 'Illuminance') { | ||||
|         Blockly.Arduino.definitions_['define_tsl'] = 'TSL45315 tsl;' | ||||
|         Blockly.Arduino.setupCode_['sensebox_sensor_illuminance'] = 'tsl.begin();' | ||||
|         code = 'tsl.get' + dropdown_name + '()'; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BMX055 Accelerometer | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_bmx055_accelerometer = function () { | ||||
|     var dropdown_value = this.getFieldValue('VALUE'); | ||||
|     var range = this.getFieldValue('RANGE'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_bmx'] = 'BMX055 bmx;'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_sensor_bmx055'] = 'bmx.beginAcc(' + range + ');'; | ||||
|     var code = 'bmx.getAcceleration' + dropdown_value + '()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * SDS011 Fine Particlar Matter | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_sds011 = function () { | ||||
|     var dropdown_name = this.getFieldValue('NAME'); | ||||
|     var serial_name = this.getFieldValue('SERIAL'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.codeFunctions_['define_sds011'] = 'SDS011 my_sds(' + serial_name + ');'; | ||||
|     Blockly.Arduino.variables_['variables_sds011'] = 'float p10,p25;\n'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_sensor_sds011'] = serial_name + '.begin(9600);'; | ||||
|     var code = 'my_sds.get' + dropdown_name + '()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * BMP280 Pressure Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_pressure = function () { | ||||
|     var dropdown_name = this.getFieldValue('NAME'); | ||||
|     var code = ''; | ||||
|     var referencePressure = this.getFieldValue('referencePressure'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_pressure'] = 'BMP280 bmp_sensor;'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_bmp_sensor'] = 'bmp_sensor.begin();'; | ||||
|     if (dropdown_name === 'Pressure' || dropdown_name === 'Temperature') { | ||||
|         code = 'bmp_sensor.get' + dropdown_name + '()'; | ||||
|     } | ||||
|     else if (dropdown_name === 'Altitude') { | ||||
|         code = 'bmp_sensor.getAltitude(' + referencePressure + ')'; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * BME680 Environmental Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_bme680_bsec = function () { | ||||
|     var dropdown_name = this.getFieldValue('dropdown'); | ||||
|     let code = ''; | ||||
|     Blockly.Arduino.libraries_['library_bsec'] = '#include "bsec.h"'; | ||||
|     Blockly.Arduino.definitions_['bsec_iaqSensor'] = 'Bsec iaqSensor;' | ||||
|     Blockly.Arduino.variables_['bmeTemperatur'] = 'float bmeTemperatur;'; | ||||
|     Blockly.Arduino.variables_['bmeHumidity'] = 'float bmeHumidity;'; | ||||
|     Blockly.Arduino.variables_['bmePressure'] = 'double bmePressure;'; | ||||
|     Blockly.Arduino.variables_['bmeIAQ'] = 'float bmeIAQ;'; | ||||
|     Blockly.Arduino.variables_['bmeIAQAccuracy'] = 'float bmeIAQAccuracy;'; | ||||
|     Blockly.Arduino.variables_['bmeCO2'] = 'int bmeCO2;'; | ||||
|     Blockly.Arduino.variables_['bmeBreathVocEquivalent'] = 'float bmeBreathVocEquivalent;' | ||||
| 
 | ||||
|     Blockly.Arduino.functionNames_['checkIaqSensorStatus'] = ` | ||||
|     void checkIaqSensorStatus(void) | ||||
|   { | ||||
|     if (iaqSensor.status != BSEC_OK) { | ||||
|       if (iaqSensor.status < BSEC_OK) { | ||||
|         for (;;) | ||||
|           errLeds(); /* Halt in case of failure */ | ||||
|       }  | ||||
|     } | ||||
|    | ||||
|     if (iaqSensor.bme680Status != BME680_OK) { | ||||
|       if (iaqSensor.bme680Status < BME680_OK) { | ||||
|         for (;;) | ||||
|           errLeds(); /* Halt in case of failure */ | ||||
|       }  | ||||
|     } | ||||
|   } | ||||
|   `;
 | ||||
|     Blockly.Arduino.functionNames_['errLeds'] = ` | ||||
|   void errLeds(void) | ||||
|   { | ||||
|     pinMode(LED_BUILTIN, OUTPUT); | ||||
|     digitalWrite(LED_BUILTIN, HIGH); | ||||
|     delay(100); | ||||
|     digitalWrite(LED_BUILTIN, LOW); | ||||
|     delay(100); | ||||
|   }`;
 | ||||
|     //Setup Code
 | ||||
|     Blockly.Arduino.setupCode_['Wire.begin'] = 'Wire.begin();'; | ||||
|     Blockly.Arduino.setupCode_['iaqSensor.begin'] = 'iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire);'; | ||||
|     Blockly.Arduino.setupCode_['checkIaqSensorStatus'] = 'checkIaqSensorStatus();'; | ||||
|     Blockly.Arduino.setupCode_['bsec_sensorlist'] = ` | ||||
|     bsec_virtual_sensor_t sensorList[10] = { | ||||
|       BSEC_OUTPUT_RAW_TEMPERATURE, | ||||
|       BSEC_OUTPUT_RAW_PRESSURE, | ||||
|       BSEC_OUTPUT_RAW_HUMIDITY, | ||||
|       BSEC_OUTPUT_RAW_GAS, | ||||
|       BSEC_OUTPUT_IAQ, | ||||
|       BSEC_OUTPUT_STATIC_IAQ, | ||||
|       BSEC_OUTPUT_CO2_EQUIVALENT, | ||||
|       BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, | ||||
|       BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, | ||||
|       BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, | ||||
|     }; | ||||
|     `;
 | ||||
|     Blockly.Arduino.setupCode_['iaqSensorUpdateSubscription'] = 'iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);\ncheckIaqSensorStatus();'; | ||||
|     //Loop Code
 | ||||
|     Blockly.Arduino.loopCodeOnce_['iaqloop'] = ` | ||||
|     if (iaqSensor.run()) { | ||||
|       bmeTemperatur = iaqSensor.temperature; | ||||
|       bmeHumidity = iaqSensor.humidity; | ||||
|       bmePressure = iaqSensor.pressure; | ||||
|       bmeIAQ = iaqSensor.iaq; | ||||
|       bmeIAQAccuracy = iaqSensor.iaqAccuracy; | ||||
|       bmeCO2 = iaqSensor.co2Equivalent; | ||||
|       bmeBreathVocEquivalent = iaqSensor.breathVocEquivalent; | ||||
|     } else { | ||||
|       checkIaqSensorStatus(); | ||||
|     } | ||||
|     `;
 | ||||
|     switch (dropdown_name) { | ||||
|         case 'temperature': | ||||
|             code = 'bmeTemperatur'; | ||||
|             break; | ||||
|         case 'humidity': | ||||
|             code = 'bmeHumidity'; | ||||
|             break; | ||||
|         case 'pressure': | ||||
|             code = 'bmePressure' | ||||
|             break; | ||||
|         case 'IAQ': | ||||
|             code = 'bmeIAQ'; | ||||
|             break; | ||||
|         case 'IAQAccuracy': | ||||
|             code = 'bmeIAQAccuracy'; | ||||
|             break; | ||||
|         case 'CO2': | ||||
|             code = 'bmeCO2'; | ||||
|             break; | ||||
|         case 'breathVocEquivalent': | ||||
|             code = 'bmeBreathVocEquivalent'; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Ultrasonic Distance Sensor | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_ultrasonic_ranger = function () { | ||||
|     var dropdown_pin_RX = this.getFieldValue('ultrasonic_trigger'); | ||||
|     var dropdown_pin_TX = this.getFieldValue('ultrasonic_echo'); | ||||
|     var port = this.getFieldValue('port'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['var_ultrasonic' + port] = 'Ultrasonic Ultrasonic' + port + '(' + dropdown_pin_RX + ',' + dropdown_pin_TX + ');'; | ||||
|     var code; | ||||
|     code = 'Ultrasonic' + port + '.getDistance()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Microphone | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_sensor_sound = function () { | ||||
|     var dropdown_pin = this.getFieldValue('PIN'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_microphone'] = 'Microphone microphone(' + dropdown_pin + ');' | ||||
|     var code = 'microphone.getValue()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
							
								
								
									
										57
									
								
								src/components/Blockly/generator/sensebox-telegram.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/components/Blockly/generator/sensebox-telegram.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Telegram Bot by re:edu | ||||
|  */ | ||||
| Blockly.Arduino.sensebox_telegram = function (Block) { | ||||
|   let token = Block.getFieldValue('telegram_token'); | ||||
|   Blockly['Arduino'].libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|   Blockly['Arduino'].libraries_['library_telegram'] = `#include <UniversalTelegramBot.h>` | ||||
|   Blockly['Arduino'].functionNames_['WiFiSSLClient'] = 'WiFiSSLClient client;'; | ||||
|   Blockly['Arduino'].functionNames_['telegram_objects'] = `#define BOTtoken "${token}"  // your Bot Token (Get from Botfather)
 | ||||
|        | ||||
|     UniversalTelegramBot bot(BOTtoken, client);` | ||||
| 
 | ||||
|   let code = 'testcode'; | ||||
|   return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_telegram_do = function (block) { | ||||
|   var messageProcessing = Blockly.Arduino.statementToCode(block, 'telegram_do', Blockly.Arduino.ORDER_ATOMIC); | ||||
| 
 | ||||
|   Blockly.Arduino.definitions_['telegram_variables'] = `int Bot_mtbs = 1000; //mean time between scan messages
 | ||||
|   long Bot_lasttime;   //last time messages' scan has been done`
 | ||||
| 
 | ||||
|   Blockly.Arduino.loopCodeOnce_['sensebox_telegram_loop'] = `if (millis() > Bot_lasttime + Bot_mtbs)  {
 | ||||
|       int numNewMessages = bot.getUpdates(bot.last_message_received + 1); | ||||
|       while(numNewMessages) { | ||||
|         for(int i=0; i<numNewMessages; i++) { | ||||
|           String chat_id = String(bot.messages[i].chat_id); | ||||
|           String text = bot.messages[i].text; | ||||
|    | ||||
|           ${messageProcessing} | ||||
|         } | ||||
|         numNewMessages = bot.getUpdates(bot.last_message_received + 1); | ||||
|       } | ||||
|       Bot_lasttime = millis(); | ||||
|     }`;
 | ||||
|   var code = ''; | ||||
|   return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_telegram_do_on_message = function (block) { | ||||
|   var message = this.getFieldValue('telegram_message'); | ||||
|   var stuffToDo = Blockly.Arduino.statementToCode(block, 'telegram_do_on_message', Blockly.Arduino.ORDER_ATOMIC); | ||||
|   var code = ` | ||||
|         if (text == "${message}") { | ||||
|           ${stuffToDo} | ||||
|         }`;
 | ||||
|   return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_telegram_send = function (block) { | ||||
|   var textToSend = Blockly.Arduino.valueToCode(this, 'telegram_text_to_send', Blockly.Arduino.ORDER_ATOMIC) || '"Keine Eingabe"'; | ||||
|   var code = `bot.sendMessage(chat_id, String(${textToSend}), "");\n`; | ||||
|   return code; | ||||
| }; | ||||
							
								
								
									
										25
									
								
								src/components/Blockly/generator/sensebox-web.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/components/Blockly/generator/sensebox-web.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| import Blockly from 'blockly'; | ||||
| 
 | ||||
| 
 | ||||
| /* Wifi connection and openSenseMap Blocks*/ | ||||
| Blockly.Arduino.sensebox_wifi = function (block) { | ||||
|     var pw = this.getFieldValue('Password'); | ||||
|     var ssid = this.getFieldValue('SSID'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_network'] = 'Bee* b = new Bee();'; | ||||
|     if (pw === "") { | ||||
|         Blockly.Arduino.setupCode_['sensebox_network'] = 'b->connectToWifi("' + ssid + '");\ndelay(1000);'; | ||||
|     } else | ||||
|         Blockly.Arduino.setupCode_['sensebox_network'] = 'b->connectToWifi("' + ssid + '","' + pw + '");\ndelay(1000);'; | ||||
|     var code = ''; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_startap = function (block) { | ||||
|     var ssid = this.getFieldValue('SSID'); | ||||
|     Blockly.Arduino.libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|     Blockly.Arduino.definitions_['define_network'] = 'Bee* b = new Bee();'; | ||||
|     Blockly.Arduino.setupCode_['sensebox_network'] = 'b->startAP("' + ssid + '");' | ||||
|     var code = ''; | ||||
|     return code; | ||||
| }; | ||||
| @ -1,19 +1,3 @@ | ||||
| import * as Blockly from 'blockly/core'; | ||||
| import { Block } from 'blockly'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Telegram Bot by re:edu | ||||
|  */ | ||||
| Blockly.Arduino['sensebox_telegram'] = function (Block) { | ||||
|   let token = Block.getFieldValue('telegram_token'); | ||||
|   Blockly['Arduino'].libraries_['library_senseBoxMCU'] = '#include "SenseBoxMCU.h"'; | ||||
|   Blockly['Arduino'].libraries_['library_telegram'] = `#include <UniversalTelegramBot.h>` | ||||
|   Blockly['Arduino'].functionNames_['WiFiSSLClient'] = 'WiFiSSLClient client;'; | ||||
|   Blockly['Arduino'].functionNames_['telegram_objects'] = `#define BOTtoken "${token}"  // your Bot Token (Get from Botfather)
 | ||||
|      | ||||
|   UniversalTelegramBot bot(BOTtoken, client);` | ||||
| 
 | ||||
|   let code = 'testcode'; | ||||
|   return code; | ||||
| }; | ||||
							
								
								
									
										80
									
								
								src/components/Blockly/generator/time.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/Blockly/generator/time.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| import Blockly from 'blockly'; | ||||
| 
 | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Arduino code generator for the Time blocks. | ||||
|  *     Arduino built-in function docs: http://arduino.cc/en/Reference/HomePage
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the delay Arduino block. | ||||
|  * Arduino code: loop { delay(X); } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['time_delay'] = function (block) { | ||||
|     var delayTime = Blockly.Arduino.valueToCode( | ||||
|         block, 'DELAY_TIME_MILI', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     var code = 'delay(' + delayTime + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the delayMicroseconds block. | ||||
|  * Arduino code: loop { delayMicroseconds(X); } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['time_delaymicros'] = function (block) { | ||||
|     var delayTimeMs = Blockly.Arduino.valueToCode( | ||||
|         block, 'DELAY_TIME_MICRO', Blockly.Arduino.ORDER_ATOMIC) || '0'; | ||||
|     var code = 'delayMicroseconds(' + delayTimeMs + ');\n'; | ||||
|     return code; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the elapsed time in milliseconds block. | ||||
|  * Arduino code: loop { millis() } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['time_millis'] = function (block) { | ||||
|     var code = 'millis()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the elapsed time in microseconds block. | ||||
|  * Arduino code: loop { micros() } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {array} Completed code with order of operation. | ||||
|  */ | ||||
| Blockly.Arduino['time_micros'] = function (block) { | ||||
|     var code = 'micros()'; | ||||
|     return [code, Blockly.Arduino.ORDER_ATOMIC]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Code generator for the wait forever (end of program) block | ||||
|  * Arduino code: loop { while(true); } | ||||
|  * @param {!Blockly.Block} block Block to generate the code from. | ||||
|  * @return {string} Completed code. | ||||
|  */ | ||||
| Blockly.Arduino['infinite_loop'] = function (block) { | ||||
|     return 'while(true);\n'; | ||||
| }; | ||||
| 
 | ||||
| Blockly.Arduino.sensebox_interval_timer = function (block) { | ||||
|     var interval = this.getFieldValue('interval'); | ||||
|     Blockly.Arduino.variables_['define_interval_variables'] = 'const long interval = ' + interval + ';\nlong time_start = 0;\nlong time_actual = 0;'; | ||||
|     var branch = Blockly.Arduino.statementToCode(block, 'DO'); | ||||
|     var code = 'time_start = millis();\n'; | ||||
|     code += 'if (time_start > time_actual + interval) {\n  time_actual = millis();\n' | ||||
|     code += branch; | ||||
|     code += '}\n' | ||||
|     return code; | ||||
| }; | ||||
							
								
								
									
										44
									
								
								src/components/Blockly/helpers/board.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/components/Blockly/helpers/board.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /** | ||||
|  * Define boards and pins | ||||
|  * | ||||
|  */ | ||||
| const sensebox_mcu = { | ||||
|     description: 'senseBox Microcontroller Unit based on Microchip SAMD21G18A', | ||||
|     compilerFlag: 'arduino:samd', | ||||
|     digitalPins: [['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']], | ||||
|     digitalPinsLED: [['BUILTIN_1', '7'], ['BUILTIN_2', '8'], ['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']], | ||||
|     digitalPinsButton: [['on Board', '0'], ['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']], | ||||
|     pwmPins: [['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']], | ||||
|     serial: [['serial', 'SerialUSB'], ['serial_1', 'Serial1'], ['serial_2', 'Serial2']], | ||||
|     serialPins: { | ||||
|         SerialUSB: [['RX', ''], ['TX', '']], | ||||
|         Serial1: [['RX', '11'], ['TX', '10']], | ||||
|         Serial2: [['RX', '13'], ['TX', '12']] | ||||
|     }, | ||||
|     serialSpeed: [['300', '300'], ['600', '600'], ['1200', '1200'], | ||||
|     ['2400', '2400'], ['4800', '4800'], ['9600', '9600'], | ||||
|     ['14400', '14400'], ['19200', '19200'], ['28800', '28800'], | ||||
|     ['31250', '31250'], ['38400', '38400'], ['57600', '57600'], | ||||
|     ['115200', '115200']], | ||||
|     spi: [['SPI', 'SPI']], | ||||
|     spiPins: { SPI: [['MOSI', '19'], ['MISO', '21'], ['SCK', '20']] }, | ||||
|     spiClockDivide: [['2 (8MHz)', 'SPI_CLOCK_DIV2'], | ||||
|     ['4 (4MHz)', 'SPI_CLOCK_DIV4'], | ||||
|     ['8 (2MHz)', 'SPI_CLOCK_DIV8'], | ||||
|     ['16 (1MHz)', 'SPI_CLOCK_DIV16'], | ||||
|     ['32 (500KHz)', 'SPI_CLOCK_DIV32'], | ||||
|     ['64 (250KHz)', 'SPI_CLOCK_DIV64'], | ||||
|     ['128 (125KHz)', 'SPI_CLOCK_DIV128']], | ||||
|     i2c: [['I2C', 'Wire']], | ||||
|     i2cPins: { Wire: [['SDA', '17'], ['SCL', '16']] }, | ||||
|     i2cSpeed: [['100kHz', '100000L'], ['400kHz', '400000L']], | ||||
|     builtinLed: [['BUILTIN_1', '7'], ['BUILTIN_2', '8']], | ||||
|     interrupt: [['interrupt1', '1'], ['interrupt2', '2'], ['interrupt3', '3'], ['interrupt4', '4'], ['interrupt5', '5'], ['interrupt6', '6']], | ||||
|     analogPins: [['A1', 'A1'], ['A2', 'A2'], ['A3', 'A3'], ['A4', 'A4'], ['A5', 'A5'], ['A6', 'A6']], | ||||
|     serial_baud_rate: 9600, | ||||
|     parseKey: '_*_' | ||||
| }; | ||||
| 
 | ||||
| export const selectedBoard = () => { | ||||
|     return sensebox_mcu; | ||||
| }; | ||||
							
								
								
									
										16
									
								
								src/components/Blockly/helpers/colour.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/components/Blockly/helpers/colour.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| 
 | ||||
| const colours = { | ||||
|     sensebox: 120, | ||||
|     logic: 210, | ||||
|     loops: 10, | ||||
|     math: 230, | ||||
|     io: 60, | ||||
|     procedures: 290, | ||||
|     time: 140, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| export const getColour = () => { | ||||
|     return colours; | ||||
| }; | ||||
| 
 | ||||
							
								
								
									
										221
									
								
								src/components/Blockly/helpers/types.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								src/components/Blockly/helpers/types.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,221 @@ | ||||
| /** | ||||
|  * @license Licensed under the Apache License, Version 2.0 (the "License"): | ||||
|  *          http://www.apache.org/licenses/LICENSE-2.0
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @fileoverview Blockly Types declarations and helper functions to identify | ||||
|  *     types. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| /** Single character. */ | ||||
| export const CHARACTER = { | ||||
|     typeId: 'Character', | ||||
|     typeMsgName: 'ARD_TYPE_CHAR', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| export const BOOLEAN = { | ||||
|     typeId: 'Boolean', | ||||
|     typeMsgName: 'ARD_TYPE_BOOL', | ||||
|     compatibleTypes: ['Boolean'] | ||||
| } | ||||
| 
 | ||||
| /** Text string. */ | ||||
| export const TEXT = { | ||||
|     typeId: 'Text', | ||||
|     typeMsgName: 'ARD_TYPE_TEXT', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| /** Short integer number. */ | ||||
| export const SHORT_NUMBER = { | ||||
|     typeId: 'Short Number', | ||||
|     typeMsgName: 'ARD_TYPE_SHORT', | ||||
|     compatibleTypes: []    // Circular dependencies, add after all declarations
 | ||||
| } | ||||
| 
 | ||||
| /** Integer number. */ | ||||
| export const NUMBER = { | ||||
|     typeId: 'Number', | ||||
|     typeMsgName: 'ARD_TYPE_NUMBER', | ||||
|     compatibleTypes: ['Number']    // Circular dependencies, add after all declarations
 | ||||
| } | ||||
| 
 | ||||
| /** Large integer number. */ | ||||
| export const LARGE_NUMBER = { | ||||
|     typeId: 'Large Number', | ||||
|     typeMsgName: 'ARD_TYPE_LONG', | ||||
|     compatibleTypes: []    // Circular dependencies, add after all declarations
 | ||||
| } | ||||
| 
 | ||||
| /** Decimal/floating point number. */ | ||||
| export const DECIMAL = { | ||||
|     typeId: 'Decimal', | ||||
|     typeMsgName: 'ARD_TYPE_DECIMAL', | ||||
|     compatibleTypes: [BOOLEAN.typeId, | ||||
|         NUMBER, | ||||
|         SHORT_NUMBER, | ||||
|         LARGE_NUMBER] | ||||
| } | ||||
| 
 | ||||
| /** Array/List of items. */ | ||||
| export const ARRAY = { | ||||
|     typeId: 'Array', | ||||
|     typeMsgName: 'ARD_TYPE_ARRAY', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| /** Null indicate there is no type. */ | ||||
| export const NULL = { | ||||
|     typeId: 'Null', | ||||
|     typeMsgName: 'ARD_TYPE_NULL', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| /** Type not defined, or not yet defined. */ | ||||
| export const UNDEF = { | ||||
|     typeId: 'Undefined', | ||||
|     typeMsgName: 'ARD_TYPE_UNDEF', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| /** Set when no child block (meant to define the variable type) is connected. */ | ||||
| export const CHILD_BLOCK_MISSING = { | ||||
|     typeId: 'ChildBlockMissing', | ||||
|     typeMsgName: 'ARD_TYPE_CHILDBLOCKMISSING', | ||||
|     compatibleTypes: [] | ||||
| } | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Some Types have circular dependencies on their compatibilities, so add them
 | ||||
| //  * after declaration.
 | ||||
| //  */
 | ||||
| // Blockly.Types.NUMBER.addCompatibleTypes([
 | ||||
| //     Blockly.Types.BOOLEAN,
 | ||||
| //     Blockly.Types.SHORT_NUMBER,
 | ||||
| //     Blockly.Types.LARGE_NUMBER,
 | ||||
| //     Blockly.Types.DECIMAL]);
 | ||||
| 
 | ||||
| // Blockly.Types.SHORT_NUMBER.addCompatibleTypes([
 | ||||
| //     Blockly.Types.BOOLEAN,
 | ||||
| //     Blockly.Types.NUMBER,
 | ||||
| //     Blockly.Types.LARGE_NUMBER,
 | ||||
| //     Blockly.Types.DECIMAL]);
 | ||||
| 
 | ||||
| // Blockly.Types.LARGE_NUMBER.addCompatibleTypes([
 | ||||
| //     Blockly.Types.BOOLEAN,
 | ||||
| //     Blockly.Types.SHORT_NUMBER,
 | ||||
| //     Blockly.Types.NUMBER,
 | ||||
| //     Blockly.Types.DECIMAL]);
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Adds another type to the Blockly.Types collection.
 | ||||
| //  * @param {string} typeId_ Identifiable name of the type.
 | ||||
| //  * @param {string} typeMsgName_ Name of the member variable from Blockly.Msg
 | ||||
| //  *     object to identify the translateble string.for the Type name.
 | ||||
| //  * @param {Array<Blockly.Type>} compatibleTypes_ List of types this Type is
 | ||||
| //  *     compatible with.
 | ||||
| //  */
 | ||||
| // Blockly.Types.addType = function (typeId_, typeMsgName_, compatibleTypes_) {
 | ||||
| //     // The Id is used as the key from the value pair in the BlocklyTypes object
 | ||||
| //     var key = typeId_.toUpperCase().replace(/ /g, '_');
 | ||||
| //     if (Blockly.Types[key] !== undefined) {
 | ||||
| //         throw 'The Blockly type ' + key + ' already exists.';
 | ||||
| //     }
 | ||||
| //     Blockly.Types[key] = new Blockly.Type({
 | ||||
| //         typeId: typeId_,
 | ||||
| //         typeName: typeMsgName_,
 | ||||
| //         compatibleTypes: compatibleTypes_
 | ||||
| //     });
 | ||||
| // };
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Converts the static types dictionary in to a an array with 2-item arrays.
 | ||||
| //  * This array only contains the valid types, excluding any error or temp types.
 | ||||
| //  * @return {!Array<Array<string>>} Blockly types in the format described above.
 | ||||
| //  */
 | ||||
| // Blockly.Types.getValidTypeArray = function () {
 | ||||
| //     var typesArray = [];
 | ||||
| //     for (var typeKey in Blockly.Types) {
 | ||||
| //         if ((typeKey !== 'UNDEF') && (typeKey !== 'CHILD_BLOCK_MISSING') &&
 | ||||
| //             (typeKey !== 'NULL') && (typeKey !== 'ARRAY') &&
 | ||||
| //             (typeof Blockly.Types[typeKey] !== 'function') &&
 | ||||
| //             !(Blockly.Types[typeKey] instanceof RegExp)) {
 | ||||
| //             typesArray.push([Blockly.Types[typeKey].typeName, typeKey]);
 | ||||
| //         }
 | ||||
| //     }
 | ||||
| //     return typesArray;
 | ||||
| // };
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Navigates through child blocks of the argument block to get this block type.
 | ||||
| //  * @param {!Blockly.Block} block Block to navigate through children.
 | ||||
| //  * @return {Blockly.Type} Type of the input block.
 | ||||
| //  */
 | ||||
| // Blockly.Types.getChildBlockType = function (block) {
 | ||||
| //     var blockType = null;
 | ||||
| //     var nextBlock = block;
 | ||||
| //     // Only checks first input block, so it decides the type. Incoherences amongst
 | ||||
| //     // multiple inputs dealt at a per-block level with their own block warnings
 | ||||
| //     while (nextBlock && (nextBlock.getBlockType === undefined) &&
 | ||||
| //         (nextBlock.inputList.length > 0) &&
 | ||||
| //         (nextBlock.inputList[0].connection)) {
 | ||||
| //         nextBlock = nextBlock.inputList[0].connection.targetBlock();
 | ||||
| //     }
 | ||||
| //     if (nextBlock === block) {
 | ||||
| //         // Set variable block is empty, so no type yet
 | ||||
| //         blockType = Blockly.Types.CHILD_BLOCK_MISSING;
 | ||||
| //     } else if (nextBlock === null) {
 | ||||
| //         // Null return from targetBlock indicates no block connected
 | ||||
| //         blockType = Blockly.Types.CHILD_BLOCK_MISSING;
 | ||||
| //     } else {
 | ||||
| //         var func = nextBlock.getBlockType;
 | ||||
| //         if (func) {
 | ||||
| //             blockType = nextBlock.getBlockType();
 | ||||
| //         } else {
 | ||||
| //             // Most inner block, supposed to define a type, is missing getBlockType()
 | ||||
| //             blockType = Blockly.Types.NULL;
 | ||||
| //         }
 | ||||
| //     }
 | ||||
| //     return blockType;
 | ||||
| // };
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Regular expressions to identify an integer.
 | ||||
| //  * @private
 | ||||
| //  */
 | ||||
| // Blockly.Types.regExpInt_ = new RegExp(/^-?\d+$/);
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Regular expressions to identify a decimal.
 | ||||
| //  * @private
 | ||||
| //  */
 | ||||
| // Blockly.Types.regExpFloat_ = new RegExp(/^-?[0-9]*[.][0-9]+$/);
 | ||||
| 
 | ||||
| // /**
 | ||||
| //  * Uses regular expressions to identify if the input number is an integer or a
 | ||||
| //  * floating point.
 | ||||
| //  * @param {string} numberString String of the number to identify.
 | ||||
| //  * @return {!Blockly.Type} Blockly type.
 | ||||
| //  */
 | ||||
| // Blockly.Types.identifyNumber = function (numberString) {
 | ||||
| //     if (Blockly.Types.regExpInt_.test(numberString)) {
 | ||||
| //         var intValue = parseInt(numberString);
 | ||||
| //         if (isNaN(intValue)) {
 | ||||
| //             return Blockly.Types.NULL;
 | ||||
| //         }
 | ||||
| //         if (intValue > 32767 || intValue < -32768) {
 | ||||
| //             return Blockly.Types.LARGE_NUMBER;
 | ||||
| //         }
 | ||||
| //         return Blockly.Types.NUMBER;
 | ||||
| //     } else if (Blockly.Types.regExpFloat_.test(numberString)) {
 | ||||
| //         return Blockly.Types.DECIMAL;
 | ||||
| //     }
 | ||||
| //     return Blockly.Types.NULL;
 | ||||
| // };
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -749,3 +749,4 @@ Blockly.Msg.sensebox_display_show_tip = "Print on Display"; | ||||
| Blockly.Msg.sensebox_sd_filename = "data"; | ||||
| Blockly.Msg.sensebox_soil_smt50 = "Soil Moisture and Temperature (SMT50)"; | ||||
| Blockly.Msg.sensebox_web_readHTML_filename = "File:"; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										297
									
								
								src/components/Blockly/toolbox/Toolbox.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								src/components/Blockly/toolbox/Toolbox.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,297 @@ | ||||
| import React from 'react'; | ||||
| import { Block, Value, Field, Shadow, Category } from '../'; | ||||
| import { getColour } from '../helpers/colour' | ||||
| 
 | ||||
| 
 | ||||
| class Toolbox extends React.Component { | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
|             <xml xmlns="https://developers.google.com/blockly/xml" id="blockly" style={{ display: 'none' }} ref={this.props.toolbox}> | ||||
|                 <Category name="senseBox" colour={getColour().sensebox}> | ||||
|                     <Category name="Sensoren" colour={getColour().sensebox}> | ||||
|                         <Block type="sensebox_sensor_temp_hum" /> | ||||
|                         <Block type="sensebox_sensor_uv_light" /> | ||||
|                         <Block type="sensebox_sensor_bmx055_accelerometer" /> | ||||
|                         <Block type="sensebox_sensor_sds011" /> | ||||
|                         <Block type="sensebox_sensor_pressure" /> | ||||
|                         <Block type="sensebox_sensor_bme680_bsec" /> | ||||
|                         <Block type="sensebox_sensor_ultrasonic_ranger" /> | ||||
|                         <Block type="sensebox_sensor_sound" /> | ||||
|                     </Category > | ||||
|                     <Category name="WIFI" colour={getColour().sensebox}> | ||||
|                         <Block type="sensebox_wifi" /> | ||||
|                         <Block type="sensebox_startap" /> | ||||
|                     </Category> | ||||
|                     <Category name="Display" colour={getColour().sensebox}> | ||||
|                         <Block type="sensebox_display_beginDisplay" /> | ||||
|                         <Block type="sensebox_display_show" /> | ||||
|                         <Block type="sensebox_display_clearDisplay" /> | ||||
|                         <Block type="sensebox_display_printDisplay"> | ||||
|                             <Value name="SIZE"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">1</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="X"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="Y"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                         </Block> | ||||
|                         <Block type="sensebox_display_plotDisplay"> | ||||
|                             <Value name="Title"> | ||||
|                                 <Block type="text"> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="YLabel"> | ||||
|                                 <Block type="text"> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="XLabel"> | ||||
|                                 <Block type="text"> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="XRange1"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="XRange2"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">15</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="YRange1"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="YRange2"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">50</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="XTick"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">5</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="YTick"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="TimeFrame"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">15</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                         </Block> | ||||
|                         <Block type="sensebox_display_fillCircle"> | ||||
|                             <Value name="X"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="Y"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="Radius"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                         </Block> | ||||
|                         <Block type="sensebox_display_drawRectangle"> | ||||
|                             <Value name="X"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="Y"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="height"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                             <Value name="width"> | ||||
|                                 <Block type="math_number"> | ||||
|                                     <Field name="NUM">0</Field> | ||||
|                                 </Block> | ||||
|                             </Value> | ||||
|                         </Block> | ||||
|                     </Category> | ||||
|                     <Category name="Telegram" colour={getColour().sensebox}> | ||||
|                         <Block type="sensebox_telegram" /> | ||||
|                         <Block type="sensebox_telegram_do" /> | ||||
|                         <Block type="sensebox_telegram_do_on_message" /> | ||||
|                         <Block type="sensebox_telegram_send" /> | ||||
|                     </Category> | ||||
|                     <Category name="osem" colour={getColour().sensebox}> | ||||
|                         <Block type="sensebox_osem_connection" /> | ||||
|                     </Category> | ||||
|                     <Category id="catSenseBoxOutput_LoRa" name="  LoRa" colour={getColour().sensebox}> | ||||
|                         <Category id="catSenseBoxOutput_LoRa_activation" name="  Activation" colour={getColour().sensebox}> | ||||
|                             <Block type="sensebox_lora_initialize_otaa" /> | ||||
|                             <Block type="sensebox_lora_initialize_abp" /> | ||||
|                         </Category> | ||||
|                         <Category id="catSenseBoxOutput_LoRa_loramessage" name="    Lora Message" colour={getColour().sensebox}> | ||||
|                             <Block type="sensebox_lora_message_send" /> | ||||
|                             <Block type="sensebox_send_lora_sensor_value" /> | ||||
|                         </Category> | ||||
|                         <Category id="catSenseBoxOutput_LoRa_cayenne" name="    Cayenne LPP" colour={getColour().sensebox}> | ||||
|                             <Block type="sensebox_lora_cayenne_send" /> | ||||
|                             <Block type="sensebox_lora_cayenne_temperature" /> | ||||
|                             <Block type="sensebox_lora_cayenne_humidity" /> | ||||
|                             <Block type="sensebox_lora_cayenne_pressure" /> | ||||
|                             <Block type="sensebox_lora_cayenne_luminosity" /> | ||||
|                             <Block type="sensebox_lora_cayenne_sensor" /> | ||||
|                             <Block type="sensebox_lora_cayenne_accelerometer" /> | ||||
|                             <Block type="sensebox_lora_cayenne_gps" /> | ||||
|                         </Category> | ||||
|                     </Category> | ||||
|                 </Category> | ||||
|                 <Category name="Logic" colour={getColour().logic}> | ||||
|                     <Block type="controls_if" /> | ||||
|                     <Block type="controls_ifelse" /> | ||||
|                     <Block type="logic_compare" /> | ||||
|                     <Block type="logic_operation" /> | ||||
|                     <Block type="logic_negate" /> | ||||
|                     <Block type="logic_boolean" /> | ||||
|                 </Category> | ||||
|                 <Category id="loops" name="Loops" colour={getColour().loops}> | ||||
|                     <Block type="controls_repeat_ext"> | ||||
|                         <Value name="TIMES"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">10</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="controls_whileUntil" /> | ||||
|                     <Block type="controls_for"> | ||||
|                         <Value name="FROM"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">1</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                         <Value name="TO" > | ||||
|                             <Block type="math_number" > | ||||
|                                 <Field name="NUM">10</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                         <Value name="BY" > | ||||
|                             <Block Type="math_number" > | ||||
|                                 <Field name="NUM">1</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="controls_flow_statements" /> | ||||
|                 </Category> | ||||
|                 <Category id="time" name="Time" colour={getColour().time}> | ||||
|                     <Block type="time_delay"> | ||||
|                         <Value name="DELAY_TIME_MILI"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">1000</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="time_delaymicros"> | ||||
|                         <Value name="DELAY_TIME_MICRO"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">100</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="time_millis"></Block> | ||||
|                     <Block type="time_micros"></Block> | ||||
|                     <Block type="infinite_loop"></Block> | ||||
|                     <Block type="sensebox_interval_timer"></Block> | ||||
|                 </Category> | ||||
|                 <Category id="catMath" name="Math" colour={getColour().math}> | ||||
|                     <Block type="math_number"></Block> | ||||
|                     <Block type="math_arithmetic"></Block> | ||||
|                     <Block type="math_single"></Block> | ||||
|                     <Block type="math_trig"></Block> | ||||
|                     <Block type="math_constant"></Block> | ||||
|                     <Block type="math_number_property"></Block> | ||||
|                     <Block type="math_change"> | ||||
|                         <Value name="DELTA"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">1</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="math_round"></Block> | ||||
|                     <Block type="math_modulo"></Block> | ||||
|                     <Block type="math_constrain"> | ||||
|                         <Value name="LOW"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">1</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                         <Value name="HIGH"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">100</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="math_random_int"> | ||||
|                         <Value name="FROM"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">1</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                         <Value name="TO"> | ||||
|                             <Block type="math_number"> | ||||
|                                 <Field name="NUM">100</Field> | ||||
|                             </Block> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="math_random_float"></Block> | ||||
|                     <Block type="base_map"></Block> | ||||
|                 </Category> | ||||
|                 <sep></sep> | ||||
|                 <Category name="Input/Output" colour={getColour().io}> | ||||
|                     <Block type="io_digitalwrite"></Block> | ||||
|                     <Block type="io_digitalread"></Block> | ||||
|                     <Block type="io_builtin_led"></Block> | ||||
|                     <Block type="io_analogwrite"></Block> | ||||
|                     <Block type="io_analogread"></Block> | ||||
|                     <Block type="io_highlow"></Block> | ||||
|                     <Block type="io_pulsein"> | ||||
|                         <Value name="PULSETYPE"> | ||||
|                             <Shadow type="io_highlow"></Shadow> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                     <Block type="io_pulsetimeout"> | ||||
|                         <Value name="PULSETYPE"> | ||||
|                             <Shadow type="io_highlow"></Shadow> | ||||
|                         </Value> | ||||
|                         <Value name="TIMEOUT"> | ||||
|                             <Shadow type="math_number"> | ||||
|                                 <Field name="NUM">100</Field> | ||||
|                             </Shadow> | ||||
|                         </Value> | ||||
|                     </Block> | ||||
|                 </Category> | ||||
|                 <Category name="Procedures" colour={getColour().procedures}> | ||||
|                     <Block type="arduino_functions" /> | ||||
|                 </Category> | ||||
|             </xml> | ||||
|         ); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export default Toolbox; | ||||
| @ -11,6 +11,8 @@ import { withStyles } from '@material-ui/core/styles'; | ||||
| import MuiAccordion from '@material-ui/core/Accordion'; | ||||
| import MuiAccordionSummary from '@material-ui/core/AccordionSummary'; | ||||
| import MuiAccordionDetails from '@material-ui/core/AccordionDetails'; | ||||
| import { Card } from '@material-ui/core'; | ||||
| 
 | ||||
| 
 | ||||
| const Accordion = withStyles((theme) => ({ | ||||
|   root: { | ||||
| @ -73,7 +75,7 @@ class CodeViewer extends Component { | ||||
|     var curlyBrackets = '{ }'; | ||||
|     var unequal = '<>'; | ||||
|     return ( | ||||
|       <div style={{height: '500px'}}> | ||||
|       <Card style={{height: '500px'}}> | ||||
|         <Accordion | ||||
|           square={true} | ||||
|           style={{margin: 0}} | ||||
| @ -110,7 +112,7 @@ class CodeViewer extends Component { | ||||
|             </pre> | ||||
|           </AccordionDetails> | ||||
|         </Accordion> | ||||
|       </div> | ||||
|       </Card> | ||||
|     ); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -11,6 +11,7 @@ import Grid from '@material-ui/core/Grid'; | ||||
| import FormControlLabel from '@material-ui/core/FormControlLabel'; | ||||
| import Switch from '@material-ui/core/Switch'; | ||||
| 
 | ||||
| 
 | ||||
| class Home extends Component { | ||||
| 
 | ||||
|   state = { | ||||
|  | ||||
| @ -30,6 +30,29 @@ class WorkspaceFunc extends Component { | ||||
|     this.setState({ open: !this.state }); | ||||
|   } | ||||
| 
 | ||||
|   compile = () => { | ||||
|     const data = { | ||||
|       "board": process.env.REACT_APP_BOARD, | ||||
|       "sketch": this.props.arduino | ||||
|     }; | ||||
| 
 | ||||
|     fetch(`${process.env.REACT_APP_COMPILER_URL}/compile`, { | ||||
|       method: "POST", | ||||
|       headers: {'Content-Type': 'application/json'}, | ||||
|       body: JSON.stringify(data) | ||||
|     }) | ||||
|       .then(response => response.json()) | ||||
|       .then(data => { | ||||
|         console.log(data) | ||||
|         this.download(data.data.id) | ||||
|       }); | ||||
|   } | ||||
| 
 | ||||
|   download = (id) => { | ||||
|     const filename = 'sketch' | ||||
|     window.open(`${process.env.REACT_APP_COMPILER_URL}/download?id=${id}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`, '_self'); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     return ( | ||||
|       <div style={{ marginTop: '20px' }}> | ||||
| @ -51,6 +74,9 @@ class WorkspaceFunc extends Component { | ||||
|           Get XML Code | ||||
|         </Button> | ||||
|         <MaxBlocks /> | ||||
|         <Button style={{ float: 'right', color: 'white' }} variant="contained" color="primary" onClick={() => this.compile()}> | ||||
|           Compile | ||||
|         </Button> | ||||
|       </div> | ||||
|     ); | ||||
|   }; | ||||
|  | ||||
| @ -6,7 +6,8 @@ import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| import { withStyles } from '@material-ui/core/styles'; | ||||
| import Tooltip from '@material-ui/core/Tooltip'; | ||||
| import Typography from '@material-ui/core/Typography'; | ||||
| import Chip from '@material-ui/core/Chip'; | ||||
| import Avatar from '@material-ui/core/Avatar'; | ||||
| 
 | ||||
| import { faPuzzlePiece, faTrash, faPlus, faPen, faArrowsAlt } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| @ -17,7 +18,7 @@ const styles = (theme) => ({ | ||||
|     display: 'inline', | ||||
|     marginLeft: '50px', | ||||
|     padding: '3px 10px', | ||||
|     borderRadius: '25%' | ||||
|     // borderRadius: '25%'
 | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| @ -27,44 +28,54 @@ class WorkspaceStats extends Component { | ||||
|     const workspace = Blockly.getMainWorkspace(); | ||||
|     const remainingBlocksInfinity = workspace ? workspace.remainingCapacity() !== Infinity : null; | ||||
|     return ( | ||||
|       <div style={{marginBottom: '20px', color: 'white'}}> | ||||
|         <Tooltip title="Anzahl aktueller Blöcke" style={{marginLeft: 0}} className={this.props.classes.stats}> | ||||
|           <div> | ||||
|             <FontAwesomeIcon icon={faPuzzlePiece} /> | ||||
|             <Typography style={{display: 'inline'}}> {workspace ? workspace.getAllBlocks().length : 0}</Typography> | ||||
|           </div> | ||||
|       <div style={{ marginBottom: '20px' }}> | ||||
|         <Tooltip title="Anzahl aktueller Blöcke" > | ||||
|           <Chip | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faPuzzlePiece} /></Avatar>} | ||||
|             label={workspace ? workspace.getAllBlocks().length : 0}> | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl neuer Blöcke" className={this.props.classes.stats}> | ||||
|           <div> | ||||
|             <FontAwesomeIcon icon={faPlus} style={{marginRight: '5px'}}/> | ||||
|             <FontAwesomeIcon icon={faPuzzlePiece} /> | ||||
|             <Typography style={{display: 'inline'}}> {this.props.create}</Typography> | ||||
|           </div> | ||||
|         <Tooltip title="Anzahl neuer Blöcke" > | ||||
|           <Chip | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faPlus} /></Avatar>} | ||||
|             label={this.props.create}> | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl veränderter Blöcke" className={this.props.classes.stats}> | ||||
|           <div> | ||||
|             <FontAwesomeIcon icon={faPen} style={{marginRight: '5px'}}/> | ||||
|             <FontAwesomeIcon icon={faPuzzlePiece} /> | ||||
|             <Typography style={{display: 'inline'}}> {this.props.change}</Typography> | ||||
|           </div> | ||||
|         <Tooltip title="Anzahl veränderter Blöcke" > | ||||
|           <Chip | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faPen} /></Avatar>} | ||||
|             label={this.props.change}> | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl bewegter Blöcke" className={this.props.classes.stats}> | ||||
|           <div> | ||||
|             <FontAwesomeIcon icon={faArrowsAlt} style={{marginRight: '5px'}}/> | ||||
|             <FontAwesomeIcon icon={faPuzzlePiece} /> | ||||
|             <Typography style={{display: 'inline'}}> {this.props.move}</Typography> | ||||
|           </div> | ||||
|         <Tooltip title="Anzahl bewegter Blöcke" > | ||||
|           <Chip | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faArrowsAlt} /></Avatar>} | ||||
|             label={this.props.move}> | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl gelöschter Blöcke" className={this.props.classes.stats}> | ||||
|           <div> | ||||
|             <FontAwesomeIcon icon={faTrash} style={{marginRight: '5px'}}/> | ||||
|             <FontAwesomeIcon icon={faPuzzlePiece} /> | ||||
|             <Typography style={{display: 'inline'}}> {this.props.delete}</Typography> | ||||
|           </div> | ||||
|         <Tooltip title="Anzahl gelöschter Blöcke" > | ||||
|           <Chip | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faTrash} /></Avatar>} | ||||
|             label={this.props.delete}> | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         {remainingBlocksInfinity ? | ||||
|           <Tooltip title="verbleibende Blöcke" className={this.props.classes.stats}> | ||||
|             <Typography style={{display: 'inline'}}>{workspace.remainingCapacity()} verbleibende Blöcke</Typography> | ||||
|           <Tooltip title="Verbleibende Blöcke" > | ||||
|             <Chip | ||||
|               style={{ marginRight: '1rem' }} | ||||
|               color="primary" | ||||
|               label={workspace.remainingCapacity()}> | ||||
|             </Chip> | ||||
|           </Tooltip> : null} | ||||
|       </div> | ||||
|     ); | ||||
|  | ||||
| @ -11,7 +11,7 @@ const store = createStore( | ||||
|   initialState, | ||||
|   compose( | ||||
|     applyMiddleware(...middleware), | ||||
|     window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() | ||||
|     // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
 | ||||
|   ) | ||||
| ); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user