ocoge/blocks/blocks.js

3547 lines
125 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Color Picker : ビルトインのブロックがウチの環境でどうもうまく働かないので自作
registerFieldColour();
Blockly.defineBlocksWithJsonArray([
{
type: 'colour_picker',
message0: '%1',
"output": "Colour",
"tooltip": "パレットから色を選んでください",
"helpUrl": "",
"style": "colour_blocks",
args0: [
{
type: 'field_colour',
name: 'COLOUR',
colour: '#ff0000',
},
],
},
]);
javascript.javascriptGenerator.forBlock['colour_picker'] = function (block, generator) {
const code = generator.quote_(block.getFieldValue('COLOUR'));
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
Blockly.defineBlocksWithJsonArray([
{
type: 'coupycolor_picker',
message0: 'クーピー30色: %1',
"output": "Colour",
"tooltip": "サクラクーピーペンシル30色のカラーチャートによる",
"helpUrl": "https://www.craypas.co.jp/products/painting-school/013/0031/182945.html#color-chart",
"style": "colour_blocks",
args0: [
{
type: 'field_colour',
name: 'COLOUR',
colour: '#E281A0',
colourOptions: [
'#F5ED68',
'#F6E92B',
'#EEB818',
'#EA9D13',
'#F2C198',
'#FBF5C5',
'#7E422A',
'#B8591F',
'#CD9711',
'#4F371D',
'#D83A2F',
'#D61242',
'#E281A0',
'#A41759',
'#E0BED6',
'#1D2973',
'#1794CE',
'#0FA275',
'#8ABC29',
'#0C834D',
'#0C834D',
'#0A68AE',
'#096CB0',
'#0F3460',
'#9CA5A4',
'#277565',
'#3F3939',
'#FFFFFF',
'#AE901E',
'#A5AEB3',
],
colourTitles: [
'レモンいろ',
'きいろ',
'やまぶきいろ',
'だいだいいろ',
'うすだいだい',
'たまごいろ',
'ちゃいろ',
'あかちゃいろ',
'おうどいろ',
'こげちゃいろ',
'しゅいろ',
'あか',
'ももいろ',
'あかむらさき',
'うすむらさき',
'むらさき',
'みずいろ',
'エメラルドいろ',
'きみどり',
'みどり',
'ふかみどり',
'あお',
'ぐんじょういろ',
'あいいろ',
'ねずみいろ',
'はいみどり',
'くろ',
'しろ',
'きんいろ',
'ぎんいろ',
],
columns: 5,
},
],
},
]);
javascript.javascriptGenerator.forBlock['coupycolor_picker'] = function (block, generator) {
const code = generator.quote_(block.getFieldValue('COLOUR'));
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
/** Additional Basic Blocks********************************************************************************* */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_text_to_number",
"message0": "%1 を整数に変換",
"args0": [
{
"type": "input_value",
"name": "text",
"check": "String"
}
],
"inputsInline": true,
"output": null,
"tooltip": "数字のテキストを整数に変換します。数字以外の文字が含まれているとエラーになります。",
"helpUrl": "",
"style": "math_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_text_to_number'] = function (block, generator) {
var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC);
var code = `Number(${value_text})`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
python.pythonGenerator.forBlock['oc_text_to_number'] = function (block, generator) {
var value_text = Blockly.Python.valueToCode(block, 'text', Blockly.Python.ORDER_ATOMIC);
var code = `int(${value_text})`;
return [code, Blockly.Python.ORDER_NONE];
};
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_codechar'] = function (block, generator) {
var value_code = Blockly.JavaScript.valueToCode(block, 'code', Blockly.JavaScript.ORDER_ATOMIC);
var code = `String.fromCharCode(${value_code})`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
python.pythonGenerator.forBlock['ugj_codechar'] = function (block, generator) {
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_charcode'] = function (block, generator) {
var value_char = Blockly.JavaScript.valueToCode(block, 'char', Blockly.JavaScript.ORDER_ATOMIC);
var code = `${value_char}.charCodeAt(0)`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
python.pythonGenerator.forBlock['ugj_charcode'] = function (block, generator) {
var value_char = Blockly.Python.valueToCode(block, 'char', Blockly.Python.ORDER_ATOMIC);
var code = `ord(${value_char})`;
return [code, Blockly.Python.ORDER_NONE];
};
Blockly.Blocks['ugj_bintodec'] = {
init: function () {
this.appendValueInput("bin")
.setCheck("String")
.appendField("0b");
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setTooltip("進数を10進数に変換します");
this.setHelpUrl("");
this.setStyle('math_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_bintodec'] = function (block, generator) {
var value_bin = Blockly.JavaScript.valueToCode(block, 'bin', Blockly.JavaScript.ORDER_ATOMIC);
var code = `parseInt (${value_bin}, 2)`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
python.pythonGenerator.forBlock['ugj_bintodec'] = function (block, generator) {
var value_bin = Blockly.Python.valueToCode(block, 'bin', Blockly.Python.ORDER_ATOMIC);
var code = `int(${value_bin}, 2)`;
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_hextodec'] = function (block, generator) {
var value_hex = Blockly.JavaScript.valueToCode(block, 'hex', Blockly.JavaScript.ORDER_ATOMIC);
var code = `parseInt (${value_hex}, 16)`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
python.pythonGenerator.forBlock['ugj_hextodec'] = function (block, generator) {
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_dectohex'] = function (block, generator) {
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];
};
python.pythonGenerator.forBlock['ugj_dectohex'] = function (block, generator) {
var value_dec = Blockly.Python.valueToCode(block, 'dec', Blockly.Python.ORDER_ATOMIC);
var code = `f'{${value_dec}:#04x}'`;
return [code, Blockly.Python.ORDER_NONE];
};
/** GPIO *****************************************************************************************************/
/** GPIO 関連共通コード */
// var require_gpio = [`const _rg = require('${apptool.gpio_lib}');`,
// `await _rg.rgpio_sbc();`];
/**************************** */
/** GPIO Breakout Board Table */
/**************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_breakout",
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "gpio",
"options": apptool.breakout_table[1]
}
],
"output": "Number",
"tooltip": apptool.breakout_table[0],
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_breakout'] = function (block, generator) {
var dropdown_gpio = block.getFieldValue('gpio');
var code = dropdown_gpio;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
/************ */
/** GPIO Open */
/************ */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_gpio_open",
"message0": "%{BKY_GPIO_OPEN_TITLE}",
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIO_OPEN_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
}]);
// javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator, generator) {
javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
Blockly.JavaScript.provideFunction_(
'require_gpio', [`const _rg = require('${apptool.gpio_lib}');`]
);
if (apptool.rghost === undefined)
var code = `await _rg.rgpio_sbc();\n`; //
else
var code = `await _rg.rgpio_sbc(host="${apptool.rghost}");\n`;
return code;
};
python.pythonGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
Blockly.Python.provideFunction_(
'import_pin', ['from machine import Pin']
);
var code = `_pin = {}\n`; //
return code;
};
/******************* */
/** Remote GPIO Open */
/******************* */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_gpio_open_remote",
"message0": "リモートホスト %1 の GPIO を使えるようにする",
"args0": [
{
"type": "input_value",
"name": "host",
"check": "String"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"style": "gpio_blocks",
"tooltip": "",
"helpUrl": ""
}]);
javascript.javascriptGenerator.forBlock['oc_gpio_open_remote'] = function (block, generator) {
var value_host = generator.valueToCode(block, 'host', javascript.Order.ATOMIC);
Blockly.JavaScript.provideFunction_(
'require_gpio', [`const _rg = require('${apptool.gpio_lib}');`]
);
var code = `await _rg.rgpio_sbc(host=${value_host});\n`; //
return code;
};
/************* */
/** GPIO Close */
/************* */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_gpio_close",
"message0": "%{BKY_GPIO_CLOSE_TITLE}",
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIO_CLOSE_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_gpio_close'] = function (block, generator) {
var code = 'await _rg.sbc_stop();\n';
return code;
};
python.pythonGenerator.forBlock['ugj_gpio_close'] = function (block, generator) {
var code = '';
return code;
};
/*********************** */
/** GPIO Set Output ** */
/*********************** */
var ugjGpioSetOutputDefinition = {
"type": "oc_gpio_set_output",
"message0": "GPIO %1 を出力モードにする",
"args0": [
{
"type": "input_value",
"name": "ugpio",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"tooltip": "GPIO を出力モードに設定します。",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['oc_gpio_set_output'] = {
init: function () {
this.jsonInit(ugjGpioSetOutputDefinition);
}
};
javascript.javascriptGenerator.forBlock['oc_gpio_set_output'] = function (block, generator) {
var value_ugpio = Blockly.JavaScript.valueToCode(block, 'ugpio', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.gpio_set_output(${value_ugpio});\n`;
return code;
};
python.pythonGenerator.forBlock['oc_gpio_set_output'] = function (block, generator) {
var value_ugpio = Blockly.Python.valueToCode(block, 'ugpio', Blockly.Python.ORDER_ATOMIC);
var code = `_pin[${value_ugpio}] = Pin(${value_ugpio}, Pin.OUT)\n`;
return code;
};
/********************** */
/** GPIO Set Input ** */
/********************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_gpio_set_input",
"message0": "GPIO %1 を入力モードにして %2",
"args0": [
{
"type": "input_value",
"name": "ugpio",
"check": "Number"
},
{
"type": "field_dropdown",
"name": "lflag",
"options": [
[
"プルしない",
"SET_PULL_NONE"
],
[
"プルアップ",
"SET_PULL_UP"
],
[
"プルダウン",
"SET_PULL_DOWN"
]
]
}
],
"previousStatement": null,
"nextStatement": null,
"tooltip": "GPIO を入力モードに設定します。Raspberry Pi では内蔵プルアップ/ダウンの設定が可能です。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_gpio_set_input'] = function (block, generator) {
var value_ugpio = Blockly.JavaScript.valueToCode(block, 'ugpio', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_lflag = block.getFieldValue('lflag');
var code = `await _rg.gpio_set_input(${value_ugpio}, _rg.${dropdown_lflag});\n`;
return code;
};
python.pythonGenerator.forBlock['oc_gpio_set_input'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'ugpio', Blockly.Python.ORDER_ATOMIC);
var dropdown_lflag = block.getFieldValue('lflag');
let lflag;
if (dropdown_lflag == 'SET_PULL_NONE') { lflag = 'None'; }
else { lflag = `Pin.${dropdown_lflag}`; }
var code = `_pin[${value_gpio}] = Pin(${value_gpio}, Pin.IN, ${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);
}
};
javascript.javascriptGenerator.forBlock['ugj_gpio_read'] = function (block, generator) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.gpio_read(${value_gpio})`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
python.pythonGenerator.forBlock['ugj_gpio_read'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var code = `_pin[${value_gpio}].value()`;
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"
},
{
"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);
}
};
javascript.javascriptGenerator.forBlock['ugj_gpio_write'] = function (block, generator) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_level = block.getFieldValue('level');
var code = `await _rg.gpio_write(${value_gpio}, ${dropdown_level});\n`;
return code;
};
python.pythonGenerator.forBlock['ugj_gpio_write'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var dropdown_level = block.getFieldValue('level');
var code = `_pin[${value_gpio}].value(${dropdown_level})\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"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_PWM_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_pwm'] = {
init: function () {
this.jsonInit(ugjPwmDefinition);
}
};
// javascript.javascriptGenerator.forBlock['ugj_pwm'] = function (block, generator) {
// 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 _rg.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
// return code;
// };
python.pythonGenerator.forBlock['ugj_pwm'] = function (block, generator) {
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);
Blockly.Python.provideFunction_(
'import_pwm', ['from machine import PWM']
);
var code = `_pin[${value_gpio}] = PWM(Pin(${value_gpio}))
_pin[${value_gpio}].freq(${value_pwm_frequency})
`;
// var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
return code;
};
Blockly.Blocks['oc_pwm_duty'] = {
init: function () {
this.appendValueInput("gpio")
.setCheck("Number")
.appendField("GPIO");
this.appendValueInput("duty")
.setCheck("Number")
.appendField("へデューティ値");
this.appendDummyInput()
.appendField("でパルスを出力");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("[RP2] PWM出力に設定したGPIOへパルスを出力します。デューティ値は 0(0%) 65535(100%) の範囲で指定します。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
python.pythonGenerator.forBlock['oc_pwm_duty'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var value_duty = Blockly.Python.valueToCode(block, 'duty', Blockly.Python.ORDER_ATOMIC);
var code = `_pin[${value_gpio}].duty_u16(${value_duty})\n`;
return code;
};
/********************** */
/** Open Serial Port ** */
/********************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_serial_open",
"message0": "ポート %1 のシリアルデバイスを %2 として速度 %3 で開く",
"args0": [
{
"type": "input_value",
"name": "port",
"check": "String"
},
{
"type": "field_variable",
"name": "ser_hand",
"variable": "シリアルデバイス"
},
{
"type": "field_dropdown",
"name": "baud",
"options": [
[
"9600bps",
"9600"
],
[
"19200bps",
"19200"
],
[
"115200bps",
"115200"
]
]
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "シリアルデバイスに名前をつけて開きます。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_serial_open'] = function (block, generator) {
var value_port = Blockly.JavaScript.valueToCode(block, 'port', Blockly.JavaScript.ORDER_ATOMIC);
var variable_ser_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('ser_hand'), Blockly.Names.NameType.VARIABLE);
var dropdown_baud = block.getFieldValue('baud');
var code = `${variable_ser_hand} = await _rg.serial_open(${value_port}, ${dropdown_baud});\nconsole.log(${variable_ser_hand});\n`;
return code;
};
/*********************** */
/** Close Serial Port ** */
/*********************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_serial_close",
"message0": "%1 を閉じる",
"args0": [
{
"type": "field_variable",
"name": "ser_hand",
"variable": "シリアルデバイス"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "シリアルデバイスとの通信を切断します。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_serial_close'] = function (block, generator) {
var variable_ser_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('ser_hand'), Blockly.Names.NameType.VARIABLE);
var code = `await _rg.serial_close(${variable_ser_hand});\n`;
return code;
};
/************************ */
/** Read Data from Serial */
/************************ */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_serial_read",
"message0": "%1 %2 から %3 文字受け取る",
"args0": [
{
"type": "field_variable",
"name": "ser_hand",
"variable": "シリアルデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "count",
"check": "Number"
}
],
"inputsInline": true,
"output": null,
"tooltip": "シリアルデバイスから指定したバイト数のデータを受け取ります。0を指定すると受信可能な全てのデータを取得します。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_serial_read'] = function (block, generator) {
var variable_ser_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('ser_hand'), Blockly.Names.NameType.VARIABLE);
var value_count = Blockly.JavaScript.valueToCode(block, 'count', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.serial_read(${variable_ser_hand}, ${value_count})`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
/************************** */
/** Write Data to Serial ** */
/************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_serial_write",
"message0": "%1 %2 に %3 を送信する",
"args0": [
{
"type": "field_variable",
"name": "ser_hand",
"variable": "シリアルデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "data",
"check": "String"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "シリアルデバイスにデータを送信します。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_serial_write'] = function (block, generator) {
var variable_ser_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('ser_hand'), Blockly.Names.NameType.VARIABLE);
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var code = `await _rg.serial_write(${variable_ser_hand}, ${value_data});\n`;
return code;
};
/******************************************************************* */
/** Returns the number of bytes available to be read from the device */
/******************************************************************* */
/********************* */
/** Open I2C Device ** */
/********************* */
Blockly.Blocks['oc_i2c_open'] = {
init: function () {
this.appendValueInput("addr")
.setCheck("Number")
.appendField("アドレス");
this.appendDummyInput()
.appendField("の I2C デバイスを")
.appendField(new Blockly.FieldVariable("I2Cデバイス"), "i2c_hand")
.appendField("として開く");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("I2C接続されたデバイスに名前をつけて通信を開始します。");
this.setHelpUrl("");
this.setStyle("gpio_blocks");
}
};
javascript.javascriptGenerator.forBlock['oc_i2c_open'] = function (block, generator) {
var value_addr = Blockly.JavaScript.valueToCode(block, 'addr', Blockly.JavaScript.ORDER_ATOMIC);
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
// Blockly.JavaScript.provideFunction_(
// 'require_gpio', require_gpio
// );
var code = `${variable_i2c_hand} = await _rg.i2c_open(${apptool.i2c_bus}, ${value_addr});\n`;
return code;
};
python.pythonGenerator.forBlock['oc_i2c_open'] = function (block, generator) {
var value_addr = Blockly.Python.valueToCode(block, 'addr', Blockly.Python.ORDER_ATOMIC);
var variable_i2c_hand = Blockly.Python.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
Blockly.Python.provideFunction_(
'import_i2c', ['from machine import I2C']
);
var code = `_addr = ${value_addr}
${variable_i2c_hand} = I2C(0,sda=Pin(0),scl=Pin(1))\n`;
return code;
};
/********************** */
/** Close I2C Device ** */
/********************** */
Blockly.Blocks['oc_i2c_close'] = {
init: function () {
this.appendDummyInput()
// .appendField("I2C デバイス")
.appendField(new Blockly.FieldVariable("I2Cデバイス"), "i2c_hand")
.appendField("を閉じる");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("指定した I2C デバイスとの通信を切断します。");
this.setHelpUrl("");
this.setStyle("gpio_blocks");
}
};
javascript.javascriptGenerator.forBlock['oc_i2c_close'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var code = `await _rg.i2c_close(${variable_i2c_hand});\n`;
return code;
};
python.pythonGenerator.forBlock['oc_i2c_close'] = function (block, generator) {
var code = ``;
return code;
};
/*************************************** */
/** Sends a single byte to the device ** */
/*************************************** */
Blockly.Blocks['oc_i2c_write_byte'] = {
init: function () {
this.appendDummyInput()
// .appendField("I2C デバイス")
.appendField(new Blockly.FieldVariable("I2Cデバイス"), "i2c_hand")
this.appendValueInput("byte_val")
.setCheck("Number")
.appendField("に1バイトデータ");
this.appendDummyInput()
.appendField("を送信");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("指定の I2C デバイスにバイトデータを送信します。0-0xFF(255)の範囲の数字で入力してください。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
javascript.javascriptGenerator.forBlock['oc_i2c_write_byte'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var value_byte_val = Blockly.JavaScript.valueToCode(block, 'byte_val', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.i2c_write_byte(${variable_i2c_hand}, ${value_byte_val});\n`;
return code;
};
/****************************************************************** */
/** Writes a single byte to the specified register of the device ** */
/****************************************************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_i2c_write_byte_data",
"message0": "%1 %2 のレジスタ %3 に %4 を書き込む",
"args0": [
{
"type": "field_variable",
"name": "i2c_hand",
"variable": "I2Cデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "reg",
"check": "Number"
},
{
"type": "input_value",
"name": "byte_val",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "I2C デバイスの指定されたレジスタに1バイトを書き込みます。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_i2c_write_byte_data'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
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 _rg.i2c_write_byte_data(${variable_i2c_hand}, ${value_reg}, ${value_byte_val});\n`;
return code;
};
python.pythonGenerator.forBlock['ugj_i2c_write_byte_data'] = function (block, generator) {
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 = `_i2c_hand.writeto_mem(_addr, ${value_reg}, (${value_byte_val}).to_bytes(1,'big'))\n`;
return code;
};
/****************************************************************** */
/** Read a single byte from the specified resister of the device ** */
/****************************************************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_i2c_read_byte_data",
"message0": "%1 %2 のレジスタ %3 の値",
"args0": [
{
"type": "field_variable",
"name": "i2c_hand",
"variable": "I2Cデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "reg",
"check": "Number"
}
],
"inputsInline": true,
"output": null,
"tooltip": "I2C デバイスの指定されたレジスタから1バイトを読み込みます。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_i2c_read_byte_data'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.i2c_read_byte_data(${variable_i2c_hand}, ${value_reg})`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
python.pythonGenerator.forBlock['ugj_i2c_read_byte_data'] = function (block, generator) {
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
var code = `int.from_bytes(_i2c_hand.readfrom_mem(_addr, ${value_reg}, 1), 'big')\n`;
return [code, Blockly.Python.ORDER_ATOMIC];
};
/************************************************************************ */
/** Reads a single 16 bit word from the specified register of the device. */
/************************************************************************ */
Blockly.Blocks['ugj_i2c_read_word_data'] = {
init: function () {
this.appendDummyInput()
.appendField(new Blockly.FieldVariable("I2Cデバイス"), "i2c_hand")
this.appendValueInput("reg")
.setCheck("Number")
.appendField("レジスタ");
this.appendDummyInput()
.appendField("のワード値");
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setStyle('gpio_blocks');
this.setTooltip("デバイスの指定レジスタからワードデータを読み出します。");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['ugj_i2c_read_word_data'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var value_reg = Blockly.JavaScript.valueToCode(block, 'reg', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.i2c_read_word_data(${variable_i2c_hand}, ${value_reg})`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
/***************************************************************** */
/** Writes up to 32 bytes to the specified register of the device. */
/***************************************************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_i2c_write_i2c_block_data",
"message0": "%1 %2 のレジスタ %3 に %4 を書き込む",
"args0": [
{
"type": "field_variable",
"name": "i2c_hand",
"variable": "I2Cデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "reg",
"check": "Number"
},
{
"type": "input_value",
"name": "data",
"check": "String"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "I2C デバイスの指定されたレジスタに最大32バイトのテキストデータを書き込みます。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_i2c_write_i2c_block_data'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
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 _rg.i2c_write_i2c_block_data (${variable_i2c_hand}, ${value_reg}, ${value_data});`;
return code;
};
python.pythonGenerator.forBlock['ugj_i2c_write_i2c_block_data'] = function (block, generator) {
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
var value_data = Blockly.Python.valueToCode(block, 'data', Blockly.Python.ORDER_ATOMIC);
var code = `_i2c_hand.writeto_mem(_addr, ${value_reg}, bytearray(${value_data}))\n`;
return code;
};
/************************************************************************** */
/** Returns count bytes read from the raw device associated with handle. ** */
/************************************************************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_i2c_read_device",
"message0": "%1 %2 から %3 文字受け取る",
"args0": [
{
"type": "field_variable",
"name": "i2c_hand",
"variable": "I2Cデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "count",
"check": "Number"
}
],
"inputsInline": true,
"output": null,
"tooltip": "I2C デバイスから指定したバイト数のデータを受け取ります。データが指定の長さより短いこともあります。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_i2c_read_device'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var value_count = Blockly.JavaScript.valueToCode(block, 'count', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.i2c_read_device(${variable_i2c_hand}, ${value_count})`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
// python.pythonGenerator.forBlock['ugj_i2c_read_device'] = function (block, generator) {
// 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. ** */
/********************************************** */
Blockly.defineBlocksWithJsonArray([{
"type": "ugj_i2c_write_device",
"message0": "%1 %2 に %3 を送信",
"args0": [
{
"type": "field_variable",
"name": "i2c_hand",
"variable": "I2Cデバイス"
},
{
"type": "input_dummy"
},
{
"type": "input_value",
"name": "data",
"check": "String"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "I2C デバイスにデータを送信します。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
javascript.javascriptGenerator.forBlock['ugj_i2c_write_device'] = function (block, generator) {
var variable_i2c_hand = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('i2c_hand'), Blockly.Names.NameType.VARIABLE);
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.i2c_write_device(${variable_i2c_hand}, ${value_data})\n`;
return code;
};
// python.pythonGenerator.forBlock['ugj_i2c_write_device'] = function (block, generator) {
// 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;
// };
/** Multimedia *****************************************************************************************************/
/******************** */
/** Face Detection ** */
/******************** */
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("Blazeface detector モデルによる顔検出を開始します。最初に実行してください");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['ugj_face_init'] = function (block, generator) {
Blockly.JavaScript.provideFunction_(
'require_tfjs', [`const _tf = require('@tensorflow/tfjs-node');`]
);
Blockly.JavaScript.provideFunction_(
'require_blazeface', [`const _blazeface = require('@tensorflow-models/blazeface');`]
);
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;",
`const _model = await _blazeface.load();`,
""
].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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_face_display'] = function (block, generator) {
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);`,
`const _overlay_ctx = _overlay.getContext('2d');`,
""
].join('\n');
return code;
};
Blockly.Blocks['ugj_face_detect'] = {
init: function () {
this.appendValueInput("preditions")
.setCheck("Variable")
.appendField("顔検出を実行し、結果をリスト");
this.appendDummyInput()
.appendField("に代入する");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("顔検出を実行します。検出結果はリストになります。顔の位置は「顔の座標」ブロックで参照します。");
this.setHelpUrl("");
this.setStyle('multimedia_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_face_detect'] = function (block, generator) {
var value_preditions = Blockly.JavaScript.valueToCode(block, 'preditions', Blockly.JavaScript.ORDER_ATOMIC);
var code = `${value_preditions} = await _model.estimateFaces(_videoEl, false);`;
return code;
};
Blockly.Blocks['ugj_face_location'] = {
init: function () {
this.appendValueInput("prediction")
.setCheck("Array")
.appendField("顔");
this.appendDummyInput()
.appendField("の")
.appendField(new Blockly.FieldDropdown([["左座標", "topLeft[0]"], ["上座標", "topLeft[1]"], ["右座標", "bottomRight[0]"], ["下座標", "bottomRight[1]"]]), "member");
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setTooltip("顔検出結果の座標を参照します。");
this.setHelpUrl("");
this.setStyle('multimedia_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_face_location'] = function (block, generator) {
var value_prediction = Blockly.JavaScript.valueToCode(block, 'prediction', Blockly.JavaScript.ORDER_NONE);
var dropdown_member = block.getFieldValue('member');
var code = `${value_prediction}.${dropdown_member}`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
Blockly.Blocks['ugj_face_draw'] = {
init: function () {
this.appendValueInput("prediction")
.setCheck("Variable")
.appendField("顔");
this.appendDummyInput()
.appendField("を描画:")
.appendField(new Blockly.FieldCheckbox("TRUE"), "with_landmark")
.appendField("ランドマーク");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("顔検出結果をビデオ画面に描画します。「ビデオを表示」ブロックが必要です。");
this.setHelpUrl("");
this.setStyle('multimedia_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_face_draw'] = function (block, generator) {
var value_prediction = Blockly.JavaScript.valueToCode(block, 'prediction', Blockly.JavaScript.ORDER_NONE);
var checkbox_with_landmark = block.getFieldValue('with_landmark') === 'TRUE';
var code = `const _start = ${value_prediction}.topLeft;
const _end = ${value_prediction}.bottomRight;
const _size = [_end[0] - _start[0], _end[1] - _start[1]];
_overlay_ctx.clearRect(0, 0, _displaySize.width, _displaySize.height)
_overlay_ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
_overlay_ctx.fillRect(_start[0], _start[1], _size[0], _size[1]);
if (${checkbox_with_landmark}) {
const _landmarks = ${value_prediction}.landmarks;
_overlay_ctx.fillStyle = 'blue';
for (let _j = 0; _j < _landmarks.length; _j++) {
const _x = _landmarks[_j][0];
const _y = _landmarks[_j][1];
_overlay_ctx.fillRect(_x, _y, 5, 5);
}
}
`;
return code;
};
/******************************* */
/** Speech Commands Recognizer * */
/******************************* */
Blockly.Blocks['oc_speechcommands_init'] = {
init: function () {
this.appendDummyInput()
.appendField("音声コマンド認識を開始");
this.appendValueInput("custom_model")
.setCheck("String")
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("カスタムモデル");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField(new Blockly.FieldVariable("ラベル"), "classlabels")
.appendField("を取得");
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("Tensorflow 音声コマンド認識モデルを初期化します。Google Teachable Machine で作成したカスタムモデルのフォルダパスを指定します。モデルに含まれるラベルのリストを取得し変数に代入します。");
this.setHelpUrl("");
this.setStyle('multimedia_blocks');
}
};
javascript.javascriptGenerator.forBlock['oc_speechcommands_init'] = function (block, generator) {
var value_custom_model = Blockly.JavaScript.valueToCode(block, 'custom_model', Blockly.JavaScript.ORDER_NONE);
var variable_classlabels = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('classlabels'), Blockly.Names.NameType.VARIABLE);
Blockly.JavaScript.provideFunction_(
'require_tfjs', [`const _tf = require('@tensorflow/tfjs-node');`]
);
Blockly.JavaScript.provideFunction_(
'require_speechcommands', [`const _speechcommands = require('@tensorflow-models/speech-commands');`]
);
// Check empty
let cp = undefined, md = undefined;
if (value_custom_model != "''") {
let cm = value_custom_model.replace(/(^'|'$)/g, '');
cp = `'file://${apptool.path.join(cm, 'model.json')}'`;
md = `'file://${apptool.path.join(cm, 'metadata.json')}'`;
}
var code = `const _checkpointURL = ${cp};
const _metadataURL = ${md};
const _recognizer = _speechcommands.create(
"BROWSER_FFT",
undefined,
_checkpointURL,
_metadataURL);
await _recognizer.ensureModelLoaded();
${variable_classlabels} = _recognizer.wordLabels();
`;
return code;
};
Blockly.Blocks['oc_speechcommand_listen'] = {
init: function () {
this.appendDummyInput()
.appendField("音声コマンドを認識したら");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField(new Blockly.FieldVariable("スコア"), "scores")
.appendField("を取得");
this.appendStatementInput("do")
.setCheck(null);
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("オーバーラップ係数")
.appendField(new FieldSlider(0.5, 0, 1, 0.05), "overlapFactor");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("スコアしきい値")
.appendField(new FieldSlider(0.75, 0, 1, 0.05), "probabilityThreshold");
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("音声コマンドを認識するとステートメントを実行します。「スコア」は「ラベル」に対応するリストです。");
this.setHelpUrl("");
this.setStyle('multimedia_blocks');
}
};
javascript.javascriptGenerator.forBlock['oc_speechcommand_listen'] = function (block, generator) {
var variable_scores = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('scores'), Blockly.Names.NameType.VARIABLE);
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
var number_probabilitythreshold = block.getFieldValue('probabilityThreshold');
var number_overlapfactor = block.getFieldValue('overlapFactor');
var code = `_recognizer.listen(_result => {
${variable_scores} = _result.scores;
${statements_do}
}, {
overlapFactor: ${number_overlapfactor},
probabilityThreshold: ${number_probabilitythreshold}
});
`;
return code;
};
/**************************** */
/** Say while some seconds ** */
/**************************** */
Blockly.Blocks['ugj_canvas_say'] = {
init: function () {
this.appendValueInput("say")
.setCheck(null);
this.appendDummyInput()
.appendField("と")
.appendField(new FieldSlider(2, 0, 30, 1), "sec")
.appendField("秒言う");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('multimedia_blocks')
this.setTooltip("キャンバスにフキダシを作ります。");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_say'] = function (block, generator) {
var value_say = Blockly.JavaScript.valueToCode(block, 'say', Blockly.JavaScript.ORDER_ATOMIC);
var value_sec = block.getFieldValue('sec');
var code = [
`_fukidashi(String(${value_say}), ${value_sec});`,
''
].join('\n');
return code;
};
python.pythonGenerator.forBlock['ugj_canvas_say'] = function (block, generator) {
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_init'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_finalize'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_loadimg'] = function (block, generator) {
var value_imgfilename = Blockly.JavaScript.valueToCode(block, 'imgfilename', Blockly.JavaScript.ORDER_ATOMIC);
var code = [
`let _img = new Image();`,
`_img.src = '${apptool.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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_clearrect'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_width'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_height'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_drawcircle'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_canvas_drawrect'] = function (block, generator) {
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;
};
/****************************** */
/** 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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
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');
}
};
javascript.javascriptGenerator.forBlock['ugj_event_key'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_sound_play'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_socket'] = function (block, generator) {
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.Names.NameType.VARIABLE);
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_socket_write'] = function (block, generator) {
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')
}
};
javascript.javascriptGenerator.forBlock['ugj_network_httpserver'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_network_axios_geturl'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_network_sendmail'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_library_skyway'] = function (block, generator) {
var code = `'${apptool.path.join(apptool.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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_webchat'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_getusermedia'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("サーバーにIDを登録して、相手先呼び出しの準備をします。");
this.setHelpUrl("");
this.setStyle('network_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_newpeer'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_called'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("チャットの相手との接続後の動作を定義します。");
this.setHelpUrl("");
this.setStyle('network_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_events'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('network_blocks')
this.setTooltip("チャット相手との接続が確立したときの動作を決めます。");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_eventopen'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("チャット相手の発言を受信したときの動作です。");
this.setHelpUrl("");
this.setStyle('network_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_eventdata'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("入力フィールドで送信が発生したときの動作を決めます。");
this.setHelpUrl("");
this.setStyle('network_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_skyway_eventsend'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_file_readsync'] = function (block, generator) {
var value_filename = Blockly.JavaScript.valueToCode(block, 'filename', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_encoding = block.getFieldValue('encoding');
let filepath = apptool.path.join(apptool.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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_localstorage_save'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_localstorage_load'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_localstorage_remove'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("質問をして答えを待ちます。入力欄でキーボードのエンターキーが入力されるか、チェックマークボタンが押されると実行されます。");
this.setHelpUrl("");
this.setStyle('special_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_event_answer'] = function (block, generator) {
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 = [
`_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("外部プログラムを実行して子プロセスを生成し、子プロセスが終了するまで待ちます。タイムアウトは10秒です。");
this.setHelpUrl("");
this.setStyle('special_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_spawnsync'] = function (block, generator) {
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 code = `${value_data} = require('child_process').spawnSync(${value_childprocess}, {timeout: 10000}).stdout.toString();\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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("外部プログラムを実行して子プロセスを生成します。データを受け取る毎にステートメントが実行されます。");
this.setHelpUrl("");
this.setStyle('special_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_spawn'] = function (block, generator) {
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 statements_do = Blockly.JavaScript.statementToCode(block, 'do');
var code = [
`let _child = require('child_process').spawn(${value_childprocess});`,
"_child.stderr.on('data', _data => { console.error(_data.toString()) })",
"_child.stdout.on('data', async _data => {",
`${value_data} = _data.toString();`,
statements_do,
"})",
`window.addEventListener( 'beforeunload', () => _child.kill(), false );`,
''
].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("");
}
};
javascript.javascriptGenerator.forBlock['aquestalk_pi'] = function (block, generator) {
var value_talk = Blockly.JavaScript.valueToCode(block, 'talk', Blockly.JavaScript.ORDER_ATOMIC);
var code = `'${apptool.path.join(apptool.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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_child_fswebcam'] = function (block, generator) {
var value_filename = Blockly.JavaScript.valueToCode(block, 'filename', Blockly.JavaScript.ORDER_ATOMIC);
var code = `'fswebcam', ['-r', '480x360', '${apptool.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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_child_julius'] = function (block, generator) {
var code = `'${apptool.path.join(apptool.executable_path, 'julius/julius-simple')}', ['-C', '${apptool.path.join(apptool.executable_path, 'julius/dictation-kit/am-gmm.jconf')}', '-gram', '${apptool.path.join(apptool.executable_path, 'julius/dic/assistant')}', '-nostrip']`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
// Python スクリプト
Blockly.Blocks['ugj_child_pyscript'] = {
init: function () {
this.appendValueInput("script_path")
.setCheck("String")
.appendField("Pythonスクリプト :");
this.setInputsInline(true);
this.setOutput(true, "shcmd");
this.setTooltip("Pythonスクリプトファイル名");
this.setHelpUrl("");
this.setStyle('special_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_child_pyscript'] = function (block, generator) {
var value_script_path = Blockly.JavaScript.valueToCode(block, 'script_path', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var code = `'python3', ['${apptool.doc_root}/' + ${value_script_path}]`;
// 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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_blackboard_show'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_blackboard_write'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_clearblackboard'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_blackboard_content'] = function (block, generator) {
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);
}
};
javascript.javascriptGenerator.forBlock['ugj_sleep'] = function (block, generator) {
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;
};
python.pythonGenerator.forBlock['ugj_sleep'] = function (block, generator) {
var value_sec = Blockly.Python.valueToCode(block, 'sec', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_sleep', ['from utime import sleep']
)
var code = `sleep(${value_sec})\n`;
return code;
};
/**************** */
/** Async IIFE ** */
/**************** */
Blockly.Blocks['ugj_async_iife'] = {
init: function () {
this.appendDummyInput()
.appendField("非同期で実行");
this.appendStatementInput("do")
.setCheck(null);
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("Async▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("ステートメントを非同期で実行します。即時関数を生成するのでスコープに注意。");
this.setHelpUrl("");
this.setStyle('special_blocks');
}
};
javascript.javascriptGenerator.forBlock['ugj_async_iife'] = function (block, generator) {
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
var code = `(async () => {
${statements_do}
})();
`;
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_text_cr'] = function (block, generator) {
var code = "'\\r'";
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
python.pythonGenerator.forBlock['ugj_text_cr'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_text_lf'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_text_null'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_text_cursor'] = function (block, generator) {
var code = "'&#9611;'";
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
/**************************** */
/** 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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_library_load'] = function (block, generator) {
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.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("▼");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("ディスプレイカラムにボタンを作成し、クリックのイベントリスナを定義します。テキストデータをひとつ、\"title\"属性値として設定・取り出しが可能です。保存したデータはマウスオーバーで確認できます。");
this.setHelpUrl("");
this.setStyle('special_blocks')
}
};
javascript.javascriptGenerator.forBlock['ugj_control_button'] = function (block, generator) {
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;
};
/** ******** */
/** RP2 専用 */
/** ******** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_input",
"message0": "入力待ち",
"inputsInline": true,
"output": null,
"tooltip": "[RP2] 標準入力を待ちます。",
"helpUrl": "",
"style": "text_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_input'] = function (block, generator) {
Blockly.Python.provideFunction_(
'import_sys', ['import sys']
);
var code = 'sys.stdin.readline().replace("\\n","")';
return [code, Blockly.Python.ORDER_NONE];
};
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_print",
"message0": "%1 を終端文字なしで表示",
"args0": [
{
"type": "input_value",
"name": "text",
"check": "String"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "[RP2] テキストを表示します。終端文字(改行など)を追加しません。",
"helpUrl": "",
"style": "text_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_print'] = function (block, generator) {
var value_text = Blockly.Python.valueToCode(block, 'text', Blockly.Python.ORDER_ATOMIC);
var code = `print(${value_text}, end='')\n`;
return code;
};
/******************** */
/** UltraJSON Encoder */
/******************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ujson_dumps",
"message0": "オブジェクト %1 を JSON に変換",
"args0": [
{
"type": "input_value",
"name": "obj"
}
],
"output": null,
"tooltip": "変数や配列の内容を JSON 形式の文字列にエンコードします。",
"helpUrl": "",
"style": "rp2_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ujson_dumps'] = function (block, generator) {
var value_obj = Blockly.Python.valueToCode(block, 'obj', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_ujson', ['import ujson']
);
var code = `ujson.dumps(${value_obj})`;
return [code, Blockly.Python.ORDER_NONE];
};
/******************** */
/** UltraJSON Decoder */
/******************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ujson_loads",
"message0": "JSON %1 をオブジェクトに変換",
"args0": [
{
"type": "input_value",
"name": "json",
"check": "String"
}
],
"output": null,
"tooltip": "JSON 形式の文字列を元の変数や配列の内容にデコードします。",
"helpUrl": "",
"style": "rp2_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ujson_loads'] = function (block, generator) {
var value_json = Blockly.Python.valueToCode(block, 'json', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_ujson', ['import ujson']
);
var code = `ujson.loads(${value_json})`;
return [code, Blockly.Python.ORDER_NONE];
};
/****************** */
/** Setup IR Record */
/****************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ir_rx",
"message0": "GPIO %1 をリモコン信号受信ピンに設定する",
"args0": [
{
"type": "input_value",
"name": "gpio",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "",
"helpUrl": "",
"style": "gpio_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ir_rx'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_upyirrx', ['from UpyIrRx import UpyIrRx']
);
var code = `_rx = UpyIrRx(_pin[${value_gpio}])\n`;
return code;
};
/******************* */
/** Record IR Signal */
/******************* */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ir_record",
"message0": "リモコン信号を受信:待ち受け時間 %1 秒",
"args0": [
{
"type": "input_value",
"name": "timeout",
"check": "Number"
}
],
"inputsInline": true,
"output": null,
"tooltip": "",
"helpUrl": "",
"style": "gpio_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ir_record'] = function (block, generator) {
var value_timeout = Blockly.Python.valueToCode(block, 'timeout', Blockly.Python.ORDER_ATOMIC);
var functionName = Blockly.Python.provideFunction_(
'_rx_record',
[
`def ${Blockly.Python.FUNCTION_NAME_PLACEHOLDER_} (rx):`,
` rx.record(${value_timeout} * 1000)`,
` if rx.get_mode() == UpyIrRx.MODE_DONE_OK:`,
` signal_list = rx.get_calibrate_list()`,
` else:`,
` signal_list = []`,
` return signal_list`,
]
);
var code = `${functionName}(_rx)`;
return [code, Blockly.Python.ORDER_NONE];
};
/******************** */
/** Setup IR Transmit */
/******************** */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ir_tx",
"message0": "GPIO %1 をリモコン信号送信ピンに設定する",
"args0": [
{
"type": "input_value",
"name": "gpio"
}
],
"previousStatement": null,
"nextStatement": null,
"tooltip": "",
"helpUrl": "",
"style": "gpio_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ir_tx'] = function (block, generator) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_upyirtx', ['from UpyIrTx import UpyIrTx']
);
var code = `_tx = UpyIrTx(0, _pin[${value_gpio}])\n`;
return code;
};
/********************* */
/** Transmit IR Signal */
/********************* */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_rp2_ir_transmit",
"message0": "リモコン信号 %1 を送信",
"args0": [
{
"type": "input_value",
"name": "signal"
}
],
"previousStatement": null,
"nextStatement": null,
"tooltip": "リモコン信号を送信します。",
"helpUrl": "",
"style": "gpio_blocks"
}]);
python.pythonGenerator.forBlock['oc_rp2_ir_transmit'] = function (block, generator) {
var value_signal = Blockly.Python.valueToCode(block, 'signal', Blockly.Python.ORDER_ATOMIC);
var code = `_tx.send(${value_signal})\n`;
return code;
};
/************************ */
/** RP2 MicroPython Slave */
/************************ */
Blockly.Blocks['oc_i2cslave'] = {
init: function () {
this.appendValueInput("i2c_addr")
.setCheck("Number")
.appendField("RP2 スレーブI2Cアドレス");
this.appendDummyInput()
.appendField(new Blockly.FieldVariable("データ"), "data")
.appendField("を受け取ったら");
this.appendStatementInput("do")
.setCheck(null);
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setTooltip("Raspberry Pi Pico及びその互換機を I2Cスレーブ化します。受信データは1バイトデータです。i2c_slave.py が必要です。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
python.pythonGenerator.forBlock['oc_i2cslave'] = function (block, generator) {
var value_i2c_addr = Blockly.Python.valueToCode(block, 'i2c_addr', Blockly.Python.ORDER_ATOMIC);
var variable_data = Blockly.Python.nameDB_.getName(block.getFieldValue('data'), Blockly.Names.NameType.VARIABLE);
var statements_do = Blockly.Python.statementToCode(block, 'do');
Blockly.Python.provideFunction_(
'import_i2cslave', ['from i2cSlave import i2c_slave']
);
var code = `_i2cs = i2c_slave(0,sda=0,scl=1,slaveAddress=${value_i2c_addr})
while True:
${variable_data} = int(_i2cs.get())
${statements_do}
`;
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("");
}
};
javascript.javascriptGenerator.forBlock['ugj_dev_run_js'] = function (block, generator) {
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("");
}
};
javascript.javascriptGenerator.forBlock['testblock'] = function (block, generator) {
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;
};
/** 互換性 */
/** 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');
}
};
javascript.javascriptGenerator.forBlock['ugj_control_for'] = function (block, generator) {
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;
};
python.pythonGenerator.forBlock['ugj_control_for'] = function (block, generator) {
var value_index = Blockly.Python.valueToCode(block, 'index', Blockly.Python.ORDER_ATOMIC);
// 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 ${value_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');
}
};
javascript.javascriptGenerator.forBlock['ugj_controls_foreach'] = function (block, generator) {
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;
};
python.pythonGenerator.forBlock['ugj_controls_foreach'] = function (block, generator) {
var value_list = Blockly.Python.valueToCode(block, 'list', Blockly.Python.ORDER_ATOMIC);
var value_item = Blockly.Python.valueToCode(block, 'item', Blockly.Python.ORDER_ATOMIC);
var statements_do = Blockly.Python.statementToCode(block, 'do');
if (statements_do === '') statements_do = ' pass';
var code = [
`for ${value_item} in ${value_list}:`,
statements_do,
''
].join('\n');
return code;
};
// /******************/
// /** 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("");
// }
// };
// javascript.javascriptGenerator.forBlock['ugj_set_interval'] = function (block, generator) {
// 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("");
// }
// };
// javascript.javascriptGenerator.forBlock['ugj_special_clearinterval'] = function (block, generator) {
// 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("");
// }
// };
// javascript.javascriptGenerator.forBlock['ugj_set_timeout'] = function (block, generator) {
// 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;
// };
// 削除予定
/********************** */
/** 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);
}
};
javascript.javascriptGenerator.forBlock['ugj_serial_open'] = function (block, generator) {
// var value_tty = Blockly.JavaScript.valueToCode(block, 'tty', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_baud = block.getFieldValue('baud');
// Blockly.JavaScript.provideFunction_(
// 'require_gpio', require_gpio
// );
var code = `let _ser_hand = await _rg.serial_open('/dev/ttyACM0', ${dropdown_baud});\nconsole.log(_ser_hand);\n`;
// var code = `await _rg.serial_open('/dev/serial0', ${dropdown_baud});\n`;
return code;
};
// python.pythonGenerator.forBlock['ugj_serial_open'] = function (block, generator) {
// 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);
}
};
javascript.javascriptGenerator.forBlock['ugj_serial_close'] = function (block, generator) {
var code = 'await _rg.serial_close(_ser_hand);\n';
return code;
};
// python.pythonGenerator.forBlock['ugj_serial_close'] = function (block, generator) {
// 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);
}
};
javascript.javascriptGenerator.forBlock['ugj_serial_write'] = function (block, generator) {
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
var code = `let ret = await _rg.serial_write(_ser_hand, ${value_data});\nconsole.log(ret);\n`;
return code;
};
// python.pythonGenerator.forBlock['ugj_serial_write'] = function (block, generator) {
// 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);
}
};
javascript.javascriptGenerator.forBlock['ugj_serial_read'] = function (block, generator) {
var value_count = Blockly.JavaScript.valueToCode(block, 'count', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _rg.serial_read(_ser_hand, ${value_count})`;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
};
// python.pythonGenerator.forBlock['ugj_serial_read'] = function (block, generator) {
// 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];
// };