add sensebox sensor blocks

This commit is contained in:
Mario 2020-07-31 11:10:22 +02:00
parent 44f2f3ca94
commit 440622a66c
28 changed files with 1919 additions and 177 deletions

View File

@ -10,49 +10,49 @@ export const workspaceChange = () => (dispatch) => {
export const onChangeWorkspace = (event) => (dispatch, getState) => {
dispatch({
type: CHANGE_WORKSPACE,
})
const workspace = Blockly.getMainWorkspace();
var code = getState().workspace.code;
code.arduino = Blockly.Arduino.workspaceToCode(workspace);
var xmlDom = Blockly.Xml.workspaceToDom(workspace);
code.xml = Blockly.Xml.domToPrettyText(xmlDom);
dispatch({
type: NEW_CODE,
payload: code
});
var stats = getState().workspace.stats;
if (event.type === Blockly.Events.BLOCK_CREATE) {
stats.create += event.ids.length;
dispatch({
type: CHANGE_WORKSPACE,
})
const workspace = Blockly.getMainWorkspace();
var code = getState().workspace.code;
code.arduino = Blockly.Arduino.workspaceToCode(workspace);
var xmlDom = Blockly.Xml.workspaceToDom(workspace);
code.xml = Blockly.Xml.domToPrettyText(xmlDom);
dispatch({
type: NEW_CODE,
payload: code
type: CREATE_BLOCK,
payload: stats
});
var stats = getState().workspace.stats;
if (event.type === Blockly.Events.BLOCK_CREATE){
stats.create += event.ids.length;
}
else if (event.type === Blockly.Events.BLOCK_MOVE) {
stats.move += 1;
dispatch({
type: MOVE_BLOCK,
payload: stats
});
}
else if (event.type === Blockly.Events.BLOCK_CHANGE) {
stats.change += 1;
dispatch({
type: CHANGE_BLOCK,
payload: stats
});
}
else if (event.type === Blockly.Events.BLOCK_DELETE) {
if (stats.create > 0) {
stats.delete += event.ids.length;
dispatch({
type: CREATE_BLOCK,
type: DELETE_BLOCK,
payload: stats
});
}
else if (event.type === Blockly.Events.BLOCK_MOVE){
stats.move += 1;
dispatch({
type: MOVE_BLOCK,
payload: stats
});
}
else if (event.type === Blockly.Events.BLOCK_CHANGE){
stats.change += 1;
dispatch({
type: CHANGE_BLOCK,
payload: stats
});
}
else if (event.type === Blockly.Events.BLOCK_DELETE){
if(stats.create > 0){
stats.delete += event.ids.length;
dispatch({
type: DELETE_BLOCK,
payload: stats
});
}
}
}
};
export const clearStats = () => (dispatch) => {

View File

@ -1,6 +1,7 @@
#blocklyDiv {
height: 100%;
min-height: 500px;
min-height: 700px;
width: 100%;
border: 1px solid #4EAF47;
position: relative;
}

View File

@ -25,11 +25,12 @@ 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);
Blockly.setLocale(locale);
class BlocklyComponent extends React.Component {
constructor(props) {

View File

@ -5,12 +5,13 @@ import { onChangeWorkspace } from '../../actions/workspaceActions';
import BlocklyComponent, { Block, Value, Field, Shadow, Category } 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 * as De from './msg/de'; // de locale files
import * as En from './msg/en'; // en locale files
import './blocks/index';
import './generator/index';
class BlocklyWindow extends Component {
constructor(props) {
@ -23,6 +24,7 @@ class BlocklyWindow extends Component {
this.props.onChangeWorkspace({});
workspace.addChangeListener((event) => {
this.props.onChangeWorkspace(event);
Blockly.Events.disableOrphans(event);
});
}
@ -31,10 +33,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,28 +54,11 @@ 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>
</BlocklyComponent >
);
};
}

View File

@ -3,4 +3,10 @@ import './sensebox';
import './logic';
import './sensebox-sensors';
import './sensebox-telegram';
import './io';
import './sensebox-osem';
import './io';
import './math';
import './procedures';
import './time';
import '../helpers/types'

View File

@ -13,6 +13,7 @@
import { defineBlocksWithJsonArray } from 'blockly';
import Blockly from 'blockly/core';
import { selectedBoard } from '../helpers/board'
import * as Types from '../helpers/types'
Blockly.Blocks['io_digitalwrite'] = {
@ -28,7 +29,7 @@ Blockly.Blocks['io_digitalwrite'] = {
.appendField(new Blockly.FieldDropdown(
selectedBoard().digitalPins), 'PIN')
.appendField(Blockly.Msg.ARD_WRITE_TO)
// .setCheck(Blockly.Types.BOOLEAN.checkList);
.setCheck(Types.BOOLEAN.checkList);
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
@ -55,13 +56,13 @@ Blockly.Blocks['io_digitalread'] = {
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_DIGITALREAD)
.appendField(new Blockly.FieldDropdown(
Blockly.Arduino.Boards.selected.digitalPins), 'PIN');
this.setOutput(true, Blockly.Types.BOOLEAN.output);
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 Blockly.Types.BOOLEAN;
return Types.BOOLEAN;
},
/**
* Updates the content of the the pin related fields.
@ -84,9 +85,9 @@ Blockly.Blocks['io_builtin_led'] = {
this.appendValueInput('STATE')
.appendField(Blockly.Msg.ARD_BUILTIN_LED)
.appendField(new Blockly.FieldDropdown(
Blockly.Arduino.Boards.selected.builtinLed), 'BUILT_IN_LED')
selectedBoard().builtinLed), 'BUILT_IN_LED')
.appendField(Blockly.Msg.ARD_WRITE_TO)
.setCheck(Blockly.Types.BOOLEAN.checkList);
.setCheck(Types.BOOLEAN.compatibleTypes);
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
@ -102,7 +103,7 @@ Blockly.Blocks['io_builtin_led'] = {
},
/** @return {!string} The type of input value for the block, an integer. */
getBlockType: function () {
return Blockly.Types.BOOLEAN;
return Types.BOOLEAN;
},
};
@ -117,9 +118,9 @@ Blockly.Blocks['io_analogwrite'] = {
this.appendValueInput('NUM')
.appendField(Blockly.Msg.ARD_ANALOGWRITE)
.appendField(new Blockly.FieldDropdown(
Blockly.Arduino.Boards.selected.pwmPins), 'PIN')
selectedBoard().pwmPins), 'PIN')
.appendField(Blockly.Msg.ARD_WRITE_TO)
.setCheck(Blockly.Types.NUMBER.output);
.setCheck(Types.NUMBER.compatibleTypes);
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
@ -134,7 +135,7 @@ Blockly.Blocks['io_analogwrite'] = {
},
/** @return {!string} The type of input value for the block, an integer. */
getBlockType: function () {
return Blockly.Types.NUMBER;
return Types.NUMBER;
},
};
@ -149,13 +150,13 @@ Blockly.Blocks['io_analogread'] = {
this.appendDummyInput()
.appendField(Blockly.Msg.ARD_ANALOGREAD)
.appendField(new Blockly.FieldDropdown(
Blockly.Arduino.Boards.selected.analogPins), 'PIN');
this.setOutput(true, Blockly.Types.NUMBER.output);
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 Blockly.Types.NUMBER;
return Types.NUMBER.typeId;
},
/**
* Updates the content of the the pin related fields.
@ -178,12 +179,12 @@ Blockly.Blocks['io_highlow'] = {
.appendField(
new Blockly.FieldDropdown([[Blockly.Msg.ARD_HIGH, 'HIGH'], [Blockly.Msg.ARD_LOW, 'LOW']]),
'STATE');
this.setOutput(true, Blockly.Types.BOOLEAN.output);
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 Blockly.Types.BOOLEAN;
return Types.BOOLEAN;
}
};
@ -199,14 +200,14 @@ Blockly.Blocks['io_pulsein'] = {
"args0": [{
"type": "input_value",
"name": "PULSETYPE",
"check": Blockly.Types.BOOLEAN.check
"check": Types.BOOLEAN.compatibleTypes
}, {
"type": "field_dropdown",
"name": "PULSEPIN",
"options": Blockly.Arduino.Boards.selected.digitalPins
"options": selectedBoard().digitalPins,
}
],
"output": Blockly.Types.NUMBER.output,
"output": Types.NUMBER.typeId,
"inputsInline": true,
"colour": 250,
"tooltip": Blockly.Msg.ARD_PULSE_TIP,
@ -215,7 +216,7 @@ Blockly.Blocks['io_pulsein'] = {
},
/** @return {!string} The type of input value for the block, an integer. */
getBlockType: function () {
return Blockly.Types.NUMBER;
return Types.NUMBER.typeId;
}
};
@ -232,18 +233,18 @@ Blockly.Blocks['io_pulsetimeout'] = {
"args0": [{
"type": "input_value",
"name": "PULSETYPE",
"check": Blockly.Types.BOOLEAN.check
"check": Types.BOOLEAN.compatibleTypes
}, {
"type": "field_dropdown",
"name": "PULSEPIN",
"options": Blockly.Arduino.Boards.selected.digitalPins
"options": selectedBoard().digitalPins,
}, {
"type": "input_value",
"name": "TIMEOUT",
"check": Blockly.Types.NUMBER.check
"check": Types.NUMBER.compatibleTypes
}
],
"output": Blockly.Types.NUMBER.output,
"output": Types.NUMBER.typeId,
"inputsInline": true,
"colour": 250,
"tooltip": Blockly.Msg.ARD_PULSETIMEOUT_TIP,
@ -252,6 +253,6 @@ Blockly.Blocks['io_pulsetimeout'] = {
},
/** @return {!string} The type of input value for the block, an integer. */
getBlockType: function () {
return Blockly.Types.NUMBER;
return Types.NUMBER.typeId;
}
};

