mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-21 15:19:48 +00:00
3450 lines
116 KiB
JavaScript
3450 lines
116 KiB
JavaScript
/** Fix Basic Blocks ****************************************************************************************/
|
||
Blockly.Blocks['ugj_control_for'] = {
|
||
init: function () {
|
||
this.appendValueInput("index")
|
||
.setCheck("Variable");
|
||
this.appendValueInput("from")
|
||
.setCheck("Number")
|
||
.appendField("を");
|
||
this.appendValueInput("to")
|
||
.setCheck("Number")
|
||
.appendField("から");
|
||
this.appendValueInput("by")
|
||
.setCheck("Number")
|
||
.appendField("まで");
|
||
this.appendDummyInput()
|
||
.appendField("ずつ")
|
||
.appendField(new Blockly.FieldDropdown([["増やして", "+"], ["減らして", "-"]]), "crease");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('loop_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_control_for'] = function (block) {
|
||
var value_index = Blockly.JavaScript.valueToCode(block, 'index', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_index = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||
var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_to = Blockly.JavaScript.valueToCode(block, 'to', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_by = Blockly.JavaScript.valueToCode(block, 'by', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_crease = block.getFieldValue('crease');
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
let daishou;
|
||
if (dropdown_crease == '+') { daishou = '<'; }
|
||
else { daishou = '>'; }
|
||
var code = [
|
||
`for (${value_index} = ${value_from}; ${value_index} ${daishou}= ${value_to}; ${value_index} ${dropdown_crease}= ${Math.abs(value_by)}) {`,
|
||
statements_do,
|
||
`}`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_control_for'] = function (block) {
|
||
var variable_index = Blockly.Python.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||
var value_from = Blockly.Python.valueToCode(block, 'from', Blockly.Python.ORDER_ATOMIC);
|
||
var value_to = Blockly.Python.valueToCode(block, 'to', Blockly.Python.ORDER_ATOMIC);
|
||
var value_by = Blockly.Python.valueToCode(block, 'by', Blockly.Python.ORDER_ATOMIC);
|
||
var dropdown_crease = block.getFieldValue('crease');
|
||
var statements_do = Blockly.Python.statementToCode(block, 'do');
|
||
if (statements_do === '') statements_do = ' pass';
|
||
if (dropdown_crease == '+') { value_by = Math.abs(value_by); value_to++; }
|
||
else { value_by = Math.abs(value_by) * (-1); value_to--; }
|
||
var code = [
|
||
`for ${variable_index} in range(${value_from}, ${value_to}, ${value_by}) :`,
|
||
statements_do,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
Blockly.Blocks['ugj_controls_foreach'] = {
|
||
init: function () {
|
||
this.appendValueInput("list")
|
||
.setCheck("Array")
|
||
.appendField("リスト");
|
||
this.appendValueInput("item")
|
||
.setCheck("Variable")
|
||
.appendField("の各");
|
||
this.appendDummyInput()
|
||
.appendField("について");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("リストの各項目について、その項目の内容を変数「項目」に代入してステートメントを実行します。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('loop_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_controls_foreach'] = function (block) {
|
||
var value_list = Blockly.JavaScript.valueToCode(block, 'list', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_item = Blockly.JavaScript.valueToCode(block, 'item', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`for (let _index in ${value_list}) {`,
|
||
`${value_item} = ${value_list}[_index];`,
|
||
statements_do,
|
||
`}`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
// Custom Color Picker
|
||
Blockly.FieldColour.COLOURS = [
|
||
'#ffffff', '#808000', '#ffff00', '#ff00ff', '#ff4500',
|
||
'#c0c0c0', '#00ffff', '#00ff00', '#ff0000', '#ff1493',
|
||
'#808080', '#0000ff', '#008000', '#800080', '#8a2be2',
|
||
'#000000', '#000080', '#008080', '#800000', '#2e8b57'
|
||
];
|
||
Blockly.FieldColour.TITLES = [
|
||
'white', 'olive', 'yellow', 'magenta', 'orangered',
|
||
'silver', 'aqua', 'lime', 'red', 'deeppink',
|
||
'gray', 'blue', 'green', 'purple', 'blueviolet',
|
||
'black', 'navy', 'teal', 'maroon', 'seagreen'
|
||
];
|
||
Blockly.FieldColour.COLUMNS = 5;
|
||
|
||
/** Additional Basic Blocks********************************************************************************* */
|
||
var ugjCodecharDefinition = {
|
||
"type": "ugj_codechar",
|
||
"message0": "%{BKY_UGJ_CODECHAR_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "code",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": "String",
|
||
"tooltip": "%{BKY_UGJ_CODECHAR_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "text_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_codechar'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjCodecharDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_codechar'] = function (block) {
|
||
var value_code = Blockly.JavaScript.valueToCode(block, 'code', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `String.fromCharCode(${value_code})`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
Blockly.Python['ugj_codechar'] = function (block) {
|
||
var value_code = Blockly.Python.valueToCode(block, 'code', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `chr(${value_code})`;
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
|
||
var ugjCharcodeDefinition = {
|
||
"type": "ugj_charcode",
|
||
"message0": "%{BKY_UGJ_CHARCODE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "char",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_UGJ_CHARCODE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "text_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_charcode'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjCharcodeDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_charcode'] = function (block) {
|
||
var value_char = Blockly.JavaScript.valueToCode(block, 'char', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `${value_char}.charCodeAt(0)`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
Blockly.Python['ugj_charcode'] = function (block) {
|
||
var value_char = Blockly.Python.valueToCode(block, 'char', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `ord(${value_char})`;
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
|
||
|
||
var ugjHextodecDefinition = {
|
||
"type": "ugj_hextodec",
|
||
"message0": "%{BKY_UGJ_HEXTODEC_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "hex",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_UGJ_HEXTODEC_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "math_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_hextodec'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjHextodecDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_hextodec'] = function (block) {
|
||
var value_hex = Blockly.JavaScript.valueToCode(block, 'hex', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `parseInt (${value_hex}, 16)`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_hextodec'] = function (block) {
|
||
var value_hex = Blockly.Python.valueToCode(block, 'hex', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `int(${value_hex}, 16)`;
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
|
||
var ugjDectohexDefinition = {
|
||
"type": "ugj_dectohex",
|
||
"message0": "%{BKY_UGJ_DECTOHEX_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "dec",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": "String",
|
||
"tooltip": "%{BKY_UGJ_DECTOHEX_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "math_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_dectohex'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjDectohexDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_dectohex'] = function (block) {
|
||
var value_dec = Blockly.JavaScript.valueToCode(block, 'dec', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `'0x' + (${value_dec}).toString(16).toUpperCase()`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
Blockly.Python['ugj_dectohex'] = function (block) {
|
||
var value_dec = Blockly.Python.valueToCode(block, 'dec', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `'0x' + format(${value_dec}, 'X')`;
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
/** GPIO *****************************************************************************************************/
|
||
|
||
/************ */
|
||
/** GPIO Open */
|
||
/************ */
|
||
var ugjGpioOpenDefinition = {
|
||
"type": "ugj_gpio_open",
|
||
"message0": "%{BKY_GPIO_OPEN_TITLE}",
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_GPIO_OPEN_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_open'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioOpenDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_open'] = function (block) {
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||
);
|
||
var code = `await _pi.gpio_open();\n`; //
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gpio_open'] = function (block) {
|
||
Blockly.Python.provideFunction_(
|
||
'import_lgpio', ['import lgpio as pi']
|
||
);
|
||
var code = `gpioHand = pi.gpiochip_open(0)\n`; //
|
||
return code;
|
||
};
|
||
|
||
/************* */
|
||
/** GPIO Close */
|
||
/************* */
|
||
var ugjGpioCloseDefinition = {
|
||
"type": "ugj_gpio_close",
|
||
"message0": "%{BKY_GPIO_CLOSE_TITLE}",
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_GPIO_CLOSE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_close'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioCloseDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_close'] = function (block) {
|
||
var code = 'await _pi.gpio_close();\n';
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gpio_close'] = function (block) {
|
||
var code = 'pi.gpiochip_close(gpioHand)\n';
|
||
return code;
|
||
};
|
||
|
||
/*********************** */
|
||
/** GPIO Set Output ** */
|
||
/*********************** */
|
||
var ugjGpioSetOutputDefinition = {
|
||
"type": "ugj_gpio_set_output",
|
||
"message0": "%{BKY_GPIO_SET_OUTPUT_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_GPIO_SET_OUTPUT_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_set_output'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioSetOutputDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_set_output'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.gpio_set_output(${value_gpio});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gpio_set_output'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.gpio_set_output(${value_gpio})\n`;
|
||
return code;
|
||
};
|
||
|
||
/********************** */
|
||
/** GPIO Set Input ** */
|
||
/********************** */
|
||
var ugjGpioSetInputDefinition = {
|
||
"type": "ugj_gpio_set_input",
|
||
"message0": "%{BKY_GPIO_SET_INPUT_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "field_dropdown",
|
||
"name": "lflag",
|
||
"options": [
|
||
[
|
||
"%{BKY_GPIO_SET_INPUT_PULLUP}",
|
||
"_pi.PULL_UP"
|
||
],
|
||
[
|
||
"%{BKY_GPIO_SET_INPUT_PULLDOWN}",
|
||
"_pi.PULL_DOWN"
|
||
],
|
||
[
|
||
"%{BKY_GPIO_SET_INPUT_PULLNONE}",
|
||
"_pi.PULL_NONE"
|
||
]
|
||
]
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_GPIO_SET_INPUT_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_set_input'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioSetInputDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_set_input'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_lflag = block.getFieldValue('lflag');
|
||
var code = `await _pi.gpio_set_input(${value_gpio}, ${dropdown_lflag});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gpio_set_input'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var dropdown_lflag = block.getFieldValue('lflag');
|
||
var code = `await pi.gpio_set_input(gpioHand, ${value_gpio}, ${dropdown_lflag})\n`;
|
||
return code;
|
||
};
|
||
|
||
/********************* */
|
||
/** Read GPIO Value ** */
|
||
/***********************/
|
||
var ugjGpioReadDefinition = {
|
||
"type": "ugj_gpio_read",
|
||
"message0": "%{BKY_GPIO_READ_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_GPIO_READ_TOOLTIP",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_read'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioReadDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_read'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.gpio_read(${value_gpio})`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
Blockly.Python['ugj_gpio_read'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.gpio_read(gpioHand, ${value_gpio})`;
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
|
||
/*******************************************/
|
||
/** GPIO Write Value - Common GPIO on/off **/
|
||
/*******************************************/
|
||
var ugjGpioWriteDefinition = {
|
||
"type": "ugj_gpio_write",
|
||
"message0": "%{BKY_GPIO_WRITE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "field_dropdown",
|
||
"name": "level",
|
||
"options": [
|
||
[
|
||
"0",
|
||
"0"
|
||
],
|
||
[
|
||
"1",
|
||
"1"
|
||
]
|
||
]
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_GPIO_WRITE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gpio_write'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGpioWriteDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gpio_write'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_level = block.getFieldValue('level');
|
||
var code = `await _pi.gpio_write(${value_gpio}, ${dropdown_level});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gpio_write'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var dropdown_level = block.getFieldValue('level');
|
||
var code = `await pi.gpio_write(gpioHand, ${value_gpio}, ${dropdown_level})\n`;
|
||
return code;
|
||
};
|
||
|
||
/*****************/
|
||
/** Servo motor **/
|
||
/*****************/
|
||
var ugjServoDefinition = {
|
||
"type": "ugj_servo",
|
||
"message0": "%{BKY_SERVO_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "pulsewidth",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_SERVO_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_servo'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjServoDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_servo'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_pulsewidth = Blockly.JavaScript.valueToCode(block, 'pulsewidth', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.servo(${value_gpio}, ${value_pulsewidth});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_servo'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var value_pulsewidth = Blockly.Python.valueToCode(block, 'pulsewidth', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.servo(gpioHand, ${value_gpio}, ${value_pulsewidth})\n`;
|
||
return code;
|
||
};
|
||
|
||
/************************************************* */
|
||
/** starts software timed PWM on an output GPIO ** */
|
||
/************************************************* */
|
||
var ugjPwmDefinition = {
|
||
"type": "ugj_pwm",
|
||
"message0": "%{BKY_PWM_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "gpio",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "pwm_frequency",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "pwm_duty_cycle",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_PWM_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_pwm'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjPwmDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_pwm'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_pwm'] = function (block) {
|
||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||
var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
|
||
var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
|
||
return code;
|
||
};
|
||
/********************** */
|
||
/** Open Serial Port ** */
|
||
/********************** */
|
||
var ugjSerialOpenDefinition = {
|
||
"type": "ugj_serial_open",
|
||
"message0": "%{BKY_SERIAL_OPEN_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "field_dropdown",
|
||
"name": "baud",
|
||
"options": [
|
||
[
|
||
"9600",
|
||
"9600"
|
||
],
|
||
[
|
||
"19200",
|
||
"19200"
|
||
],
|
||
[
|
||
"115200",
|
||
"115200"
|
||
]
|
||
]
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_SERIAL_OPEN_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_serial_open'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjSerialOpenDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_serial_open'] = function (block) {
|
||
// var value_tty = Blockly.JavaScript.valueToCode(block, 'tty', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_baud = block.getFieldValue('baud');
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||
);
|
||
var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_serial_open'] = function (block) {
|
||
var value_tty = Blockly.Python.valueToCode(block, 'tty', Blockly.Python.ORDER_ATOMIC);
|
||
var dropdown_baud = block.getFieldValue('baud');
|
||
Blockly.Python.provideFunction_(
|
||
'import_lgpio', ['import lgpio as pi']
|
||
);
|
||
var code = `ser_hand = pi.serial_open(${value_tty}, ${dropdown_baud}, 0)\n`;
|
||
return code;
|
||
};
|
||
/*********************** */
|
||
/** Close Serial Port ** */
|
||
/*********************** */
|
||
var ugjSerialCloseDefinition = {
|
||
"type": "ugj_serial_close",
|
||
"message0": "%{BKY_SERIAL_CLOSE_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_SERIAL_CLOSE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_serial_close'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjSerialCloseDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_serial_close'] = function (block) {
|
||
var code = 'await _pi.serial_close();\n';
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_serial_close'] = function (block) {
|
||
var code = 'pi.serial_close(ser_hand)\n';
|
||
return code;
|
||
};
|
||
|
||
/************************** */
|
||
/** Write Data to Serial ** */
|
||
/************************** */
|
||
var ugjSerialWriteDefinition = {
|
||
"type": "ugj_serial_write",
|
||
"message0": "%{BKY_SERIAL_WRITE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "data",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_SERIAL_WRITE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_serial_write'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjSerialWriteDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_serial_write'] = function (block) {
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.serial_write(${value_data});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_serial_write'] = function (block) {
|
||
var value_data = Blockly.Python.valueToCode(block, 'data', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.serial_write(ser_hand, ${value_data}.encode())\n`;
|
||
return code;
|
||
};
|
||
|
||
/************************ */
|
||
/** Read Data from Serial */
|
||
/************************ */
|
||
var ugjSerialReadDefinition = {
|
||
"type": "ugj_serial_read",
|
||
"message0": "%{BKY_SERIAL_READ_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "count",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": null,
|
||
"tooltip": "%{BKY_SERIAL_READ_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_serial_read'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjSerialReadDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_serial_read'] = function (block) {
|
||
var value_count = Blockly.JavaScript.valueToCode(block, 'count', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.serial_read(${value_count})`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_serial_read'] = function (block) {
|
||
var value_count = Blockly.Python.valueToCode(block, 'count', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.serial_read(ser_hand, ${value_count}).decode()`;
|
||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||
};
|
||
|
||
/********************* */
|
||
/** Open I2C Device ** */
|
||
/********************* */
|
||
var ugjI2cOpenDefinition = {
|
||
"type": "ugj_i2c_open",
|
||
"message0": "%{BKY_I2C_OPEN_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "i2c_address",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_I2C_OPEN_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_open'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cOpenDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_open'] = function (block) {
|
||
var value_i2c_address = Blockly.JavaScript.valueToCode(block, 'i2c_address', Blockly.JavaScript.ORDER_ATOMIC);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||
);
|
||
var code = `await _pi.i2c_open(${elutil.i2c_bus}, ${value_i2c_address});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_i2c_open'] = function (block) {
|
||
var value_i2c_address = Blockly.Python.valueToCode(block, 'i2c_address', Blockly.Python.ORDER_ATOMIC);
|
||
Blockly.Python.provideFunction_(
|
||
'import_lgpio', ['import lgpio as pi']
|
||
);
|
||
var code = `i2c_hand = pi.i2c_open(1, ${value_i2c_address})\n`;
|
||
return code;
|
||
};
|
||
/********************** */
|
||
/** Close I2C Device ** */
|
||
/********************** */
|
||
var ugjI2cCloseDefinition = {
|
||
"type": "ugj_i2c_close",
|
||
"message0": "%{BKY_I2C_CLOSE_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_I2C_CLOSE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_close'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cCloseDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_close'] = function (block) {
|
||
var code = `await _pi.i2c_close();\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_i2c_close'] = function (block) {
|
||
var code = `await pi.i2c_close(i2c_hand)\n`;
|
||
return code;
|
||
};
|
||
|
||
/****************************************************************** */
|
||
/** Writes a single byte to the specified register of the device ** */
|
||
/****************************************************************** */
|
||
var ugjI2cWriteByteDataDefinition = {
|
||
"type": "ugj_i2c_write_byte_data",
|
||
"message0": "%{BKY_I2C_WRITE_BYTE_DATA_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "reg",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "byte_val",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_I2C_WRITE_BYTE_DATA_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_write_byte_data'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cWriteByteDataDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_write_byte_data'] = function (block) {
|
||
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_byte_val = Blockly.JavaScript.valueToCode(block, 'byte_val', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_write_byte_data(${value_reg}, ${value_byte_val});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_i2c_write_byte_data'] = function (block) {
|
||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||
var value_byte_val = Blockly.Python.valueToCode(block, 'byte_val', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.i2c_write_byte_data(i2c_hand, ${value_reg}, ${value_byte_val})\n`;
|
||
return code;
|
||
};
|
||
|
||
/****************************************************************** */
|
||
/** Read a single byte from the specified resister of the device ** */
|
||
/****************************************************************** */
|
||
var ugjI2cReadByteDataDefinition = {
|
||
"type": "ugj_i2c_read_byte_data",
|
||
"message0": "%{BKY_I2C_READ_BYTE_DATA_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "reg",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": null,
|
||
"tooltip": "%{BKY_I2C_READ_BYTE_DATA_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_read_byte_data'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cReadByteDataDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_read_byte_data'] = function (block) {
|
||
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_read_byte_data(${value_reg})`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_i2c_read_byte_data'] = function (block) {
|
||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.i2c_read_byte_data(i2c_hand, ${value_reg})\n`;
|
||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||
};
|
||
|
||
Blockly.Blocks['ugj_i2c_read_word_data'] = {
|
||
init: function () {
|
||
this.appendValueInput("reg")
|
||
.setCheck("Number")
|
||
.appendField("レジスタ");
|
||
this.appendDummyInput()
|
||
.appendField("のワード値");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "Number");
|
||
this.setStyle('gpio_blocks');
|
||
this.setTooltip("デバイスの指定レジスタからワードデータを読み出します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_read_word_data'] = function (block) {
|
||
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_read_word_data(${value_reg})`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
|
||
var ugjI2cWriteI2cBlockDataDefinition = {
|
||
"type": "ugj_i2c_write_i2c_block_data",
|
||
"message0": "%{BKY_I2C_WRITE_I2C_BLOCK_DATA_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "reg",
|
||
"check": "Number"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "data",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_I2C_WRITE_I2C_BLOCK_DATA_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_write_i2c_block_data'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cWriteI2cBlockDataDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_write_i2c_block_data'] = function (block) {
|
||
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_write_i2c_block_data (${value_reg}, ${value_data});`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_i2c_write_i2c_block_data'] = function (block) {
|
||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||
var value_name = Blockly.Python.valueToCode(block, 'NAME', Blockly.Python.ORDER_ATOMIC);
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...\n';
|
||
return code;
|
||
};
|
||
|
||
/************************************************************************** */
|
||
/** Returns count bytes read from the raw device associated with handle. ** */
|
||
/************************************************************************** */
|
||
var ugjI2cReadDeviceDefinition = {
|
||
"type": "ugj_i2c_read_device",
|
||
"message0": "%{BKY_I2C_READ_DEVICE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "count",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"output": null,
|
||
"tooltip": "%{BKY_I2C_READ_DEVICE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_read_device'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cReadDeviceDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_read_device'] = function (block) {
|
||
var value_count = Blockly.JavaScript.valueToCode(block, 'count', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_read_device(${value_count})`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_i2c_read_device'] = function (block) {
|
||
var value_count = Blockly.Python.valueToCode(block, 'count', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.i2c_read_device(i2c_hand, ${value_count}).decode()`;
|
||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||
};
|
||
/********************************************** */
|
||
/** Writes the data bytes to the raw device. ** */
|
||
/********************************************** */
|
||
var ugjI2cWriteDeviceDefinition = {
|
||
"type": "ugj_i2c_write_device",
|
||
"message0": "%{BKY_I2C_WRITE_DEVICE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "data",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_I2C_WRITE_DEVICE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "gpio_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_i2c_write_device'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjI2cWriteDeviceDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_i2c_write_device'] = function (block) {
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `await _pi.i2c_write_device(${value_data})\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_i2c_write_device'] = function (block) {
|
||
var value_data = Blockly.Python.valueToCode(block, 'data', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `await pi.i2c_write_device(i2c_hand, ${value_data}.encode())\n`;
|
||
return code;
|
||
};
|
||
|
||
/** センサー */
|
||
/********* */
|
||
/** BME280 */
|
||
/********* */
|
||
Blockly.Blocks['ugj_bme280'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("BME280(アドレス")
|
||
.appendField(new Blockly.FieldDropdown([["0x76", "0x76"], ["0x77", "0x77"]]), "addr")
|
||
.appendField(")の計測値を取得");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('sensor_blocks');
|
||
this.setTooltip("環境センサーBME280で、気温(摂氏)、湿度(%)、気圧(hPa)を計測します。計測結果は計測値ブロックで参照します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_bme280'] = function (block) {
|
||
var dropdown_addr = block.getFieldValue('addr');
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_bme280', [`const _bme280 = require('@ocogeclub/bme280');`]
|
||
);
|
||
var code = `const options = {
|
||
i2cBusNo: ${elutil.i2c_bus},
|
||
i2cAddress: ${dropdown_addr}
|
||
};
|
||
await _bme280.init(options);
|
||
let _thp = await _bme280.readSensorData();
|
||
let _bmedata = [];
|
||
_bmedata[0] = Math.round(_thp.temperature_C * 10) / 10;
|
||
_bmedata[1] = Math.round(_thp.humidity * 10) / 10;
|
||
_bmedata[2] = Math.round(_thp.pressure_hPa);
|
||
await _bme280.cancel();
|
||
`;
|
||
return code;
|
||
};
|
||
Blockly.Blocks['ugj_bme280_data'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField(new Blockly.FieldDropdown([["気温", "0"], ["湿度", "1"], ["気圧", "2"]]), "thp");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, null);
|
||
this.setStyle('sensor_blocks');
|
||
this.setTooltip("BME280 の計測値を返します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_bme280_data'] = function (block) {
|
||
var dropdown_thp = block.getFieldValue('thp');
|
||
var code = `_bmedata[${dropdown_thp}]`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
|
||
/********** */
|
||
/** PAJ7620 */
|
||
/********** */
|
||
var ugjGestureInitDefinition = {
|
||
"type": "ugj_gesture_init",
|
||
"message0": "%{BKY_UGJ_GESTURE_INIT_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "i2c_addr",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GESTURE_INIT_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gesture_init'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGestureInitDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gesture_init'] = function (block) {
|
||
var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_paj7620', [`const _paj7620 = require('@ocogeclub/paj7620');`]
|
||
);
|
||
var code = `await _paj7620.init(${elutil.i2c_bus}, ${value_i2c_addr});
|
||
`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gesture_init'] = function (block) {
|
||
var value_i2c_addr = Blockly.Python.valueToCode(block, 'i2c_addr', Blockly.Python.ORDER_ATOMIC);
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...\n';
|
||
return code;
|
||
};
|
||
|
||
/****************** */
|
||
/** Gesture Read ** */
|
||
/****************** */
|
||
var ugjGestureReadDefinition = {
|
||
"type": "ugj_gesture_read",
|
||
"message0": "%{BKY_UGJ_GESTURE_READ_TITLE}",
|
||
"inputsInline": true,
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_UGJ_GESTURE_READ_TOOLTIP}",
|
||
"helpUrl": "https://ocoge.club/sensors/paj7620.html",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gesture_read'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGestureReadDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gesture_read'] = function (block) {
|
||
var code = 'await _paj7620.return_gesture()';
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_gesture_read'] = function (block) {
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...';
|
||
// TODO: Change ORDER_NONE to the correct strength.
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
/****************** */
|
||
/** Gesture Stop ** */
|
||
/****************** */
|
||
var ugjGestureStopDefinition = {
|
||
"type": "ugj_gesture_stop",
|
||
"message0": "%{BKY_UGJ_GESTURE_STOP_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GESTURE_STOP_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_gesture_stop'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGestureStopDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_gesture_stop'] = function (block) {
|
||
var code = 'await _paj7620.stop();\n';
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_gesture_stop'] = function (block) {
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...\n';
|
||
return code;
|
||
};
|
||
|
||
/******************* */
|
||
/** Init Grid-Eye ** */
|
||
/******************* */
|
||
var ugjGridEyeInitDefinition = {
|
||
"type": "ugj_grideye_init",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_INIT_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "field_dropdown",
|
||
"name": "addr",
|
||
"options": [
|
||
[
|
||
"0x68",
|
||
"0x68"
|
||
],
|
||
[
|
||
"0x69",
|
||
"0x69"
|
||
]
|
||
]
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_INIT_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_init'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeInitDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_init'] = function (block) {
|
||
var dropdown_addr = block.getFieldValue('addr');
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_amg8833', [`const _amg8833 = require('@ocogeclub/amg8833');`]
|
||
);
|
||
var code = `await _amg8833.init(${elutil.i2c_bus}, ${dropdown_addr});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_grideye_init'] = function (block) {
|
||
var dropdown_addr = block.getFieldValue('addr');
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...\n';
|
||
return code;
|
||
};
|
||
/********************** */
|
||
/** Grid-Eye 本体温度 ** */
|
||
/********************** */
|
||
var ugjGridEyeThermistorDefinition = {
|
||
"type": "ugj_grideye_thermistor",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_THERMISTOR_TITLE}",
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_THERMISTOR_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_thermistor'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeThermistorDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_thermistor'] = function (block) {
|
||
var code = `await _amg8833.read_thermistor()`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
Blockly.Python['ugj_grideye_thermistor'] = function (block) {
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...';
|
||
// TODO: Change ORDER_NONE to the correct strength.
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
|
||
/**************************** */
|
||
/** Read Temperature Array ** */
|
||
/**************************** */
|
||
var ugjGridEyeReadDefinition = {
|
||
"type": "ugj_grideye_read",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_READ_TITLE}",
|
||
"inputsInline": true,
|
||
"output": "Array",
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_READ_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_read'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeReadDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_read'] = function (block) {
|
||
var code = 'await _amg8833.read_temp_array()';
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_grideye_read'] = function (block) {
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...';
|
||
// TODO: Change ORDER_NONE to the correct strength.
|
||
return [code, Blockly.Python.ORDER_NONE];
|
||
};
|
||
/******************* */
|
||
/** Stop Grid-Eye ** */
|
||
/******************* */
|
||
var ugjGridEyeStopDefinition = {
|
||
"type": "ugj_grideye_stop",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_STOP_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_STOP_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "sensor_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_stop'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeStopDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_stop'] = function (block) {
|
||
var code = 'await _amg8833.stop();\n';
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_grideye_stop'] = function (block) {
|
||
// TODO: Assemble Python into code variable.
|
||
var code = '...\n';
|
||
return code;
|
||
};
|
||
|
||
/** Multimedia *****************************************************************************************************/
|
||
|
||
|
||
/******************** */
|
||
/** Face Detection ** */
|
||
/******************** */
|
||
var with_landmark;
|
||
Blockly.Blocks['ugj_faceapi'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("TensorFlowによる顔検出を1秒に")
|
||
.appendField(new Blockly.FieldDropdown([["1", "1000"], ["2", "500"], ["5", "200"], ["10", "100"]]), "interval_sec")
|
||
.appendField("回実行:")
|
||
.appendField(new Blockly.FieldCheckbox("TRUE"), "with_landmark")
|
||
.appendField("ランドマークを検出");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setTooltip("TensorFlow とFaceAPI をロードし、顔検出をできるようにします。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('multimedia_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_faceapi'] = function (block) {
|
||
var dropdown_interval_sec = block.getFieldValue('interval_sec');
|
||
with_landmark = block.getFieldValue('with_landmark') == 'TRUE';
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`require('@tensorflow/tfjs-node');`,
|
||
`const _faceapi = require('@vladmandic/face-api/dist/face-api.node.js');`,
|
||
`const _interval_sec = ${dropdown_interval_sec};`,
|
||
statements_do,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Blocks['ugj_face_init'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("顔検出のビデオを開始");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks');
|
||
this.setTooltip("顔検出のためのビデオストリームを開始します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_face_init'] = function (block) {
|
||
var code = [
|
||
"const _videoEl = document.getElementById('subdisplay');",
|
||
`const _displaySize = { width: _videoEl.width, height: _videoEl.height };`,
|
||
"const _stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: _displaySize });",
|
||
"_videoEl.srcObject = _stream;",
|
||
""
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Blocks['ugj_face_display'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("ビデオを表示");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("カメラの映像を画像エリアに表示します。必須ではないブロックです。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_face_display'] = function (block) {
|
||
var code = [
|
||
"_videoEl.style.display = 'inline-block';",
|
||
`const _overlay = document.createElement('canvas');`,
|
||
`_overlay.setAttribute('width', _videoEl.width);`,
|
||
`_overlay.setAttribute('height', _videoEl.height);`,
|
||
`_overlay.className = 'subdisplay';`,
|
||
`document.getElementById('display_area').appendChild(_overlay);`,
|
||
""
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Blocks['ugj_face_detect'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("顔を検出したら");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setTooltip("顔を発見したら動作します。位置データは「顔の座標」ブロックで参照します。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('multimedia_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_face_detect'] = function (block) {
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code_model = `await _faceapi.nets.tinyFaceDetector.load('${elutil.path.join(elutil.library_path, 'models/')}');`;
|
||
if (with_landmark) { code_model += `\nawait _faceapi.nets.faceLandmark68TinyNet.load('${elutil.path.join(elutil.library_path, 'models/')}');`; }
|
||
var code_detect_face = " let _result = await _faceapi.detectSingleFace(_videoEl, _options)"
|
||
if (with_landmark) { code_detect_face += `.withFaceLandmarks(true);` }
|
||
else { code_detect_face += `;` }
|
||
var code_rect;
|
||
if (with_landmark) {
|
||
code_rect = [
|
||
` _coord[0] = Math.round(_result.detection.box.x);`,
|
||
` _coord[1] = Math.round(_result.detection.box.y);`,
|
||
` _coord[2] = Math.round(_result.detection.box.width);`,
|
||
` _coord[3] = Math.round(_result.detection.box.height);`,
|
||
].join('\n');
|
||
} else {
|
||
code_rect = [
|
||
` _coord[0] = Math.round(_result.box.x);`,
|
||
` _coord[1] = Math.round(_result.box.y);`,
|
||
` _coord[2] = Math.round(_result.box.width);`,
|
||
` _coord[3] = Math.round(_result.box.height);`,
|
||
].join('\n');
|
||
}
|
||
var code = [
|
||
code_model,
|
||
"const _options = new _faceapi.TinyFaceDetectorOptions({ inputSize: 128, scoreThreshold : 0.3 });",
|
||
// `const _onPlay = async () => {`,
|
||
` const _detectInterval = setInterval(async () => {`,
|
||
code_detect_face,
|
||
" if (_result) {",
|
||
` let _coord = [];`,
|
||
code_rect,
|
||
statements_do,
|
||
" }",
|
||
` }, _interval_sec);`,
|
||
// " setTimeout(() => onPlay())",
|
||
// "}",
|
||
// "_videoEl.onplay = _onPlay;",
|
||
""
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Blocks['ugj_face_coord'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("顔の座標")
|
||
.appendField(new Blockly.FieldDropdown([["左", "0"], ["上", "1"], ["幅", "2"], ["高さ", "3"]]), "face_coord");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, null);
|
||
this.setTooltip("顔の座標(位置)を参照します。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('multimedia_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_face_coord'] = function (block) {
|
||
var dropdown_face_coord = block.getFieldValue('face_coord');
|
||
var code = `_coord[${dropdown_face_coord}]`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
//
|
||
Blockly.Blocks['ugj_face_drawrect'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("検出結果を描画");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks');
|
||
this.setTooltip("ビデオに検出結果を四角や点で表示します。「ビデオを表示」ブロックが必要です。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_face_drawrect'] = function (block) {
|
||
var code_draw = ` _faceapi.draw.drawDetections(_overlay, _resizedDetections);`;
|
||
if (with_landmark) { code_draw += `\n _faceapi.draw.drawFaceLandmarks(_overlay, _resizedDetections);`; }
|
||
var code = [
|
||
` _faceapi.matchDimensions(_overlay, _displaySize);`,
|
||
` const _resizedDetections = _faceapi.resizeResults(_result, _displaySize);`,
|
||
code_draw,
|
||
""
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
|
||
/**************************** */
|
||
/** Say while some seconds ** */
|
||
/**************************** */
|
||
Blockly.Blocks['ugj_canvas_say'] = {
|
||
init: function () {
|
||
this.appendValueInput("say")
|
||
.setCheck(null);
|
||
this.appendValueInput("sec")
|
||
.setCheck("Number")
|
||
.appendField("と");
|
||
this.appendDummyInput()
|
||
.appendField("秒言う");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("キャンバスにフキダシを作ります。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_say'] = function (block) {
|
||
var value_say = Blockly.JavaScript.valueToCode(block, 'say', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = [
|
||
`ugj_fukidashi(String(${value_say}), ${value_sec});`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_canvas_say'] = function (block) {
|
||
var value_say = Blockly.Python.valueToCode(block, 'say', Blockly.Python.ORDER_ATOMIC);
|
||
var value_sec = Blockly.Python.valueToCode(block, 'sec', Blockly.Python.ORDER_ATOMIC);
|
||
var code = `print(${value_say})\n`;
|
||
return code;
|
||
};
|
||
|
||
/*************************** */
|
||
/** Canvas Initialization ** */
|
||
/*************************** */
|
||
var ugj_canvas_init_definition = {
|
||
"type": "ugj_canvas_init",
|
||
"message0": "%{BKY_UGJ_CANVAS_INIT_TITLE}",
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_CANVAS_INIT_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
}
|
||
Blockly.Blocks['ugj_canvas_init'] = {
|
||
init: function () {
|
||
this.jsonInit(ugj_canvas_init_definition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_init'] = function (block) {
|
||
var code = [
|
||
`let _canvas = document.getElementById('gcanvas');`,
|
||
`_canvas.style.display = 'inline-block';`,
|
||
"let _ctx = _canvas.getContext('2d');",
|
||
''
|
||
].join('\n');
|
||
|
||
return code;
|
||
};
|
||
|
||
/************************* */
|
||
/** Canvas Finalization ** */
|
||
/************************* */
|
||
Blockly.Blocks['ugj_canvas_finalize'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("キャンバスを片付ける");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("使ったキャンバスを片付けます。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_finalize'] = function (block) {
|
||
var code = `document.getElementById('gcanvas').style.display = 'none';\n`;
|
||
return code;
|
||
};
|
||
|
||
/**************************** */
|
||
/** Load Image File to Canvas */
|
||
/**************************** */
|
||
Blockly.Blocks['ugj_canvas_loadimg'] = {
|
||
init: function () {
|
||
this.appendValueInput("imgfilename")
|
||
.setCheck("String")
|
||
.appendField("ファイル名");
|
||
this.appendDummyInput()
|
||
.appendField("の画像をキャンバスに描画");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("画像ファイルの内容をキャンバス上にロードします。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_loadimg'] = function (block) {
|
||
var value_imgfilename = Blockly.JavaScript.valueToCode(block, 'imgfilename', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = [
|
||
`let _img = new Image();`,
|
||
`_img.src = '${elutil.doc_root}' + ${value_imgfilename};`,
|
||
`_img.onload = () => _ctx.drawImage(img,0,0);`,
|
||
// `ugj_canvasImg('${ugj_const.doc_root}' + ${value_imgfilename});`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
|
||
/**************** */
|
||
/** Clear Rect ** */
|
||
/**************** */
|
||
Blockly.Blocks['ugj_canvas_clearrect'] = {
|
||
init: function () {
|
||
this.appendValueInput("x")
|
||
.setCheck("Number")
|
||
.appendField("長方形に消去:X");
|
||
this.appendValueInput("y")
|
||
.setCheck("Number")
|
||
.appendField("Y");
|
||
this.appendValueInput("w")
|
||
.setCheck("Number")
|
||
.appendField("幅");
|
||
this.appendValueInput("h")
|
||
.setCheck("Number")
|
||
.appendField("高さ");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("長方形に図形を消去します。左上の頂点の座標と、幅・高さを指定します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_clearrect'] = function (block) {
|
||
var value_x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_w = Blockly.JavaScript.valueToCode(block, 'w', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_h = Blockly.JavaScript.valueToCode(block, 'h', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `_ctx.clearRect(${value_x},${value_y}, ${value_w}, ${value_h});\n`;
|
||
return code;
|
||
};
|
||
|
||
|
||
/********************** */
|
||
/** Get Canvas Width ** */
|
||
/********************** */
|
||
Blockly.Blocks['ugj_canvas_width'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("キャンバスの幅");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, null);
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("キャンバスの幅を取得します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_width'] = function (block) {
|
||
var code = '_canvas.width';
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
/*********************** */
|
||
/** Get Canvas Height ** */
|
||
/*********************** */
|
||
Blockly.Blocks['ugj_canvas_height'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("キャンバスの高さ");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "Number");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("キャンバスの高さを取得します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_height'] = function (block) {
|
||
var code = '_canvas.height';
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
|
||
|
||
/*************************** */
|
||
/** Draw Circle on Canvas ** */
|
||
/*************************** */
|
||
Blockly.Blocks['ugj_canvas_drawcircle'] = {
|
||
init: function () {
|
||
this.appendValueInput("x")
|
||
.setCheck("Number")
|
||
.appendField("中心の座標 X");
|
||
this.appendValueInput("y")
|
||
.setCheck("Number")
|
||
.appendField(", Y");
|
||
this.appendValueInput("r")
|
||
.setCheck("Number")
|
||
.appendField(", 半径");
|
||
this.appendValueInput("color")
|
||
.setCheck("Colour")
|
||
.appendField(", 塗りつぶしの色");
|
||
this.appendDummyInput()
|
||
.appendField("の円を描画");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("円を描画します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_drawcircle'] = function (block) {
|
||
var value_x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_r = Blockly.JavaScript.valueToCode(block, 'r', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = [
|
||
'_ctx.beginPath();',
|
||
`_ctx.arc(${value_x}, ${value_y}, ${value_r}, 0, Math.PI*2);`,
|
||
`_ctx.fillStyle = ${value_color};`,
|
||
'_ctx.fill();',
|
||
'_ctx.closePath();',
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/************************* */
|
||
/** Draw Rect on Canvas ** */
|
||
/************************* */
|
||
Blockly.Blocks['ugj_canvas_drawrect'] = {
|
||
init: function () {
|
||
this.appendValueInput("x")
|
||
.setCheck("Number")
|
||
.appendField("左上の座標 (X:");
|
||
this.appendValueInput("y")
|
||
.setCheck("Number")
|
||
.appendField(", Y:");
|
||
this.appendValueInput("w")
|
||
.setCheck("Number")
|
||
.appendField("), 幅:");
|
||
this.appendValueInput("h")
|
||
.setCheck("Number")
|
||
.appendField(", 高さ:");
|
||
this.appendValueInput("color")
|
||
.setCheck("Colour")
|
||
.appendField(", 塗りつぶしの色:");
|
||
this.appendDummyInput()
|
||
.appendField("の四角形を描画");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("キャンバス上に長方形を描画します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_canvas_drawrect'] = function (block) {
|
||
var value_x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_w = Blockly.JavaScript.valueToCode(block, 'w', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_h = Blockly.JavaScript.valueToCode(block, 'h', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = [
|
||
`_ctx.beginPath();`,
|
||
`_ctx.rect(${value_x}, ${value_y}, ${value_w}, ${value_h});`,
|
||
`_ctx.fillStyle = ${value_color};`,
|
||
`_ctx.fill();`,
|
||
`_ctx.closePath();`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/***************************** */
|
||
/** GridEye 表示キャンバス作成 ** */
|
||
/***************************** */
|
||
var ugjGridEyeCanvasCreateDefinition = {
|
||
"type": "ugj_grideye_canvas_create",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_canvas_create'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeCanvasCreateDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_canvas_create'] = function (block) {
|
||
var code = `let _grideye_canvas = document.createElement('canvas');
|
||
_grideye_canvas.setAttribute('width', 8);
|
||
_grideye_canvas.setAttribute('height', 8);
|
||
_grideye_canvas.className = 'subdisplay';
|
||
_grideye_canvas.style.width = '160px';
|
||
_grideye_canvas.style.height = '160px';
|
||
_grideye_canvas.id = 'subcanvas';
|
||
document.getElementById('display_area').appendChild(_grideye_canvas);
|
||
_grideye_ctx = _grideye_canvas.getContext('2d');
|
||
_grideye_imgData = _grideye_ctx.createImageData(8, 8);
|
||
`;
|
||
return code;
|
||
};
|
||
/********************************************** */
|
||
/** Draw IR Array Data to Image Data ** */
|
||
/********************************************** */
|
||
var ugjDrawGrideyedataDefinition = {
|
||
"type": "ugj_draw_grideyedata",
|
||
"message0": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_dummy"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "amg8833data",
|
||
"check": "Array",
|
||
"align": "RIGHT"
|
||
},
|
||
{
|
||
"type": "field_colour",
|
||
"name": "color_high",
|
||
"colour": "#ff0000"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "temp_high",
|
||
"check": "Number",
|
||
"align": "RIGHT"
|
||
},
|
||
{
|
||
"type": "field_colour",
|
||
"name": "color_low",
|
||
"colour": "#3333ff"
|
||
},
|
||
{
|
||
"type": "input_value",
|
||
"name": "temp_low",
|
||
"check": "Number",
|
||
"align": "RIGHT"
|
||
}
|
||
],
|
||
"inputsInline": false,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_draw_grideyedata'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjDrawGrideyedataDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_draw_grideyedata'] = function (block) {
|
||
var value_amg8833data = Blockly.JavaScript.valueToCode(block, 'amg8833data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var colour_color_high = block.getFieldValue('color_high');
|
||
var value_temp_high = Blockly.JavaScript.valueToCode(block, 'temp_high', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var colour_color_low = block.getFieldValue('color_low');
|
||
var value_temp_low = Blockly.JavaScript.valueToCode(block, 'temp_low', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var functionName = Blockly.JavaScript.provideFunction_(
|
||
'_mapVal',
|
||
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = (val, inMin, inMax, outMin, outMax) => {',
|
||
`return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;`,
|
||
'}'
|
||
]
|
||
);
|
||
// 温度カラー
|
||
let hr, hg, hb, lr, lg, lb;
|
||
hr = '0x' + colour_color_high.slice(1, 3);
|
||
hg = '0x' + colour_color_high.slice(3, 5);
|
||
hb = '0x' + colour_color_high.slice(5, 7);
|
||
lr = '0x' + colour_color_low.slice(1, 3);
|
||
lg = '0x' + colour_color_low.slice(3, 5);
|
||
lb = '0x' + colour_color_low.slice(5, 7);
|
||
var code = ` const _color_range = [[${lr}, ${hr}], [${lg}, ${hg}], [${lb}, ${hb}]];
|
||
let _grideye_data = ${value_amg8833data};//読み取りブロックを入力に直接接続できるようにする
|
||
for (let raw = 0; raw < _grideye_canvas.height; raw++) {
|
||
for (let col = 0; col < _grideye_canvas.width; col++) {
|
||
for (let rgb = 0; rgb < 3; rgb++) {
|
||
let pixel = ${functionName}(_grideye_data[raw][col], ${value_temp_low}, ${value_temp_high}, _color_range[rgb][0], _color_range[rgb][1]);
|
||
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + rgb] = pixel;
|
||
}
|
||
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + 3] = 0xff;
|
||
}
|
||
}
|
||
_grideye_ctx.putImageData(_grideye_imgData, 0, 0);
|
||
|
||
`;
|
||
return code;
|
||
};
|
||
|
||
/**************************** */
|
||
/** Teachable Machine を開始** */
|
||
/**************************** */
|
||
var ugjTeachableMachineDefinition = {
|
||
"type": "ugj_teachable_machine",
|
||
"message0": "%{BKY_UGJ_TEACHABLE_MACHINE_TITLE}",
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_TEACHABLE_MACHINE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_teachable_machine'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjTeachableMachineDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_teachable_machine'] = function (block) {
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_ts', [`const _tf = require('@tensorflow/tfjs-node');`]
|
||
);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_mobilenet', [`const _mobilenet = require('@tensorflow-models/mobilenet');`]
|
||
);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_knn', [`const _knnClassifier = require('@tensorflow-models/knn-classifier');`]
|
||
);
|
||
|
||
var code = `const _classifier = _knnClassifier.create();
|
||
const _net = await _mobilenet.load({ version: 1, alpha: 0.25 }); // 高速・低精度
|
||
`;
|
||
return code;
|
||
};
|
||
/************************* */
|
||
/** GridEye で推論を行う ** */
|
||
/************************* */
|
||
var ugjGridEyePredictClassDefinition = {
|
||
"type": "ugj_grideye_predict_class",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TITLE}",
|
||
"inputsInline": true,
|
||
"output": "Number",
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_predict_class'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyePredictClassDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_predict_class'] = function (block) {
|
||
var functionName = Blockly.JavaScript.provideFunction_( // left output にするための関数化
|
||
'_predictClass',
|
||
[
|
||
`if (_confidence === undefined) var _confidence;`,
|
||
`const ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_} = async (img, clsfr, mblnet) => {`,
|
||
`if (clsfr.getNumClasses() > 0) {`,
|
||
`const result = await clsfr.predictClass(mblnet.infer(img, 'conv_preds'));`,
|
||
`_confidence = result.confidences[result.label];`,
|
||
`return result.label;`,
|
||
`}`,
|
||
`else return 0;`,
|
||
`}`
|
||
]
|
||
);
|
||
var code = `await ${functionName}(_grideye_canvas, _classifier, _net)`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
/******************************************** */
|
||
/** ラベルをつけて Example をデータセットに追加 ** */
|
||
/******************************************** */
|
||
var ugjGridEyeAddExampleDefinition = {
|
||
"type": "ugj_grideye_add_example",
|
||
"message0": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "class_id",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_grideye_add_example'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjGridEyeAddExampleDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_grideye_add_example'] = function (block) {
|
||
var value_class_id = Blockly.JavaScript.valueToCode(block, 'class_id', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `_classifier.addExample (_net.infer(_grideye_canvas, true), ${value_class_id});`;
|
||
return code;
|
||
};
|
||
/*************************** */
|
||
/** 学習したクラスを文字列化 ** */
|
||
/*************************** */
|
||
var ugjTensorsetStringifyDefinition = {
|
||
"type": "ugj_tensorset_stringify",
|
||
"message0": "%{BKY_UGJ_TENSORSET_STRINGIFY_TITLE}",
|
||
"output": null,
|
||
"tooltip": "%{BKY_UGJ_TENSORSET_STRINGIFY_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_tensorset_stringify'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjTensorsetStringifyDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_tensorset_stringify'] = function (block) {
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
||
);
|
||
var code = `await _Tensorset.stringify(_classifier.getClassifierDataset())`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
/***************************************** */
|
||
/** jsonをデータセットに戻して分類器にセット ** */
|
||
/***************************************** */
|
||
var ugjTensorsetParseDefinition = {
|
||
"type": "ugj_tensorset_parse",
|
||
"message0": "%{BKY_UGJ_TENSORSET_PARSE_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "class_data_json",
|
||
"check": "String"
|
||
}
|
||
],
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_TENSORSET_PARSE_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "multimedia_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_tensorset_parse'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjTensorsetParseDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_tensorset_parse'] = function (block) {
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
||
);
|
||
var value_class_data_json = Blockly.JavaScript.valueToCode(block, 'class_data_json', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `try {
|
||
let _class_dataset = _Tensorset.parse(${value_class_data_json});
|
||
_classifier.setClassifierDataset(_class_dataset);
|
||
} catch (error) {
|
||
alert('Could not load class dataset.');
|
||
}
|
||
`;
|
||
return code;
|
||
};
|
||
|
||
|
||
/****************************** */
|
||
/** KeyUpDown Event Listener ** */
|
||
/****************************** */
|
||
Blockly.Blocks['ugj_event_key'] = {
|
||
init: function () {
|
||
this.appendValueInput("key")
|
||
.setCheck("Variable")
|
||
.appendField("キーボードの");
|
||
this.appendDummyInput()
|
||
.appendField("を")
|
||
.appendField(new Blockly.FieldDropdown([["押したとき", "keydown"], ["離したとき", "keyup"]]), "updown");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("キーボードを押したり離したりした時のアクションです。");
|
||
this.setHelpUrl("https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/key/Key_Values");
|
||
this.setStyle('multimedia_blocks');
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_event_key'] = function (block) {
|
||
var value_key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_updown = block.getFieldValue('updown');
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`document.addEventListener('${dropdown_updown}', async (_e) => {`,
|
||
` ${value_key} = _e.key;`,
|
||
statements_do,
|
||
`}, false);`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/**************** */
|
||
/** Play Sound ** */
|
||
/**************** */
|
||
Blockly.Blocks['ugj_sound_play'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField(new Blockly.FieldDropdown([["ニャー", "meow"], ["コン", "bounce"], ["チン", "type_chime"], ["ディン", "type_dink"], ["タイプ", "type_tap"], ["空白", "type_space"], ["改行", "type_return"]]), "sound")
|
||
.appendField("の音を鳴らす");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('multimedia_blocks')
|
||
this.setTooltip("音を鳴らします。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_sound_play'] = function (block) {
|
||
var dropdown_sound = block.getFieldValue('sound');
|
||
var code = `ugj_soundPlay('${dropdown_sound}');\n`;
|
||
return code;
|
||
};
|
||
|
||
|
||
|
||
|
||
/** Network *****************************************************************************************************/
|
||
/**************** */
|
||
/** TCP/IP Socket */
|
||
/**************** */
|
||
Blockly.Blocks['ugj_socket'] = {
|
||
init: function () {
|
||
this.appendValueInput("host")
|
||
.setCheck("String")
|
||
.appendField("ホスト");
|
||
this.appendValueInput("port")
|
||
.setCheck("Number")
|
||
.appendField("ポート");
|
||
this.appendDummyInput()
|
||
.appendField("で TCP 接続する");
|
||
this.appendStatementInput("connect")
|
||
.setCheck(null)
|
||
.appendField("接続したら");
|
||
this.appendStatementInput("data")
|
||
.setCheck(null)
|
||
.appendField(new Blockly.FieldVariable("受信データ"), "data")
|
||
.appendField("が来たら");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("TCP接続(Telnet)でサーバーと接続します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_socket'] = function (block) {
|
||
var value_host = Blockly.JavaScript.valueToCode(block, 'host', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_port = Blockly.JavaScript.valueToCode(block, 'port', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_connect = Blockly.JavaScript.statementToCode(block, 'connect');
|
||
var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
||
var statements_data = Blockly.JavaScript.statementToCode(block, 'data');
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_net', [`const _net = require('net');`]
|
||
);
|
||
var code = [
|
||
`var _client = _net.connect(${value_port}, ${value_host});`,
|
||
`_client.on('connect', async ()=>{`,
|
||
statements_connect,
|
||
`}).on('data', async _data=>{`,
|
||
`${variable_data} = _data.toString('utf-8', 0, _data.length);`,
|
||
statements_data,
|
||
`}).on('close', ()=>{`,
|
||
`console.log('Connection closed.');`,
|
||
`});`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
/*************** */
|
||
/** Socket Write */
|
||
/*************** */
|
||
Blockly.Blocks['ugj_socket_write'] = {
|
||
init: function () {
|
||
this.appendValueInput("cmd")
|
||
.setCheck("String")
|
||
.appendField("TCP接続に");
|
||
this.appendDummyInput()
|
||
.appendField("を送信する");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("TCP接続で開いたソケットにデータを書き込みます。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_socket_write'] = function (block) {
|
||
var value_cmd = Blockly.JavaScript.valueToCode(block, 'cmd', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = [
|
||
`_client.write(${value_cmd});`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/************** */
|
||
/** HTTP Server */
|
||
/************** */
|
||
Blockly.Blocks['ugj_network_httpserver'] = {
|
||
init: function () {
|
||
this.appendValueInput("url")
|
||
.setCheck("Variable")
|
||
.appendField("Webサーバを起動してアクセスを待ち、");
|
||
this.appendDummyInput()
|
||
.appendField("へアクセスがあったら");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.appendValueInput("response")
|
||
.setCheck(null)
|
||
.appendField("最後に");
|
||
this.appendDummyInput()
|
||
.appendField("を表示してアクセス待ちに戻る");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setTooltip("HTTPサーバを起動します。ポートは3000固定です。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('network_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_network_httpserver'] = function (block) {
|
||
var value_url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_url = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('URL'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var value_response = Blockly.JavaScript.valueToCode(block, 'response', Blockly.JavaScript.ORDER_ATOMIC);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_http', [`const _http = require('http');`]
|
||
);
|
||
var code = [
|
||
`let _req, _res;`,
|
||
`_http.createServer(async (_req, _res) => {`,
|
||
`_res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });`,
|
||
`${value_url} = _req.url;`,
|
||
statements_do,
|
||
// `_res.write('<!DOCTYPE html><html lang="ja"><head><meta charset="UTF-8"></head><body>');`,
|
||
`_res.end(${value_response});`,
|
||
`}).listen(3000);`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/******************** */
|
||
/** axios HTTP client */
|
||
/******************** */
|
||
// Get URL
|
||
Blockly.Blocks['ugj_network_axios_geturl'] = {
|
||
init: function () {
|
||
this.appendValueInput("url")
|
||
.setCheck("String")
|
||
.appendField("URL");
|
||
this.appendDummyInput()
|
||
.appendField("の内容");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("URLにGETリクエストを送信し、レスポンスを取得します。エラーの場合、HTTPステータスコードを返します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_network_axios_geturl'] = function (block) {
|
||
var value_url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var functionName = Blockly.JavaScript.provideFunction_(
|
||
'_getUrl',
|
||
[
|
||
`const axios = require('axios');`,
|
||
'const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = async url => {',
|
||
'let res, ret;',
|
||
'try {',
|
||
`res = await axios.get(url);`,
|
||
'ret = res.data;',
|
||
'} catch (error) {',
|
||
'if (error.response) {',
|
||
'ret = error.response.status;',
|
||
'} else {',
|
||
'ret = 999;',
|
||
'}',
|
||
'}',
|
||
'return ret;',
|
||
'}'
|
||
]
|
||
);
|
||
var code = `await ${functionName}(${value_url})`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
/*********** */
|
||
/** Sendmail */
|
||
/*********** */
|
||
Blockly.Blocks['ugj_network_sendmail'] = {
|
||
init: function () {
|
||
this.appendValueInput("to")
|
||
.setCheck("String")
|
||
this.appendValueInput("subject")
|
||
.setCheck("String")
|
||
.appendField("へメールを送信:件名");
|
||
this.appendValueInput("text")
|
||
.setCheck("String")
|
||
.appendField("本文");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("メールを送信します。Fromアドレスは使用できません。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_network_sendmail'] = function (block) {
|
||
var value_to = Blockly.JavaScript.valueToCode(block, 'to', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_subject = Blockly.JavaScript.valueToCode(block, 'subject', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC);
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_sendmail', [`const _nodemailer = require('nodemailer');`]
|
||
);
|
||
var code = [
|
||
`let _smtp = _nodemailer.createTransport({`,
|
||
`host: '192.168.0.201',`,
|
||
`port: 25`,
|
||
`});`,
|
||
`let _message = {`,
|
||
`from: 'no-reply@ocoge.club',`,
|
||
`to: ${value_to},`,
|
||
`subject: ${value_subject},`,
|
||
`text: ${value_text}`,
|
||
`};`,
|
||
`try{`,
|
||
`_smtp.sendMail(_message, function(_error, _info){`,
|
||
`if(_error){`,
|
||
`alert('送信エラー:' + _error.message);`,
|
||
`return;`,
|
||
`}`,
|
||
`console.log('send successfully');`,
|
||
`});`,
|
||
`} catch(_e) {alert('Error: ',_e);}`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/********************* */
|
||
/** WebRTC Web Chat ** */
|
||
/********************* */
|
||
|
||
// skyway.js Library
|
||
Blockly.Blocks['ugj_library_skyway'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("WebRTC+SkyWayによるウェブチャット");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "Library");
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("skyway.jsをロードし、ウェブチャットができるようにします。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_library_skyway'] = function (block) {
|
||
var code = `'${elutil.path.join(elutil.library_path, 'skyway.min.js')}'`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
|
||
// WebChat Statement Begin
|
||
Blockly.Blocks['ugj_webchat'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("チャットに必要な部品を表示");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("ビデオ画面、チャット入力フォームや黒板を表示します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_webchat'] = function (block) {
|
||
var code = [
|
||
`const _blackboard = document.getElementById('blackboard');`,
|
||
"_blackboard.style.display = 'inline-block';",
|
||
`const _inputForm = document.getElementById('inputForm');`,
|
||
"_inputForm.style.display = 'inline-block';",
|
||
`const _inputBox = document.getElementById('inputBox');`,
|
||
"_inputBox.focus();",
|
||
"const _remoteVideo = document.getElementById('maindisplay');",
|
||
`_remoteVideo.style.display = 'inline-block';`,
|
||
"const _localVideo = document.getElementById('subdisplay');",
|
||
`_localVideo.style.display = 'inline-block';`,
|
||
`var _localStream;`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// getUserMedia
|
||
Blockly.Blocks['ugj_getusermedia'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("ローカルメディアを開始")
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("このコンピュータにつながれているメディアデバイスから映像を取得して表示します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_getusermedia'] = function (block) {
|
||
var code = [
|
||
`navigator.mediaDevices.getUserMedia({video: true, audio: false})`,
|
||
' .then(_stream => {',
|
||
' _localVideo.srcObject = _stream;',
|
||
' _localStream = _stream;',
|
||
' }).catch( _error => {',
|
||
' console.error(\'mediaDevice.getUserMedia() error:\', _error);',
|
||
' return;',
|
||
' });',
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// SkyWay New Peer
|
||
Blockly.Blocks['ugj_skyway_newpeer'] = {
|
||
init: function () {
|
||
this.appendValueInput("my_id")
|
||
.setCheck("Variable")
|
||
.appendField("SkyWayサーバーに ID:");
|
||
this.appendValueInput("apikey")
|
||
.setCheck("String")
|
||
.appendField("APIキー:");
|
||
this.appendDummyInput()
|
||
.appendField("で接続する");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null)
|
||
.appendField("接続したら");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("サーバーにIDを登録して、相手先呼び出しの準備をします。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('network_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_newpeer'] = function (block) {
|
||
var value_my_id = Blockly.JavaScript.valueToCode(block, 'my_id', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_my_id = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('my_id'), Blockly.Variables.NAME_TYPE);
|
||
// var text_name = block.getFieldValue('NAME');
|
||
var value_apikey = Blockly.JavaScript.valueToCode(block, 'apikey', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`const _peer = new Peer(${value_my_id}, {`,
|
||
` key: ${value_apikey},`,
|
||
// " key: window.__SKYWAY_KEY__,",
|
||
" debug: 3",
|
||
"});",
|
||
"_peer.on('open', () => {",
|
||
// ' ugj_blackboardWrite(`SkyWay: "${peer.id}" OK`)',
|
||
`${value_my_id} = _peer.id;`,
|
||
"_inputForm.addEventListener('submit', _onMakeCall);",
|
||
statements_do,
|
||
"});",
|
||
"_peer.on('error', _err => alert(_err.message));",
|
||
"const _onMakeCall = _e => {",
|
||
" _e.preventDefault();",
|
||
" const _call = _peer.call(_inputBox.value, _localStream);",
|
||
" _setupCallEventHandlers(_call);",
|
||
" const _connect = _peer.connect(_inputBox.value);",
|
||
" _setupConnectEventHandlers(_connect);",
|
||
" _inputBox.value = '';",
|
||
"}",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// Catch Call and Connect Request
|
||
Blockly.Blocks['ugj_skyway_called'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("チャットに誘われたら応じる");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("接続要求があった場合、チャットを開始する処理です。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_called'] = function (block) {
|
||
var code = [
|
||
"_peer.on('call', _call => {",
|
||
" _call.answer(_localStream);",
|
||
" _setupCallEventHandlers(_call);",
|
||
"});",
|
||
"_peer.on('connection', _connect => {",
|
||
" _setupConnectEventHandlers(_connect);",
|
||
"});",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// EventHandlers for Call and Connect
|
||
Blockly.Blocks['ugj_skyway_events'] = {
|
||
init: function () {
|
||
this.appendValueInput("remote_id")
|
||
.setCheck("Variable");
|
||
this.appendDummyInput()
|
||
.appendField("との接続後にすること");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("チャットの相手との接続後の動作を定義します。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('network_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_events'] = function (block) {
|
||
var value_remote_id = Blockly.JavaScript.valueToCode(block, 'remote_id', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_remote_id = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('remote_id'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
"const _setupCallEventHandlers = _call => _call.on('stream', _stream => _remoteVideo.srcObject = _stream);",
|
||
"const _setupConnectEventHandlers = _connect => {",
|
||
" _inputForm.removeEventListener('submit', _onMakeCall);",
|
||
` ${value_remote_id} = _connect.remoteId;`,
|
||
statements_do,
|
||
"}",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// Peer Open
|
||
Blockly.Blocks['ugj_skyway_eventopen'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("接続したらすぐ");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('network_blocks')
|
||
this.setTooltip("チャット相手との接続が確立したときの動作を決めます。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_eventopen'] = function (block) {
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
" _connect.on('open', () => {",
|
||
" _inputForm.addEventListener('submit', _onSendMsg)",
|
||
statements_do,
|
||
" });",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// Peer Data Receive
|
||
Blockly.Blocks['ugj_skyway_eventdata'] = {
|
||
init: function () {
|
||
this.appendValueInput("data")
|
||
.setCheck("Variable")
|
||
.appendField("相手の");
|
||
this.appendDummyInput()
|
||
.appendField("を受けとったら");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("チャット相手の発言を受信したときの動作です。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('network_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_eventdata'] = function (block) {
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
" _connect.on('data', _data => {",
|
||
` ${value_data} = _data;`,
|
||
statements_do,
|
||
" });",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
// Send Message
|
||
Blockly.Blocks['ugj_skyway_eventsend'] = {
|
||
init: function () {
|
||
this.appendValueInput("data")
|
||
.setCheck("Variable")
|
||
.appendField("入力フィールドの");
|
||
this.appendDummyInput()
|
||
.appendField("を送信するとき");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("入力フィールドで送信が発生したときの動作を決めます。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('network_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_skyway_eventsend'] = function (block) {
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
" const _onSendMsg = () => {",
|
||
` ${value_data} = _inputBox.value;`,
|
||
` _connect.send(${value_data});`,
|
||
" _inputBox.value = '';",
|
||
statements_do,
|
||
" }",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
|
||
|
||
/** Utilitiy Blocks ***********************************************************************************************/
|
||
|
||
/************ */
|
||
/** File Read */
|
||
/************ */
|
||
Blockly.Blocks['ugj_file_readsync'] = {
|
||
init: function () {
|
||
this.appendValueInput("filename")
|
||
.setCheck("String")
|
||
.appendField("ファイル");
|
||
this.appendDummyInput()
|
||
.appendField("の内容:符号化")
|
||
.appendField(new Blockly.FieldDropdown([["utf8", "utf8"], ["base64", "base64"], ["binary", "binary"]]), "encoding");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("あなたのホーム/Documentsディレクトリ内にあるファイルの内容を取得します。「符号化」は、テキストファイルでは通常「utf8」を選択します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_file_readsync'] = function (block) {
|
||
var value_filename = Blockly.JavaScript.valueToCode(block, 'filename', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_encoding = block.getFieldValue('encoding');
|
||
let filepath = elutil.path.join(elutil.doc_root, value_filename.replace(/\'/g, ''));
|
||
Blockly.JavaScript.provideFunction_(
|
||
'require_fs', [`const _fs = require('fs');`]
|
||
);
|
||
var code = `_fs.readFileSync('${filepath}', '${dropdown_encoding}')`;
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
|
||
/********************************* */
|
||
/** Save TextData to Local Storage */
|
||
/********************************* */
|
||
Blockly.Blocks['ugj_localstorage_save'] = {
|
||
init: function () {
|
||
this.appendValueInput("keyValue")
|
||
.setCheck("String");
|
||
this.appendValueInput("keyName")
|
||
.setCheck("String")
|
||
.appendField("をローカルストレージ");
|
||
this.appendDummyInput()
|
||
.appendField("に保存する");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("テキストデータをローカルストレージに名前を付けて保存します。名前は半角アルファベットと数字だけで指定してください。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_localstorage_save'] = function (block) {
|
||
var value_keyvalue = Blockly.JavaScript.valueToCode(block, 'keyValue', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_keyname = Blockly.JavaScript.valueToCode(block, 'keyName', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `localStorage.setItem(${value_keyname}, ${value_keyvalue});\n`;
|
||
return code;
|
||
};
|
||
/*********************************** */
|
||
/** Load Textdata from Local Storage */
|
||
/*********************************** */
|
||
Blockly.Blocks['ugj_localstorage_load'] = {
|
||
init: function () {
|
||
this.appendValueInput("keyName")
|
||
.setCheck("String")
|
||
.appendField("ローカルストレージ");
|
||
this.appendDummyInput()
|
||
.appendField("の内容");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks');
|
||
this.setTooltip("ローカルストレージからテキストデータを読み込みます。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_localstorage_load'] = function (block) {
|
||
var value_keyname = Blockly.JavaScript.valueToCode(block, 'keyName', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `localStorage.getItem(${value_keyname})`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
/******************************* */
|
||
/** Remove Item in Local Storage */
|
||
/******************************* */
|
||
Blockly.Blocks['ugj_localstorage_remove'] = {
|
||
init: function () {
|
||
this.appendValueInput("key")
|
||
.setCheck("String")
|
||
.appendField("ローカルストレージ");
|
||
this.appendDummyInput()
|
||
.appendField("を削除");
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks');
|
||
this.setTooltip("ローカルストレージに保存されたアイテムを削除します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_localstorage_remove'] = function (block) {
|
||
var value_key = Blockly.JavaScript.valueToCode(block, 'key', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `localStorage.removeItem(${value_key});\n`;
|
||
return code;
|
||
};
|
||
|
||
/********************** */
|
||
/** Question and Answer */
|
||
/********************** */
|
||
Blockly.Blocks['ugj_event_answer'] = {
|
||
init: function () {
|
||
this.appendValueInput("question")
|
||
.setCheck("String");
|
||
this.appendValueInput("answer")
|
||
.setCheck("Variable")
|
||
.appendField("ときいて");
|
||
this.appendDummyInput()
|
||
.appendField("を待つ");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setPreviousStatement(true, null);
|
||
this.setTooltip("質問をして答えを待ちます。入力欄でキーボードのエンターキーが入力されるか、チェックマークボタンが押されると実行されます。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('special_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_event_answer'] = function (block) {
|
||
var value_question = Blockly.JavaScript.valueToCode(block, 'question', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_answer = Blockly.JavaScript.valueToCode(block, 'answer', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_answer = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('answer'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`ugj_fukidashi(${value_question}, 0);`,
|
||
`_inputForm = document.getElementById('inputForm');`,
|
||
`_inputBox = document.getElementById('inputBox');`,
|
||
"_inputForm.style.display = 'inline-block'",
|
||
"_inputBox.focus();",
|
||
"const _inputFunc = async () => { ",
|
||
" if (_inputBox.value.length > 0) {",
|
||
` ${value_answer} = _inputBox.value;`,
|
||
' _inputForm.style.display = "none"',
|
||
" _inputBox.value = '';",
|
||
" document.getElementById('canvas').getContext('2d').clearRect(ugj_fdRecentBox.x,ugj_fdRecentBox.y,ugj_fdRecentBox.w,ugj_fdRecentBox.h);",
|
||
statements_do,
|
||
" console.log('Removing listener...');",
|
||
" _inputForm.removeEventListener('submit', _inputFunc );",
|
||
" }",
|
||
"}",
|
||
"_inputForm.addEventListener('submit', _inputFunc );",
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/************ */
|
||
/** SpawnSync */
|
||
/************ */
|
||
Blockly.Blocks['ugj_spawnsync'] = {
|
||
init: function () {
|
||
this.appendValueInput("childprocess")
|
||
.setCheck("shcmd")
|
||
.appendField("外部プログラム");
|
||
this.appendValueInput("data")
|
||
.setCheck("Variable")
|
||
.appendField("を同期的に実行して");
|
||
this.appendDummyInput()
|
||
.appendField("を受け取る");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("外部プログラムを実行して子プロセスを生成し、子プロセスが終了するまで待ちます。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('special_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_spawnsync'] = function (block) {
|
||
var value_childprocess = Blockly.JavaScript.valueToCode(block, 'childprocess', Blockly.JavaScript.ORDER_NONE);
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
||
var code = `${value_data} = require('child_process').spawnSync(${value_childprocess}).stdout.toString();\n`;
|
||
// var code = `${variable_data} = require('child_process').execFileSync(${value_childprocess});\n`;
|
||
return code;
|
||
};
|
||
|
||
/*********** */
|
||
/** Spawn ** */
|
||
/*********** */
|
||
Blockly.Blocks['ugj_spawn'] = {
|
||
init: function () {
|
||
this.appendValueInput("childprocess")
|
||
.setCheck("shcmd")
|
||
.appendField("外部プログラム");
|
||
this.appendValueInput("data")
|
||
.setCheck(null)
|
||
.appendField("を非同期に実行して");
|
||
this.appendDummyInput()
|
||
.appendField("を受け取る");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("外部プログラムを実行して子プロセスを生成します。データを受け取る毎にステートメントが実行されます。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('special_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_spawn'] = function (block) {
|
||
var value_childprocess = Blockly.JavaScript.valueToCode(block, 'childprocess', Blockly.JavaScript.ORDER_NONE);
|
||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`let _child = require('child_process').spawn(${value_childprocess});`,
|
||
`elutil.addChild(_child);`,
|
||
"_child.stderr.on('data', _data => { console.error(_data.toString()) })",
|
||
"_child.stdout.on('data', async _data => {",
|
||
`${value_data} = _data.toString();`,
|
||
statements_do,
|
||
"})",
|
||
"_child.on('close', (_code, _signal) => { if (_code !== 0) { console.error(`process exited with code ${_code}, signal ${_signal}`)}",
|
||
"})",
|
||
''
|
||
].join("\n");
|
||
return code;
|
||
};
|
||
/************************** */
|
||
/** Child shell commands ** */
|
||
/************************** */
|
||
|
||
|
||
// AquesTalk Pi
|
||
Blockly.Blocks['aquestalk_pi'] = {
|
||
init: function () {
|
||
this.appendValueInput("talk")
|
||
.setCheck("String")
|
||
.appendField("ゆっくりで");
|
||
this.appendDummyInput()
|
||
.appendField("とおしゃべりする");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("日本語音声合成プログラム「AquesTalk Pi」を使用してしゃべります。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['aquestalk_pi'] = function (block) {
|
||
var value_talk = Blockly.JavaScript.valueToCode(block, 'talk', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `"${elutil.path.join(elutil.executable_path, 'aquestalkpi/AquesTalkPi') + ' -g 50 ' + value_talk + ' | aplay'}", { shell: true }`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
// fswebcam
|
||
Blockly.Blocks['ugj_child_fswebcam'] = {
|
||
init: function () {
|
||
this.appendValueInput("filename")
|
||
.setCheck("String")
|
||
.appendField("fswebcamで写真を撮り、ファイル");
|
||
this.appendDummyInput()
|
||
.appendField("に保存");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("fswebcam");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_fswebcam'] = function (block) {
|
||
var value_filename = Blockly.JavaScript.valueToCode(block, 'filename', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `'fswebcam', ['-r', '480x360', '${elutil.doc_root}' + ${value_filename}]`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
// Julius
|
||
Blockly.Blocks['ugj_child_julius'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("Julius");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("音声認識エンジン \"Julius\"");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_julius'] = function (block) {
|
||
var code = `'${elutil.path.join(elutil.executable_path, 'julius/julius-simple')}', ['-C', '${elutil.path.join(elutil.executable_path, 'julius/dictation-kit/am-gmm.jconf')}', '-gram', '${elutil.path.join(elutil.executable_path, 'julius/dic/assistant')}', '-nostrip']`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
// irrp.py - pigpioによる赤外線リモコンの学習
|
||
Blockly.Blocks['ugj_child_irrecord'] = {
|
||
init: function () {
|
||
this.appendValueInput("gpio")
|
||
.setCheck("Number")
|
||
.appendField("GPIO");
|
||
this.appendDummyInput()
|
||
.appendField("でリモコンの信号を受信");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("受信した赤外線リモコンの信号を文字列として取得します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_irrecord'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var code = `'python3', ['${elutil.path.join(elutil.library_path, 'irrp.py')}', '-r', '-g', '${value_gpio}', 'signal', '--post', '130']`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
// 送信
|
||
Blockly.Blocks['ugj_child_irplayback'] = {
|
||
init: function () {
|
||
this.appendValueInput("gpio")
|
||
.setCheck("Number")
|
||
.appendField("GPIO");
|
||
this.appendValueInput("signal")
|
||
.setCheck("String")
|
||
.appendField("からリモコン信号");
|
||
this.appendDummyInput()
|
||
.appendField("を送信");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("学習済みの赤外線リモコンの信号を送信します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_irplayback'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_signal = Blockly.JavaScript.valueToCode(block, 'signal', Blockly.JavaScript.ORDER_ATOMIC);//.replace('{','\\{').replace('}','\\}').replace(/"/g,'\\"').replace(/ /g,'\\ ')
|
||
var code = `'python3', ['${elutil.path.join(elutil.library_path, 'irrp.py')}', '-p', '-g', '${value_gpio}', '--irdata', ${value_signal}, 'signal']`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
// ハッシュ生成
|
||
Blockly.Blocks['ugj_child_irrcvr'] = {
|
||
init: function () {
|
||
this.appendValueInput("gpio")
|
||
.setCheck("Number")
|
||
.appendField("GPIO");
|
||
this.appendDummyInput()
|
||
.appendField("で受信したリモコン信号から識別コードを生成");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("受信した赤外線リモコンの信号からハッシュを生成します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_irrcvr'] = function (block) {
|
||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// var code = `'python3', ['./scripts/irrcvr.py', '-g', '${value_gpio}']`;
|
||
var code = `'${elutil.path.join(elutil.executable_path, 'ir_hash/ir_hash')}', ['${value_gpio}']`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
// Python との連携のひな型
|
||
Blockly.Blocks['ugj_child_testpy'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("testpy");
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_testpy'] = function (block) {
|
||
// TODO: Assemble JavaScript into code variable.
|
||
var code = "'python3', ['test.py']";
|
||
// TODO: Change ORDER_NONE to the correct strength.
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
// 外部 Node との連携のひな型
|
||
Blockly.Blocks['ugj_child_testjs'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("testjs");
|
||
this.setOutput(true, "shcmd");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_child_testjs'] = function (block) {
|
||
// TODO: Assemble JavaScript into code variable.
|
||
var code = "'node', ['test.js']";
|
||
// TODO: Change ORDER_NONE to the correct strength.
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
/******************* */
|
||
/** Show Blackboard ** */
|
||
/******************* */
|
||
Blockly.Blocks['ugj_blackboard_show'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("黒板を表示");
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("文字を表示するための専用エリアを表示します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_blackboard_show'] = function (block) {
|
||
var code = "document.getElementById('blackboard').style.display = 'inline-block';\n";
|
||
return code;
|
||
};
|
||
|
||
/************************* */
|
||
/** Write text to Blackboard */
|
||
/************************* */
|
||
Blockly.Blocks['ugj_blackboard_write'] = {
|
||
init: function () {
|
||
this.appendValueInput("text")
|
||
.setCheck("String")
|
||
.appendField("黒板に");
|
||
this.appendValueInput("color")
|
||
.setCheck("Colour")
|
||
.appendField("を表示 | 色:");
|
||
this.appendDummyInput()
|
||
.appendField("|")
|
||
.appendField(new Blockly.FieldDropdown([["普通", "normal"], ["斜体", "italic"]]), "style")
|
||
.appendField("|")
|
||
.appendField(new Blockly.FieldDropdown([["新しい行を追加", "new"], ["最後の行を上書き", "last"]]), "line");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("黒板に文字を表示します。次の行に追加する他、最後の行を書き換えることもできます。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_blackboard_write'] = function (block) {
|
||
var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var dropdown_style = block.getFieldValue('style');
|
||
var dropdown_line = block.getFieldValue('line');
|
||
var funcAppendDivName = Blockly.JavaScript.provideFunction_(
|
||
'_appendDiv',
|
||
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = termEl => {',
|
||
`let el = document.createElement('div');`,
|
||
`termEl.appendChild(el);`,
|
||
`return el;`,
|
||
'}']
|
||
);
|
||
var funcTermWriteName = Blockly.JavaScript.provideFunction_(
|
||
'_blackboardWrite',
|
||
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = (text, color, style, line) => {',
|
||
`let termEl = document.getElementById('blackboard')`,
|
||
'let el = null;',
|
||
`if (line == 'new') {`,
|
||
`el = ${funcAppendDivName}(termEl);`,
|
||
`} else {`,
|
||
`el = termEl.lastChild;`,
|
||
`if (el === null) {`,
|
||
`el = ${funcAppendDivName}(termEl);`,
|
||
`}`,
|
||
`}`,
|
||
`el.style.color = color;`,
|
||
`el.style.fontStyle = style;`,
|
||
// `el.innerHTML = ugj_htmlEntities(text);`,
|
||
`el.innerHTML = text;`,
|
||
`termEl.scrollTop = termEl.scrollHeight;`,
|
||
'}//#']
|
||
);
|
||
value_text = ugj_htmlEntities(value_text);
|
||
var code = [
|
||
`${funcTermWriteName}(${value_text}, ${value_color}, '${dropdown_style}', '${dropdown_line}');`,
|
||
'',
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/******************** */
|
||
/** Clear Blackboard ** */
|
||
/******************** */
|
||
Blockly.Blocks['ugj_clearblackboard'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("黒板をクリア");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("黒板をきれいにします。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_clearblackboard'] = function (block) {
|
||
var code = `document.getElementById('blackboard').innerHTML = '';\n`;
|
||
return code;
|
||
};
|
||
|
||
/************************* */
|
||
/** Get BlackBoard Content */
|
||
/************************* */
|
||
Blockly.Blocks['ugj_blackboard_content'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("黒板の内容");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("黒板の内容をプレーンテキストで取得します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_blackboard_content'] = function (block) {
|
||
var code = `document.getElementById('blackboard').innerText`;
|
||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||
};
|
||
|
||
/************* */
|
||
/** Soft Sleep */
|
||
/************* */
|
||
var ugjSleepDefinition = {
|
||
"type": "ugj_sleep",
|
||
"message0": "%{BKY_UGJ_SLEEP_TITLE}",
|
||
"args0": [
|
||
{
|
||
"type": "input_value",
|
||
"name": "sec",
|
||
"check": "Number"
|
||
}
|
||
],
|
||
"inputsInline": true,
|
||
"previousStatement": null,
|
||
"nextStatement": null,
|
||
"tooltip": "%{BKY_UGJ_SLEEP_TOOLTIP}",
|
||
"helpUrl": "",
|
||
"style": "special_blocks"
|
||
};
|
||
Blockly.Blocks['ugj_sleep'] = {
|
||
init: function () {
|
||
this.jsonInit(ugjSleepDefinition);
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_sleep'] = function (block) {
|
||
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var functionName = Blockly.JavaScript.provideFunction_(
|
||
'_sleep',
|
||
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = sec =>',
|
||
'new Promise(r => setTimeout(r, sec * 1000));']
|
||
);
|
||
var code = `await ${functionName}(${value_sec});\n`;
|
||
return code;
|
||
};
|
||
Blockly.Python['ugj_sleep'] = function (block) {
|
||
var value_sec = Blockly.Python.valueToCode(block, 'sec', Blockly.Python.ORDER_ATOMIC);
|
||
Blockly.Python.provideFunction_(
|
||
'import_sleep', ['from time import sleep']
|
||
)
|
||
var code = `sleep(${value_sec})\n`;
|
||
return code;
|
||
};
|
||
/********************* */
|
||
/** Carriage Return ** */
|
||
/********************* */
|
||
Blockly.Blocks['ugj_text_cr'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("CR");
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setColour(Blockly.Msg.TEXTS_HUE);
|
||
this.setTooltip("特殊記号(キャリッジリターン)");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_text_cr'] = function (block) {
|
||
var code = "'\\r'";
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
Blockly.Python['ugj_text_cr'] = function (block) {
|
||
var code = "'\\r'";
|
||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||
};
|
||
/*************** */
|
||
/** Line Feed ** */
|
||
/*************** */
|
||
Blockly.Blocks['ugj_text_lf'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("LF");
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setColour(Blockly.Msg.TEXTS_HUE);
|
||
this.setTooltip("特殊記号(ラインフィード)");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_text_lf'] = function (block) {
|
||
var code = "'\\n'";
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
/******* */
|
||
/** Null */
|
||
/******* */
|
||
Blockly.Blocks['ugj_text_null'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("NULL");
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setColour(Blockly.Msg.TEXTS_HUE);
|
||
this.setTooltip("特殊記号(ヌル文字)");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_text_null'] = function (block) {
|
||
var code = "'\\0'";
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
/********* */
|
||
/** Cursor */
|
||
/********* */
|
||
Blockly.Blocks['ugj_text_cursor'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("カーソル");
|
||
this.setInputsInline(true);
|
||
this.setOutput(true, "String");
|
||
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
|
||
this.setColour(Blockly.Msg.TEXTS_HUE);
|
||
this.setTooltip("特殊記号(カーソル)");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_text_cursor'] = function (block) {
|
||
var code = "'▋'";
|
||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||
};
|
||
|
||
/******************/
|
||
/** Set Interval **/
|
||
/******************/
|
||
Blockly.Blocks['ugj_set_interval'] = {
|
||
init: function () {
|
||
this.appendValueInput("sec")
|
||
.setCheck("Number");
|
||
this.appendDummyInput()
|
||
.appendField("秒ごとにくり返す");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("非同期で繰り返し処理を行います(停止ボタンまたは停止ブロックで停止)。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_set_interval'] = function (block) {
|
||
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
'let _interval = setInterval( async () => {',
|
||
statements_do,
|
||
`}, ${value_sec}*1000);`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
/******************** */
|
||
/** Clear Interval ** */
|
||
/******************** */
|
||
Blockly.Blocks['ugj_special_clearinterval'] = {
|
||
init: function () {
|
||
this.appendDummyInput()
|
||
.appendField("繰り返しを停止する");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("非同期の繰り返し処理を停止します。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_special_clearinterval'] = function (block) {
|
||
var code = 'clearInterval(_interval);\n';
|
||
return code;
|
||
};
|
||
/********+********/
|
||
/** Set Timeout **/
|
||
/********+********/
|
||
Blockly.Blocks['ugj_set_timeout'] = {
|
||
init: function () {
|
||
this.appendValueInput("sec")
|
||
.setCheck("Number");
|
||
this.appendDummyInput()
|
||
.appendField("秒待ってから");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("指定した秒数だけ待ってから実行します。");//内側のブロック部を 外側下に接続したものは待たずに直ちに実行されます(非同期動作)。
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_set_timeout'] = function (block) {
|
||
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = `let _interval = setTimeout(async () => {\n${statements_do}}, ${value_sec}*1000);\n`;
|
||
return code;
|
||
};
|
||
|
||
/**************************** */
|
||
/** Dinamic Load JS Libraries */
|
||
/**************************** */
|
||
Blockly.Blocks['ugj_library_load'] = {
|
||
init: function () {
|
||
this.appendValueInput("lib")
|
||
.setCheck("Library");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setStyle('special_blocks')
|
||
this.setTooltip("ライブラリをロードします。");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_library_load'] = function (block) {
|
||
var value_lib = Blockly.JavaScript.valueToCode(block, 'lib', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`let _scriptEl = document.createElement('script');`,
|
||
`_scriptEl.onload = async _ev => {`,
|
||
`${statements_do}`,
|
||
`};`,
|
||
`_scriptEl.src = ${value_lib};`,
|
||
`document.getElementsByTagName('head')[0].appendChild(_scriptEl);`,
|
||
''
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
/******************* */
|
||
/** Create Button ** */
|
||
/******************* */
|
||
Blockly.Blocks['ugj_control_button'] = {
|
||
init: function () {
|
||
this.appendValueInput("label")
|
||
.setCheck("String")
|
||
.appendField("ボタンを作成:ラベル");
|
||
this.appendValueInput("textcolor")
|
||
.setCheck("Colour")
|
||
.appendField("文字色");
|
||
this.appendValueInput("bgcolor")
|
||
.setCheck("Colour")
|
||
.appendField("背景色");
|
||
this.appendValueInput("title")
|
||
.setCheck("String")
|
||
.appendField("ツールチップ");
|
||
this.appendStatementInput("do")
|
||
.setCheck(null);
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setTooltip("ディスプレイカラムにボタンを作成し、クリックのイベントリスナを定義します。テキストデータをひとつ、\"title\"属性値として設定・取り出しが可能です。保存したデータはマウスオーバーで確認できます。");
|
||
this.setHelpUrl("");
|
||
this.setStyle('special_blocks')
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_control_button'] = function (block) {
|
||
var value_label = Blockly.JavaScript.valueToCode(block, 'label', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_textcolor = Blockly.JavaScript.valueToCode(block, 'textcolor', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_bgcolor = Blockly.JavaScript.valueToCode(block, 'bgcolor', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_title = Blockly.JavaScript.valueToCode(block, 'title', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||
var code = [
|
||
`( async () => {`,
|
||
`let el = document.createElement('button');`,
|
||
`el.innerText = ${value_label};`,
|
||
`el.style.color = ${value_textcolor};`,
|
||
`el.style.backgroundColor = ${value_bgcolor};`,
|
||
`el.title = ${value_title};`,
|
||
`el.className = 'toolbarButton ocgButton';`,
|
||
`document.getElementById('dispColumn').appendChild(el);`,
|
||
`el.addEventListener('click', async ev => {`,
|
||
statements_do,
|
||
`});`,
|
||
`})();`,
|
||
'',
|
||
].join('\n');
|
||
return code;
|
||
};
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
// 開発用
|
||
///////////////////////////////////////////////////////////////////////////
|
||
Blockly.Blocks['ugj_dev_run_js'] = {
|
||
init: function () {
|
||
this.appendValueInput("arg")
|
||
.setCheck(null)
|
||
.setAlign(Blockly.ALIGN_RIGHT)
|
||
.appendField("Arg:");
|
||
this.appendValueInput("code")
|
||
.setCheck("String")
|
||
.setAlign(Blockly.ALIGN_RIGHT)
|
||
.appendField("Code:");
|
||
this.appendValueInput("password")
|
||
.setCheck("String")
|
||
.setAlign(Blockly.ALIGN_RIGHT)
|
||
.appendField("Pwd:");
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setColour(230);
|
||
this.setTooltip("");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['ugj_dev_run_js'] = function (block) {
|
||
var value_arg = Blockly.JavaScript.valueToCode(block, 'arg', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_code = Blockly.JavaScript.valueToCode(block, 'code', Blockly.JavaScript.ORDER_ATOMIC);
|
||
var value_password = Blockly.JavaScript.valueToCode(block, 'password', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// TODO: Assemble JavaScript into code variable.
|
||
var code = `
|
||
const crypto = require('crypto');
|
||
let hashHex = crypto.createHash('sha256').update(${value_password}, 'utf8').digest('hex');
|
||
if (hashHex == ugj_const.dev_hash) {
|
||
let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor
|
||
let ocogeFunc = new AsyncFunction('arg', ${value_code});
|
||
await ocogeFunc(${value_arg});
|
||
}
|
||
else console.log('invalid certification');
|
||
`;
|
||
return code;
|
||
};
|
||
|
||
Blockly.Blocks['testblock'] = {
|
||
init: function () {
|
||
this.appendValueInput("foo")
|
||
.setCheck("Variable")
|
||
.appendField("テスト");
|
||
this.setInputsInline(true);
|
||
this.setPreviousStatement(true, null);
|
||
this.setNextStatement(true, null);
|
||
this.setColour(230);
|
||
this.setTooltip("");
|
||
this.setHelpUrl("");
|
||
}
|
||
};
|
||
Blockly.JavaScript['testblock'] = function (block) {
|
||
var value_foo = Blockly.JavaScript.valueToCode(block, 'foo', Blockly.JavaScript.ORDER_ATOMIC);
|
||
// TODO: Assemble JavaScript into code variable.
|
||
var code = `${value_foo} = 42;\n`;
|
||
return code;
|
||
}; |