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'
|
||||
|
@ -23,29 +23,29 @@ export const onChangeWorkspace = (event) => (dispatch, getState) => {
|
||||
payload: code
|
||||
});
|
||||
var stats = getState().workspace.stats;
|
||||
if (event.type === Blockly.Events.BLOCK_CREATE){
|
||||
if (event.type === Blockly.Events.BLOCK_CREATE) {
|
||||
stats.create += event.ids.length;
|
||||
dispatch({
|
||||
type: CREATE_BLOCK,
|
||||
payload: stats
|
||||
});
|
||||
}
|
||||
else if (event.type === Blockly.Events.BLOCK_MOVE){
|
||||
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){
|
||||
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){
|
||||
else if (event.type === Blockly.Events.BLOCK_DELETE) {
|
||||
if (stats.create > 0) {
|
||||
stats.delete += event.ids.length;
|
||||
dispatch({
|
||||
type: DELETE_BLOCK,
|
||||
|
@ -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,28 +53,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 >
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@ -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,13 +11,14 @@ 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 = {
|
||||
codeOn: false
|
||||
}
|
||||
|
||||
componentDidUpdate(){
|
||||
componentDidUpdate() {
|
||||
/* Resize and reposition all of the workspace chrome (toolbox, trash,
|
||||
scrollbars etc.) This should be called when something changes that requires
|
||||
recalculating dimensions and positions of the trash, zoom, toolbox, etc.
|
||||
@ -35,17 +36,17 @@ class Home extends Component {
|
||||
<div>
|
||||
<WorkspaceStats />
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={this.state.codeOn ? 6 : 12} style={{position: 'relative'}}>
|
||||
<Grid item xs={12} md={this.state.codeOn ? 6 : 12} style={{ position: 'relative' }}>
|
||||
<FormControlLabel
|
||||
style={{margin: '5px 10px 0 0', position: 'absolute', top: 0, right:0, zIndex:1}}
|
||||
control={<Switch checked={this.state.codeOn} onChange={this.onChange} color='primary'/>}
|
||||
style={{ margin: '5px 10px 0 0', position: 'absolute', top: 0, right: 0, zIndex: 1 }}
|
||||
control={<Switch checked={this.state.codeOn} onChange={this.onChange} color='primary' />}
|
||||
label="Code"
|
||||
/>
|
||||
<BlocklyWindow />
|
||||
</Grid>
|
||||
{this.state.codeOn ?
|
||||
<Grid item xs={12} md={6}>
|
||||
<CodeViewer/>
|
||||
<CodeViewer />
|
||||
</Grid>
|
||||
: null}
|
||||
</Grid>
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, {Component} from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
@ -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>
|
||||
);
|
||||
@ -87,4 +98,4 @@ const mapStateToProps = state => ({
|
||||
worskpaceChange: state.workspace.change
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null)(withStyles(styles, {withTheme: true})(WorkspaceStats));
|
||||
export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(WorkspaceStats));
|
||||
|
@ -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