View File

@ -1,61 +1,236 @@
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: 'controls_ifelse',
message0: '%{BKY_CONTROLS_IF_MSG_IF} %1',
args0: [
"type": "logic_compare",
"message0": "%1 %2 %3",
"args0": [
{
type: 'input_value',
name: 'IF0',
check: 'Boolean'
"type": "input_value",
"name": "A"
},
{
"type": "field_dropdown",
"name": "OP",
"options": [
["=", "EQ"],
["\u2260", "NEQ"],
["\u200F<", "LT"],
["\u200F\u2264", "LTE"],
["\u200F>", "GT"],
["\u200F\u2265", "GTE"]
]
},
{
"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": "logic_operation",
"message0": "%1 %2 %3",
"args0": [
{
type: 'input_statement',
name: 'DO0'
"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": "logic_negate",
"message0": "%{BKY_LOGIC_NEGATE_TITLE}",
"args0": [
{
type: 'input_statement',
name: 'ELSE'
"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}"
}
]);

View File

@ -0,0 +1,2 @@
import Blockly from 'blockly';

View 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;
}
};

View File

@ -0,0 +1,114 @@
import * as Blockly from 'blockly/core';
import { getColour } from '../helpers/colour';
import Block from 'blockly'
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) {
var block = this;
var blocks = block.getDescendants()
//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'],
};

View File

@ -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,12 +16,297 @@ 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');
},
getBlockType: function () {
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) {
var input = (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) {
var input = (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;
}
},
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;
},
};

View File

@ -1,8 +1,10 @@
import Blockly from 'blockly';
import { getColour } from '../helpers/colour'
Blockly.Blocks["sensebox_telegram"] = {
init: function () {
this.setColour(120);
this.setColour(getColour().sensebox);
this.appendDummyInput()
.appendField(Blockly.Msg.senseBox_telegram_init);
this.appendDummyInput()
@ -15,3 +17,37 @@ Blockly.Blocks["sensebox_telegram"] = {
};
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"]
};

View 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);
}
};

View File

@ -81,6 +81,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 +102,17 @@ 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 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 +193,42 @@ Blockly['Arduino'].init = function (workspace) {
*/
Blockly['Arduino'].finish = function (code) {
let libraryCode = '';
let variablesCode = ''
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'].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 +237,10 @@ Blockly['Arduino'].finish = function (code) {
'\n' +
libraryCode +
'\n' +
variablesCode +
'\n' +
definitionsCode +
'\n' +
Blockly['Arduino'].variablesInitCode_ +
'\n' +
functionsCode +
@ -225,6 +253,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();

View File

@ -1,7 +1,12 @@
import './generator';
import './loops';
import './sensebox';
import './sensebox-sensors';
import './sensebox-telegram';
import './sensebox-osem';
import './logic';
import './math';
import './io';
import './procedures';
import './time';

View File

@ -30,3 +30,86 @@ Blockly.Arduino['io_digitalread'] = function (block) {
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];
};

View File

@ -55,7 +55,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 = '',

View File

@ -0,0 +1,30 @@
import * as Blockly from 'blockly/core';
import { Block } from 'blockly';
/**
* 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 '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;
};

View File

@ -0,0 +1,178 @@
import Blockly, { Blocks } from 'blockly';
import { getColour } from '../helpers/colour'
import Block 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;
}
}
}`
var code = '';
code += branch;
code += 'submitValues(' + lat + ',' + lng + ',' + altitude + ',' + timestamp + ');\n';
}
return code;
};

View File

@ -1,6 +1,225 @@
import * as Blockly from 'blockly/core';
import { Block } from 'blockly';
import Blockly from 'blockly';
import { getColour } from '../helpers/colour';
import { selectedBoard } from '../helpers/board';
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');
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();'
var code = 'veml.get' + dropdown_name + '()';
}
if (dropdown_name === 'Illuminance') {
Blockly.Arduino.definitions_['define_tsl'] = 'TSL45315 tsl;'
Blockly.Arduino.setupCode_['sensebox_sensor_illuminance'] = 'tsl.begin();'
var 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 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') {
var code = 'bmp_sensor.get' + dropdown_name + '()';
}
else if (dropdown_name === 'Altitude') {
var 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');
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':
var code = 'bmeTemperatur';
break;
case 'humidity':
var code = 'bmeHumidity';
break;
case 'pressure':
var code = 'bmePressure'
break;
case 'IAQ':
var code = 'bmeIAQ';
break;
case 'IAQAccuracy':
var code = 'bmeIAQAccuracy';
break;
case 'CO2':
var code = 'bmeCO2';
break;
case 'breathVocEquivalent':
var code = 'bmeBreathVocEquivalent';
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];
};

View File

@ -0,0 +1,58 @@
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;
};
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;
};

View File

@ -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;
};

View 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;
};

View 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;
};

View 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;
// };

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import BlocklyComponent, { Block, Value, Field, Shadow, Category } from '../';
import { getColour } from '../helpers/colour'
class Toolbox extends React.Component {
@ -10,23 +11,36 @@ 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="120">
<Category name="Sensoren" colour="120" >
<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="Telegram">
<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>
<Category name="Logic" colour="#b063c5">
<Block type="control_if" />
<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="lops" name="Loops" colour="10">
<Category id="loops" name="Loops" colour={getColour().loops}>
<Block type="controls_repeat_ext">
<Value name="TIMES">
<Block type="math_number">
@ -54,7 +68,27 @@ class Toolbox extends React.Component {
</Block>
<Block type="controls_flow_statements" />
</Category>
<Category id="catMath" name="Math" colour="230">
<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>
@ -98,9 +132,31 @@ class Toolbox extends React.Component {
{/* <Block type="base_map"></Block> */}
</Category>
<sep></sep>
<Category name="Input/Output">
<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>
);

View File

@ -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 = {