diff --git a/.vscode/settings.json b/.vscode/settings.json index de288e1..e2400d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,58 @@ { - "python.formatting.provider": "black" + "python.formatting.provider": "black", + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "set": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + }, + "C_Cpp.errorSquiggles": "Disabled" } \ No newline at end of file diff --git a/google-blockly/javascript_compressed.js b/google-blockly/javascript_compressed.js index 267d9eb..14c8456 100644 --- a/google-blockly/javascript_compressed.js +++ b/google-blockly/javascript_compressed.js @@ -83,8 +83,8 @@ Blockly.JavaScript.math_constrain=function(a){var b=Blockly.JavaScript.valueToCo Blockly.JavaScript.math_random_int=function(a){var b=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_NONE)||"0";a=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_NONE)||"0";return[Blockly.JavaScript.provideFunction_("mathRandomInt",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(a, b) {"," if (a > b) {"," // Swap a and b to ensure a is smaller."," var c = a;"," a = b;"," b = c;"," }"," return Math.floor(Math.random() * (b - a + 1) + a);", "}"])+"("+b+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_random_float=function(a){return["Math.random()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_atan2=function(a){var b=Blockly.JavaScript.valueToCode(a,"X",Blockly.JavaScript.ORDER_NONE)||"0";return["Math.atan2("+(Blockly.JavaScript.valueToCode(a,"Y",Blockly.JavaScript.ORDER_NONE)||"0")+", "+b+") / Math.PI * 180",Blockly.JavaScript.ORDER_DIVISION]};Blockly.JavaScript.procedures={}; Blockly.JavaScript.procedures_defreturn=function(a){var b=Blockly.JavaScript.nameDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c="";Blockly.JavaScript.STATEMENT_PREFIX&&(c+=Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX,a));Blockly.JavaScript.STATEMENT_SUFFIX&&(c+=Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX,a));c&&(c=Blockly.JavaScript.prefixLines(c,Blockly.JavaScript.INDENT));var d="";Blockly.JavaScript.INFINITE_LOOP_TRAP&&(d=Blockly.JavaScript.prefixLines(Blockly.JavaScript.injectId(Blockly.JavaScript.INFINITE_LOOP_TRAP, -a),Blockly.JavaScript.INDENT));var e=Blockly.JavaScript.statementToCode(a,"STACK"),f=Blockly.JavaScript.valueToCode(a,"RETURN",Blockly.JavaScript.ORDER_NONE)||"",g="";e&&f&&(g=c);f&&(f=Blockly.JavaScript.INDENT+"return "+f+";\n");for(var h=[],l=a.getVars(),k=0;k - - - + + + 5 @@ -335,7 +335,7 @@ 1 - + pi.SET_PULL_DOWN @@ -351,7 +351,7 @@ - + 5 @@ -368,7 +368,7 @@ - + 12 @@ -592,11 +592,6 @@ meow - - ことば - once - TRUE - FALSE @@ -610,17 +605,6 @@ 高さ - - - - - - - - - - 結果 - diff --git a/index.js b/index.js index 1c6a688..6cbf734 100644 --- a/index.js +++ b/index.js @@ -80,23 +80,23 @@ Blockly.Msg["UGJ_FOREACH_TITLE"] = "リスト %1 の各 %2 について %3 %4"; Blockly.Msg["UGJ_FOREACH_ITEM"] = "項目"; Blockly.Msg["UGJ_FOREACH_TOOLTIP"] = "リストの各項目について、その項目を変数「項目」としてステートメントを実行します。"; -Blockly.Msg["GPIOCHIP_OPEN_TITLE"] = "GPIO を使えるようにする"; -Blockly.Msg["GPIOCHIP_OPEN_TOOLTIP"] = "GPIOを初期化して接続します。"; -Blockly.Msg["GPIOCHIP_CLOSE_TITLE"] = "GPIO の後片付けをする"; -Blockly.Msg["GPIOCHIP_CLOSE_TOOLTIP"] = "GPIOとの接続を終了します。"; -Blockly.Msg["GPIOCHIP_CLOSE_TITLE"] = "GPIO の後片付けをする"; -Blockly.Msg["GPIO_CLAIM_INPUT_TITLE"] = "GPIO %1 を入力モードにして %2"; -Blockly.Msg["GPIO_CLAIM_INPUT_TOOLTIP"] = "GPIO端子を入力モードにして、プルアップ・プルダウン・無しを設定します。"; -Blockly.Msg["GPIO_CLAIM_OUTPUT_TITLE"] = "GPIO %1 を出力モードにする"; -Blockly.Msg["GPIO_CLAIM_OUTPUT_TOOLTIP"] = "GPIO端子のモードを出力に設定します。"; +Blockly.Msg["GPIO_OPEN_TITLE"] = "GPIO を使えるようにする"; +Blockly.Msg["GPIO_OPEN_TOOLTIP"] = "GPIOを初期化して接続します。"; +Blockly.Msg["GPIO_CLOSE_TITLE"] = "GPIO の後片付けをする"; +Blockly.Msg["GPIO_CLOSE_TOOLTIP"] = "GPIOとの接続を終了します。"; +Blockly.Msg["GPIO_CLOSE_TITLE"] = "GPIO の後片付けをする"; +Blockly.Msg["GPIO_SET_INPUT_TITLE"] = "GPIO %1 を入力モードにして %2"; +Blockly.Msg["GPIO_SET_INPUT_TOOLTIP"] = "GPIO端子を入力モードにして、プルアップ・プルダウン・無しを設定します。"; +Blockly.Msg["GPIO_SET_OUTPUT_TITLE"] = "GPIO %1 を出力モードにする"; +Blockly.Msg["GPIO_SET_OUTPUT_TOOLTIP"] = "GPIO端子のモードを出力に設定します。"; Blockly.Msg["GPIO_READ_TITLE"] = "GPIO %1 の値"; Blockly.Msg["GPIO_READ_TOOLTIP"] = "GPIO端子の値をデジタル値(0または1)で読み取ります。"; Blockly.Msg["GPIO_WRITE_TITLE"] = "GPIO %1 の値を %2 にする"; Blockly.Msg["GPIO_WRITE_TOOLTIP"] = "GPIO端子の値をデジタル値(0または1)で出力します。"; -Blockly.Msg["TX_SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする"; -Blockly.Msg["TX_SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(1000~2000μsec)までの数値で指定します。"; -Blockly.Msg["TX_PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力"; -Blockly.Msg["TX_PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。"; +Blockly.Msg["SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする"; +Blockly.Msg["SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(1000~2000μsec)までの数値で指定します。"; +Blockly.Msg["PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力"; +Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。"; Blockly.Msg["I2C_OPEN_TITLE"] = "アドレス %1 の I2C デバイスを開く"; Blockly.Msg["I2C_OPEN_TOOLTIP"] = "I2C接続されたデバイスとの通信を開始します。一度にオープンできるI2Cデバイスはひとつだけです。"; Blockly.Msg["SERIAL_OPEN_TITLE"] = "シリアルポートを速度 %1 bpsで開く"; @@ -620,6 +620,6 @@ window.onbeforeunload = () => { ugj_saveWorkspace(); elutil.savePrefsToLS(); elutil.killAllChildren(); - elutil.cleanupLGPIO(); + elutil.cleanupGPIO(); } diff --git a/index_elutil.js b/index_elutil.js index 710f7f8..b6e493c 100644 --- a/index_elutil.js +++ b/index_elutil.js @@ -11,7 +11,9 @@ const ugj_const = { library_path: './lib/', executable_path: './bin/', localStorage_fname: 'ocoge.json', - error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。' + error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。', + PIG: 'pigpio', + LG: 'lgpio' } /** クラス elUtil ****************************************************************** */ @@ -26,6 +28,7 @@ class elUtil { this.wsChanged = false; this.mascotFilePath = this.path.join(ugj_const.mascot_path, ugj_const.mascot_defname); this.children = []; + this.gpio_backend = ugj_const.PIG; } // 0で数値の桁合わせ : NUM=値 LEN=桁数 zeroPadding(NUM, LEN) { @@ -189,9 +192,9 @@ class elUtil { this.children = []; } - // LGPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ - cleanupLGPIO() { - let pi = require('@ocogeclub/lgpio').close_all_handle(); + // GPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ + cleanupGPIO() { + require('@ocogeclub/' + this.gpio_backend).close_all_handle(); } // 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存 @@ -273,7 +276,7 @@ class brUtil { newFile() { ; } setWsChanged() { ; } killAllChildren() { ; } - cleanupLGPIO() { ; } + cleanupGPIO() { ; } } // Electron 動作 / ブラウザ動作自動判別 @@ -303,7 +306,7 @@ if (!is_el) { case 'nodemailer': block = 'メール送信'; break; - case '@ocogeclub/lgpio': + case '@ocogeclub/gpio': block = 'GPIO'; break; case '@ocogeclub/bme280': diff --git a/installer/install.sh b/installer/install.sh index 08f6995..7a24d82 100644 --- a/installer/install.sh +++ b/installer/install.sh @@ -1,22 +1,18 @@ #!/bin/bash -x # Usage: bash install.sh -NODEJS=14.17.0 +NODEVER=14.17.0 -# install lgpio (and python3) +# install some packages sudo apt update -sudo apt install build-essential python3 swig python3-dev python3-setuptools -y -wget http://abyz.me.uk/lg/lg.zip -unzip lg.zip -rm lg.zip -cd lg -make -sudo make install -cd .. +sudo apt install fswebcam -y +# enable pigpiod service +sudo systemctl enable pigpiod.service +sudo systemctl start pigpiod.service # install node.js (=electron node version) via n (https://github.com/tj/n) curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n -sudo bash n $NODEJS +sudo bash n $NODEVER # install python code formatter python3 -m pip install black # install desktop entry diff --git a/local_modules/@ocogeclub/lgpio/index.js b/local_modules/@ocogeclub/lgpio/index.js index 2642ea6..71b424d 100644 --- a/local_modules/@ocogeclub/lgpio/index.js +++ b/local_modules/@ocogeclub/lgpio/index.js @@ -1,28 +1,32 @@ module.exports = require('bindings')('lgpio'); -module.exports.SET_ACTIVE_LOW = 4; -module.exports.SET_OPEN_DRAIN = 8; -module.exports.SET_OPEN_SOURCE = 16; -module.exports.SET_PULL_UP = 32; -module.exports.SET_PULL_DOWN = 64; -module.exports.SET_PULL_NONE = 128; +// module.exports.SET_ACTIVE_LOW = 4; +// module.exports.SET_OPEN_DRAIN = 8; +// module.exports.SET_OPEN_SOURCE = 16; +// module.exports.SET_PULL_UP = 32; +// module.exports.SET_PULL_DOWN = 64; +// module.exports.SET_PULL_NONE = 128; +module.exports.PULL_UP = 32; +module.exports.PULL_DOWN = 64; +module.exports.PULL_NONE = 128; + let gpio_hand = -1; let ser_hand = -1; let i2c_hand = -1; -module.exports.gpiochip_open = gpiochip => { - if (gpio_hand < 0) gpio_hand = module.exports._gpiochip_open(gpiochip); +module.exports.gpio_open = () => { + if (gpio_hand < 0) gpio_hand = module.exports._gpiochip_open(0); return gpio_hand; } -module.exports.gpiochip_close = () => { +module.exports.gpio_close = () => { if (gpio_hand >= 0) module.exports._gpiochip_close(gpio_hand); gpio_hand = -1; } -module.exports.gpio_claim_output = gpio => { +module.exports.gpio_set_output = gpio => { if (gpio_hand >= 0) return module.exports._gpio_claim_output(gpio_hand, gpio); } -module.exports.gpio_claim_input = gpio => { - if (gpio_hand >= 0) return module.exports._gpio_claim_input(gpio_hand, gpio); +module.exports.gpio_set_input = (gpio, lflag) => { + if (gpio_hand >= 0) return module.exports._gpio_claim_input(gpio_hand, gpio, lflag); } module.exports.gpio_read = gpio => { if (gpio_hand >= 0) return module.exports._gpio_read(gpio_hand, gpio); @@ -30,6 +34,12 @@ module.exports.gpio_read = gpio => { module.exports.gpio_write = (gpio, value) => { if (gpio_hand >= 0) return module.exports._gpio_write(gpio_hand, gpio, value); } +module.exports.servo = (gpio, pulse_width) => { + if (gpio_hand >= 0) return module.exports._tx_servo(gpio_hand, gpio, pulse_width); +} +module.exports.pwm = (gpio, pwm_frequency, pwm_duty_cycle) => { + if (gpio_hand >= 0) return module.exports._tx_pwm(gpio_hand, gpio, pwm_frequency, pwm_duty_cycle); +} module.exports.serial_open = (tty, baud) => { if (ser_hand >= 0) module.exports._serial_close(ser_hand); // 勝手に閉じる ser_hand = module.exports._serial_open(tty, baud); @@ -68,7 +78,7 @@ module.exports.i2c_write_device = data => { } // 終了処理 module.exports.close_all_handle = () => { - module.exports.gpiochip_close(); + module.exports.gpio_close(); module.exports.serial_close(); module.exports.i2c_close(); } \ No newline at end of file diff --git a/local_modules/@ocogeclub/lgpio/lgpio.cpp b/local_modules/@ocogeclub/lgpio/lgpio.cpp index 16ea233..88fb75e 100644 --- a/local_modules/@ocogeclub/lgpio/lgpio.cpp +++ b/local_modules/@ocogeclub/lgpio/lgpio.cpp @@ -206,9 +206,6 @@ Value serialOpen(const CallbackInfo &info) } std::string tty = info[0].As().Utf8Value(); - // char *c = new char[tty.size()+1]; - // std::strcpy(c, tty.c_str()); - // &ser_tty[0] で参照できるらしいけど危険? int baud = info[1].As().Int32Value(); diff --git a/local_modules/@ocogeclub/pigpio/binding.gyp b/local_modules/@ocogeclub/pigpio/binding.gyp new file mode 100644 index 0000000..46a8237 --- /dev/null +++ b/local_modules/@ocogeclub/pigpio/binding.gyp @@ -0,0 +1,12 @@ +{ + "targets": [ + { + "target_name": "pigpio", + "sources": ["pigpio.cpp"], + "defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"], + "include_dirs": [" { + if (pi < 0) pi = module.exports._pigpio_start('', ''); + return pi; +} +module.exports.gpio_close = () => { + if (pi >= 0) module.exports._pigpio_stop(pi); + pi = -1; +} +module.exports.gpio_set_output = gpio => { + if (pi >= 0) return module.exports._set_mode(pi, gpio, 1); +} +module.exports.gpio_set_input = (gpio, mode) => { + if (pi >= 0) { + let r = module.exports._set_mode(pi, gpio, 0); + if (r == 0) + return module.exports._set_pull_up_down(pi, gpio, mode); + else + return r; + } +} +module.exports.gpio_read = gpio => { + if (pi >= 0) return module.exports._gpio_read(pi, gpio); +} +module.exports.gpio_write = (gpio, value) => { + if (pi >= 0) return module.exports._gpio_write(pi, gpio, value); +} +module.exports.servo = (gpio, pulse_width) => { + if (pi >= 0) return module.exports._set_servo_pulsewidth(pi, gpio, pulse_width); +} +module.exports.pwm = (gpio, pwm_frequency, pwm_duty_cycle) => { + if (pi >= 0) { + module.exports._set_PWM_frequency(pi, gpio, pwm_frequency); + module.exports._set_PWM_dutycycle(pi, gpio, pwm_duty_cycle); + } +} +module.exports.serial_open = (tty, baud) => { + if (ser_hand >= 0) module.exports._serial_close(pi, ser_hand); // 勝手に閉じる + ser_hand = module.exports._serial_open(pi, tty, baud); + return ser_hand; +} +module.exports.serial_close = () => { + if (ser_hand >= 0) module.exports._serial_close(pi, ser_hand); + ser_hand = -1; +} +module.exports.serial_write = data => { + if (ser_hand >= 0) return module.exports._serial_write(pi, ser_hand, Buffer.from(data)); +} +module.exports.serial_read = count => { + if (ser_hand >= 0) return module.exports._serial_read(pi, ser_hand, count).toString('utf8'); +} +module.exports.i2c_open = (i2c_bus, i2c_address) => { + if (i2c_hand >= 0) module.exports._i2c_close(pi, i2c_hand); // 勝手に閉じる + i2c_hand = module.exports._i2c_open(pi, i2c_bus, i2c_address); + return i2c_hand; +} +module.exports.i2c_close = () => { + if (i2c_hand >= 0) module.exports._i2c_close(pi, i2c_hand); + i2c_hand = -1; +} +module.exports.i2c_write_byte_data = (reg, byte_val) => { + if (i2c_hand >= 0) return module.exports._i2c_write_byte_data(pi, i2c_hand, reg, byte_val); +} +module.exports.i2c_read_byte_data = reg => { + if (i2c_hand >= 0) return module.exports._i2c_read_byte_data(pi, i2c_hand, reg); +} +module.exports.i2c_read_device = count => { + if (i2c_hand >= 0) return module.exports._i2c_read_device(pi, i2c_hand, count).toString('utf8'); +} +module.exports.i2c_write_device = data => { + if (i2c_hand >= 0) return module.exports._i2c_write_device(pi, i2c_hand, Buffer.from(data)); +} +// 終了処理 +module.exports.close_all_handle = () => { + module.exports.serial_close(); + module.exports.i2c_close(); + module.exports.gpio_close(); +} \ No newline at end of file diff --git a/local_modules/@ocogeclub/pigpio/package.json b/local_modules/@ocogeclub/pigpio/package.json new file mode 100644 index 0000000..d61ab1c --- /dev/null +++ b/local_modules/@ocogeclub/pigpio/package.json @@ -0,0 +1,11 @@ +{ + "name": "@ocogeclub/pigpio", + "version": "0.0.1", + "main": "index.js", + "private": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } +} \ No newline at end of file diff --git a/local_modules/@ocogeclub/pigpio/pigpio.cpp b/local_modules/@ocogeclub/pigpio/pigpio.cpp new file mode 100644 index 0000000..83beac9 --- /dev/null +++ b/local_modules/@ocogeclub/pigpio/pigpio.cpp @@ -0,0 +1,622 @@ +/** PIGPIO デーモンを Node.js から利用するモジュール ** */ +/** 関数名・書式は Python Interface に準拠 ******************* */ + +#include +#include +#include +#include + +using namespace Napi; + +// pigpio 初期化 +Value _pigpioStart(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 2) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsString() || !info[1].IsString()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + std::string addrStr = info[0].As().Utf8Value(); + std::string portStr = info[1].As().Utf8Value(); + return Number::New(env, pigpio_start(&addrStr[0], &portStr[0])); +} + +// pigpio 後始末 +Value _pigpioStop(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 1) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + pigpio_stop(pi); + return env.Null(); +} + +// GPIO 端子のモードを設定 +Value _setMode(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int gpio = info[1].As().Uint32Value(); + unsigned int mode = info[2].As().Uint32Value(); + + return Number::New(env, + set_mode(pi, gpio, mode)); +} + +// GPIO 端子のモードを取得 +// Value _GetMode(const CallbackInfo &info) +// { +// Env env = info.Env(); +// if (info.Length() < 1) +// { +// TypeError::New(env, "Wrong number of arguments") +// .ThrowAsJavaScriptException(); +// return env.Null(); +// } +// if (!info[0].IsNumber()) +// { +// TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); +// return env.Null(); +// } + +// unsigned int gpio = info[0].As().DoubleValue(); + +// return Number::New(env, +// get_mode(pi, gpio)); +// } + +// GPIOの内部プルアップ/ダウン抵抗の設定/クリア +Value _setPullUpDown(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int gpio = info[1].As().Uint32Value(); + unsigned int pud = info[2].As().Uint32Value(); + + return Number::New(env, + set_pull_up_down(pi, gpio, pud)); +} + +// GPIOの電圧を読む +Value _gpioRead(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 2) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + int pi = info[0].As().Int32Value(); + unsigned int gpio = info[1].As().Uint32Value(); + + return Number::New(env, + gpio_read(pi, gpio)); +} + +// GPIO の電圧をセットする +Value _gpioWrite(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int gpio = info[1].As().Uint32Value(); + unsigned int value = info[2].As().Uint32Value(); + + return Number::New(env, + gpio_write(pi, gpio, value)); +} + +// サーボパルス幅をセットする +Value _setServoPulsewidth(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int user_gpio = info[1].As().Uint32Value(); + unsigned int pulsewidth = info[2].As().Uint32Value(); + + return Number::New(env, + set_servo_pulsewidth(pi, user_gpio, pulsewidth)); +} + +// PWM周波数を設定する +Value _setPwmFrequency(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int user_gpio = info[1].As().Uint32Value(); + unsigned int frequency = info[2].As().Uint32Value(); + + return Number::New(env, + set_PWM_frequency(pi, user_gpio, frequency)); +} + +// PWMのレンジを設定する +// Value _SetPwmRange(const CallbackInfo &info) +// { +// Env env = info.Env(); +// if (info.Length() < 2) +// { +// TypeError::New(env, "Wrong number of arguments") +// .ThrowAsJavaScriptException(); +// return env.Null(); +// } +// if (!info[0].IsNumber() || !info[1].IsNumber()) +// { +// TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); +// return env.Null(); +// } + +// unsigned int user_gpio = info[0].As().DoubleValue(); +// unsigned int range = info[1].As().DoubleValue(); + +// return Number::New(env, +// set_PWM_range(pi, user_gpio, range)); +// } + +// PWMのデューティ比を指定して出力を開始する +Value _setPwmDutycycle(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int user_gpio = info[1].As().Uint32Value(); + unsigned int dutycycle = info[2].As().Uint32Value(); + + return Number::New(env, + set_PWM_dutycycle(pi, user_gpio, dutycycle)); +} + +// シリアルポートを開く +Value _serialOpen(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + std::string ser_tty = info[1].As().Utf8Value(); + unsigned int baud = info[2].As().Uint32Value(); + // &ser_tty[0] + return Number::New(env, + serial_open(pi, (char *)ser_tty.c_str(), baud, 0)); +} + +// シリアルポートを閉じる +Value _serialClose(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 2) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + + return Number::New(env, + serial_close(pi, handle)); +} + +// シリアルデバイスからデータを読む +Value _serialRead(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int count = info[2].As().Uint32Value(); + + char buf[count]; + int rxCount = serial_read(pi, handle, buf, count); + auto outBuf = Buffer::Copy(env, buf, rxCount); + + return outBuf; +} + +// シリアルデバイスにバイト列を書き込む(data: string) +Value _serialWrite(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + auto buf = info[2].As>(); + + int count = buf.Length(); + + return Number::New(env, + serial_write(pi, handle, buf.Data(), count)); +} + +// I2Cバスアドレスのデバイスのハンドルを返す +Value _i2cOpen(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + + int pi = info[0].As().Int32Value(); + unsigned int i2c_bus = info[1].As().Uint32Value(); + unsigned int i2c_addr = info[2].As().Uint32Value(); + + return Number::New(env, + i2c_open(pi, i2c_bus, i2c_addr, 0)); +} +// オープン済みI2Cハンドルを閉じる +Value _i2cClose(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 2) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[0].As().Uint32Value(); + + return Number::New(env, + i2c_close(pi, handle)); +} + +// デバイスに1バイトを送る +Value _i2cWriteByte(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int bVal = info[2].As().Uint32Value(); + + return Number::New(env, + i2c_write_byte(pi, handle, bVal)); +} +// デバイスから1バイトを受け取る +Value _i2cReadByte(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 2) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[0].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + + return Number::New(env, + i2c_read_byte(pi, handle)); +} + +// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む +Value _i2cWriteByteData(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 4) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[0].As().Uint32Value(); + unsigned int i2c_reg = info[1].As().Uint32Value(); + unsigned int bVal = info[2].As().Uint32Value(); + + return Number::New(env, + i2c_write_byte_data(pi, handle, i2c_reg, bVal)); +} + +// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから1バイトを読み込む +Value _i2cReadByteData(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int i2c_reg = info[2].As().Uint32Value(); + + return Number::New(env, + i2c_read_byte_data(pi, handle, i2c_reg)); +} + +// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは1~32。 +Value _i2cReadI2cBlockData(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 4) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int i2cReg = info[2].As().Uint32Value(); + unsigned int count = info[3].As().Uint32Value(); + + char buf[count]; + int rxCount = i2c_read_i2c_block_data(pi, handle, i2cReg, buf, count); + auto outBuf = Buffer::Copy(env, buf, rxCount); + + return outBuf; +} + +// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから単一の16ビットワードを読み取る +Value _i2cReadWordData(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int i2c_reg = info[2].As().Uint32Value(); + + return Number::New(env, + i2c_read_word_data(pi, handle, i2c_reg)); +} + +// i2c デバイスからデータを受け取る +Value _i2cReadDevice(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + unsigned int count = info[2].As().Uint32Value(); + + char buf[count]; + int rxCount = i2c_read_device(pi, handle, buf, count); + auto outBuf = Buffer::Copy(env, buf, rxCount); + + return outBuf; +} + +// i2c デバイスにバイト列を送る(data: buffer) +Value _i2cWriteDevice(const CallbackInfo &info) +{ + Env env = info.Env(); + if (info.Length() < 3) + { + TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer()) + { + TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + int pi = info[0].As().Int32Value(); + unsigned int handle = info[1].As().Uint32Value(); + auto buf = info[2].As>(); + + unsigned int count = buf.Length(); + + return Number::New(env, + i2c_write_device(pi, handle, buf.Data(), count)); +} + +Object +Init(Env env, Object exports) +{ + // exports.Set(String::New(env, "usleep"), Function::New(env, _Usleep)); + exports.Set(String::New(env, "_pigpio_start"), Function::New(env, _pigpioStart)); + exports.Set(String::New(env, "_pigpio_stop"), Function::New(env, _pigpioStop)); + exports.Set(String::New(env, "_set_mode"), Function::New(env, _setMode)); + // exports.Set(String::New(env, "get_mode"), Function::New(env, _GetMode)); + exports.Set(String::New(env, "_set_pull_up_down"), Function::New(env, _setPullUpDown)); + exports.Set(String::New(env, "_gpio_read"), Function::New(env, _gpioRead)); + exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite)); + exports.Set(String::New(env, "_set_servo_pulsewidth"), Function::New(env, _setServoPulsewidth)); + exports.Set(String::New(env, "_set_PWM_frequency"), Function::New(env, _setPwmFrequency)); + // exports.Set(String::New(env, "set_PWM_range"), Function::New(env, _SetPwmRange)); + exports.Set(String::New(env, "_set_PWM_dutycycle"), Function::New(env, _setPwmDutycycle)); + exports.Set(String::New(env, "_serial_open"), Function::New(env, _serialOpen)); + exports.Set(String::New(env, "_serial_close"), Function::New(env, _serialClose)); + exports.Set(String::New(env, "_serial_read"), Function::New(env, _serialRead)); + exports.Set(String::New(env, "_serial_write"), Function::New(env, _serialWrite)); + exports.Set(String::New(env, "_i2c_open"), Function::New(env, _i2cOpen)); + exports.Set(String::New(env, "_i2c_close"), Function::New(env, _i2cClose)); + exports.Set(String::New(env, "_i2c_write_byte"), Function::New(env, _i2cWriteByte)); + exports.Set(String::New(env, "_i2c_read_byte"), Function::New(env, _i2cReadByte)); + exports.Set(String::New(env, "_i2c_write_byte_data"), Function::New(env, _i2cWriteByteData)); + exports.Set(String::New(env, "_i2c_read_byte_data"), Function::New(env, _i2cReadByteData)); + exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData)); + exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData)); + exports.Set(String::New(env, "_i2c_write_device"), Function::New(env, _i2cWriteDevice)); + exports.Set(String::New(env, "_i2c_read_device"), Function::New(env, _i2cReadDevice)); + return exports; +} + +NODE_API_MODULE(pigpio, Init) \ No newline at end of file diff --git a/package.json b/package.json index 0bea959..217f857 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ }, "dependencies": { "@ocogeclub/bme280": "file:local_modules/@ocogeclub/bme280", - "@ocogeclub/lgpio": "file:local_modules/@ocogeclub/lgpio", + "@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio", "@tensorflow/tfjs-node": "^3.9.0", "@vladmandic/face-api": "^1.5.3", "axios": "^0.21.1", "nodemailer": "^6.6.0" } -} +} \ No newline at end of file diff --git a/ugj_blocks.js b/ugj_blocks.js index 27da81a..978f80e 100644 --- a/ugj_blocks.js +++ b/ugj_blocks.js @@ -291,70 +291,67 @@ Blockly.Python['ugj_dectohex'] = function (block) { /************ */ /** GPIO Open */ /************ */ -var ugjGpiochipOpenDefinition = { - "type": "ugj_gpiochip_open", - "message0": "%{BKY_GPIOCHIP_OPEN_TITLE}", +var ugjGpioOpenDefinition = { + "type": "ugj_gpio_open", + "message0": "%{BKY_GPIO_OPEN_TITLE}", "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_GPIOCHIP_OPEN_TOOLTIP}", + "tooltip": "%{BKY_GPIO_OPEN_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_gpiochip_open'] = { +Blockly.Blocks['ugj_gpio_open'] = { init: function () { - this.jsonInit(ugjGpiochipOpenDefinition); + this.jsonInit(ugjGpioOpenDefinition); } }; -Blockly.JavaScript['ugj_gpiochip_open'] = function (block) { +Blockly.JavaScript['ugj_gpio_open'] = function (block) { Blockly.JavaScript.provideFunction_( - 'require_oclg', [`const pi = require('@ocogeclub/lgpio');`] + 'require_gpio', [`const pi = require('@ocogeclub/` + elutil.gpio_backend + `');`] ); - // var code = `pi.gpio_chip_open(0);\nconsole.log(pi.get_hand());`; // - // var code = `var lgHand = pi.gpiochip_open(0);\n`; // - var code = `pi.gpiochip_open(0);\n`; // + var code = `pi.gpio_open();\n`; // return code; }; -Blockly.Python['ugj_gpiochip_open'] = function (block) { +Blockly.Python['ugj_gpio_open'] = function (block) { Blockly.Python.provideFunction_( 'import_lgpio', ['import lgpio as pi'] ); - var code = `lgHand = pi.gpiochip_open(0)\n`; // + var code = `gpioHand = pi.gpiochip_open(0)\n`; // return code; }; /************* */ /** GPIO Close */ /************* */ -var ugjGpiochipCloseDefinition = { - "type": "ugj_gpiochip_close", - "message0": "%{BKY_GPIOCHIP_CLOSE_TITLE}", +var ugjGpioCloseDefinition = { + "type": "ugj_gpio_close", + "message0": "%{BKY_GPIO_CLOSE_TITLE}", "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_GPIOCHIP_CLOSE_TOOLTIP}", + "tooltip": "%{BKY_GPIO_CLOSE_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_gpiochip_close'] = { +Blockly.Blocks['ugj_gpio_close'] = { init: function () { - this.jsonInit(ugjGpiochipCloseDefinition); + this.jsonInit(ugjGpioCloseDefinition); } }; -Blockly.JavaScript['ugj_gpiochip_close'] = function (block) { - var code = 'pi.gpiochip_close();\n'; - // var code = 'pi.gpiochip_close(lgHand);\n'; +Blockly.JavaScript['ugj_gpio_close'] = function (block) { + var code = 'pi.gpio_close();\n'; return code; }; -Blockly.Python['ugj_gpiochip_close'] = function (block) { - var code = 'pi.gpiochip_close(lgHand)\n'; +Blockly.Python['ugj_gpio_close'] = function (block) { + var code = 'pi.gpiochip_close(gpioHand)\n'; return code; }; /*********************** */ -/** GPIO Claim Output ** */ +/** GPIO Set Output ** */ /*********************** */ -var ugjGpioClaimOutputDefinition = { - "type": "ugj_gpio_claim_output", - "message0": "%{BKY_GPIO_CLAIM_OUTPUT_TITLE}", +var ugjGpioSetOutputDefinition = { + "type": "ugj_gpio_set_output", + "message0": "%{BKY_GPIO_SET_OUTPUT_TITLE}", "args0": [ { "type": "input_value", @@ -365,32 +362,32 @@ var ugjGpioClaimOutputDefinition = { "inputsInline": true, "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_GPIO_CLAIM_OUTPUT_TOOLTIP}", + "tooltip": "%{BKY_GPIO_SET_OUTPUT_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_gpio_claim_output'] = { +Blockly.Blocks['ugj_gpio_set_output'] = { init: function () { - this.jsonInit(ugjGpioClaimOutputDefinition); + this.jsonInit(ugjGpioSetOutputDefinition); } }; -Blockly.JavaScript['ugj_gpio_claim_output'] = function (block) { +Blockly.JavaScript['ugj_gpio_set_output'] = function (block) { var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC); - var code = `pi.gpio_claim_output(${value_gpio});\n`; + var code = `pi.gpio_set_output(${value_gpio});\n`; return code; }; -Blockly.Python['ugj_gpio_claim_output'] = function (block) { +Blockly.Python['ugj_gpio_set_output'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); - var code = `pi.gpio_claim_output(${value_gpio})\n`; + var code = `pi.gpio_set_output(${value_gpio})\n`; return code; }; /********************** */ -/** GPIO Claim Input ** */ +/** GPIO Set Input ** */ /********************** */ -var ugjGpioClaimInputDefinition = { - "type": "ugj_gpio_claim_input", - "message0": "%{BKY_GPIO_CLAIM_INPUT_TITLE}", +var ugjGpioSetInputDefinition = { + "type": "ugj_gpio_set_input", + "message0": "%{BKY_GPIO_SET_INPUT_TITLE}", "args0": [ { "type": "input_value", @@ -419,25 +416,25 @@ var ugjGpioClaimInputDefinition = { "inputsInline": true, "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_GPIO_CLAIM_INPUT_TOOLTIP}", + "tooltip": "%{BKY_GPIO_SET_INPUT_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_gpio_claim_input'] = { +Blockly.Blocks['ugj_gpio_set_input'] = { init: function () { - this.jsonInit(ugjGpioClaimInputDefinition); + this.jsonInit(ugjGpioSetInputDefinition); } }; -Blockly.JavaScript['ugj_gpio_claim_input'] = function (block) { +Blockly.JavaScript['ugj_gpio_set_input'] = function (block) { var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC); var dropdown_lflag = block.getFieldValue('lflag'); - var code = `pi.gpio_claim_input(${value_gpio}, ${dropdown_lflag});\n`; + var code = `pi.gpio_set_input(${value_gpio}, ${dropdown_lflag});\n`; return code; }; -Blockly.Python['ugj_gpio_claim_input'] = function (block) { +Blockly.Python['ugj_gpio_set_input'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); var dropdown_lflag = block.getFieldValue('lflag'); - var code = `pi.gpio_claim_input(lgHand, ${value_gpio}, ${dropdown_lflag})\n`; + var code = `pi.gpio_set_input(gpioHand, ${value_gpio}, ${dropdown_lflag})\n`; return code; }; @@ -467,12 +464,12 @@ Blockly.Blocks['ugj_gpio_read'] = { }; Blockly.JavaScript['ugj_gpio_read'] = function (block) { var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC); - var code = `pi.gpio_read(lgHand, ${value_gpio})`; + var code = `pi.gpio_read(${value_gpio})`; return [code, Blockly.JavaScript.ORDER_NONE]; }; Blockly.Python['ugj_gpio_read'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); - var code = `pi.gpio_read(lgHand, ${value_gpio})`; + var code = `pi.gpio_read(gpioHand, ${value_gpio})`; return [code, Blockly.Python.ORDER_NONE]; }; @@ -524,16 +521,16 @@ Blockly.JavaScript['ugj_gpio_write'] = function (block) { Blockly.Python['ugj_gpio_write'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); var dropdown_level = block.getFieldValue('level'); - var code = `pi.gpio_write(lgHand, ${value_gpio}, ${dropdown_level})\n`; + var code = `pi.gpio_write(gpioHand, ${value_gpio}, ${dropdown_level})\n`; return code; }; /*****************/ /** Servo motor **/ /*****************/ -var ugjTxServoDefinition = { - "type": "ugj_tx_servo", - "message0": "%{BKY_TX_SERVO_TITLE}", +var ugjServoDefinition = { + "type": "ugj_servo", + "message0": "%{BKY_SERVO_TITLE}", "args0": [ { "type": "input_value", @@ -549,34 +546,34 @@ var ugjTxServoDefinition = { "inputsInline": true, "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_TX_SERVO_TOOLTIP}", + "tooltip": "%{BKY_SERVO_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_tx_servo'] = { +Blockly.Blocks['ugj_servo'] = { init: function () { - this.jsonInit(ugjTxServoDefinition); + this.jsonInit(ugjServoDefinition); } }; -Blockly.JavaScript['ugj_tx_servo'] = function (block) { +Blockly.JavaScript['ugj_servo'] = function (block) { var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC); var value_pulsewidth = Blockly.JavaScript.valueToCode(block, 'pulsewidth', Blockly.JavaScript.ORDER_ATOMIC); - var code = `pi.tx_servo(lgHand, ${value_gpio}, ${value_pulsewidth});\n`; + var code = `pi.servo(${value_gpio}, ${value_pulsewidth});\n`; return code; }; -Blockly.Python['ugj_tx_servo'] = function (block) { +Blockly.Python['ugj_servo'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); var value_pulsewidth = Blockly.Python.valueToCode(block, 'pulsewidth', Blockly.Python.ORDER_ATOMIC); - var code = `pi.tx_servo(lgHand, ${value_gpio}, ${value_pulsewidth})\n`; + var code = `pi.servo(gpioHand, ${value_gpio}, ${value_pulsewidth})\n`; return code; }; /************************************************* */ /** starts software timed PWM on an output GPIO ** */ /************************************************* */ -var ugjTxPwmDefinition = { - "type": "ugj_tx_pwm", - "message0": "%{BKY_TX_PWM_TITLE}", +var ugjPwmDefinition = { + "type": "ugj_pwm", + "message0": "%{BKY_PWM_TITLE}", "args0": [ { "type": "input_value", @@ -597,27 +594,27 @@ var ugjTxPwmDefinition = { "inputsInline": true, "previousStatement": null, "nextStatement": null, - "tooltip": "%{BKY_TX_PWM_TOOLTIP}", + "tooltip": "%{BKY_PWM_TOOLTIP}", "helpUrl": "", "style": "gpio_blocks" }; -Blockly.Blocks['ugj_tx_pwm'] = { +Blockly.Blocks['ugj_pwm'] = { init: function () { - this.jsonInit(ugjTxPwmDefinition); + this.jsonInit(ugjPwmDefinition); } }; -Blockly.JavaScript['ugj_tx_pwm'] = function (block) { +Blockly.JavaScript['ugj_pwm'] = function (block) { var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC); var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC); var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC); - var code = `pi.tx_pwm(lgHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`; + var code = `pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`; return code; }; -Blockly.Python['ugj_tx_pwm'] = function (block) { +Blockly.Python['ugj_pwm'] = function (block) { var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC); var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC); var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC); - var code = `pi.tx_pwm(lgHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`; + var code = `pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`; return code; }; /********************** */ @@ -809,7 +806,7 @@ Blockly.JavaScript['ugj_i2c_open'] = function (block) { Blockly.JavaScript.provideFunction_( 'require_oclg', [`const pi = require('@ocogeclub/lgpio');`] ); - var code = `pi.i2c_open(1, ${value_i2c_address});\n`; + var code = `pi.i2c_open(3, ${value_i2c_address});\n`; return code; }; Blockly.Python['ugj_i2c_open'] = function (block) { @@ -1046,7 +1043,7 @@ Blockly.JavaScript['ugj_bme280'] = function (block) { ); var code = [ `const options = {`, - ` i2cBusNo: 1,`, + ` i2cBusNo: 3,`, ` i2cAddress: ${value_address}`, `};`, `bme280.init(options);`, @@ -1081,110 +1078,6 @@ Blockly.Python['ugj_bme280'] = function (block) { /** Multimedia *****************************************************************************************************/ -/******************* */ -/** TensorFlow.js ** */ -/******************* */ -Blockly.Blocks['ugj_library_tensorflow'] = { - init: function () { - this.appendDummyInput() - .appendField("TensorFlowによる画像認識(推論)"); - this.setOutput(true, "Library"); - this.setStyle('special_blocks') - this.setTooltip("tensorflow.jsをロードし、推論ができるようにします。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_library_tensorflow'] = function (block) { - var code = `'${ugj_const.library_path}tensorflow.min.js'`; - return [code, Blockly.JavaScript.ORDER_NONE]; -}; -/********************** */ -/** Object Detection ** */ -/********************** */ -Blockly.Blocks['ugj_tfpredict_init'] = { - init: function () { - this.appendDummyInput() - .appendField("画像認識のビデオを表示"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setStyle('multimedia_blocks') - this.setTooltip("画像認識(推論)をするためのビデオストリームを表示します。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_tfpredict_init'] = function (block) { - var code = [ - `const video = document.getElementById('subdisplay');`, - `video.style.display = 'inline-block';`, - `const overlay = document.createElement('canvas');`, - `overlay.setAttribute('width', video.width);`, - `overlay.setAttribute('height', video.height);`, - "const context = overlay.getContext('2d');", - "const stream = await navigator.mediaDevices.getUserMedia({ video: {} });", - "video.srcObject = stream;", - "" - ].join('\n'); - return code; -}; -Blockly.Blocks['ugj_tfpredict_loadmodel'] = { - init: function () { - this.appendDummyInput() - .appendField("学習済みの指数えモデル (sign_language_vgg16) を読み込む"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setStyle('multimedia_blocks') - this.setTooltip("ardamavi氏による指数え画像データセットをPonDad氏がts.js用モデルにコンバートしたものです。"); - this.setHelpUrl("https://github.com/PonDad/manatee"); - } -}; -Blockly.JavaScript['ugj_tfpredict_loadmodel'] = function (block) { - var code = [ - `const model = await tf.loadModel('${ugj_const.library_path}sign_language_vgg16/model.json');`, - "const CLASSES = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'};", - "" - ].join('\n'); - return code; -}; -Blockly.Blocks['ugj_tfpredict_predict'] = { - init: function () { - this.appendDummyInput() - .appendField("推論をして") - .appendField(new Blockly.FieldVariable("結果"), "result") - .appendField("を取得する"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setStyle('multimedia_blocks') - this.setTooltip("読み込んだモデルを使用してカメラ画像から画像認識を行い、変数に代入します。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_tfpredict_predict'] = function (block) { - var variable_result = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('result'), Blockly.Variables.NAME_TYPE); - var code = [ - "context.drawImage(video, 0, 0, video.width, video.height);", - "let tensor = tf.fromPixels(canvas).resizeNearestNeighbor([100,100]).toFloat();", - "tensor = tensor.div(tf.scalar(255)).expandDims();", - "let prediction = await model.predict(tensor).data();", - "let results = Array.from(prediction).map(function(p,i){", - " return {", - " probability: p,", - " className: CLASSES[i]", - " };", - "}).sort(function(a,b){", - " return b.probability-a.probability;", - "}).slice(0,5);", - "let r = '';", - "results.forEach(function(p){", - " r += `${p.className}:${p.probability.toFixed(6)},`;", - "});", - `${variable_result} = r;`, - "" - ].join('\n'); - return code; -}; /******************** */ /** Face Detection ** */ @@ -1707,73 +1600,6 @@ Blockly.JavaScript['ugj_sound_play'] = function (block) { return code; }; -/*************************** */ -/** Web Speech Recognization */ -/*************************** */ -Blockly.Blocks['ugj_multimedia_webspeech_recognition'] = { - init: function () { - this.appendDummyInput() - .appendField("音声認識で") - .appendField(new Blockly.FieldVariable("ことば"), "transcript") - .appendField("を取得する:") - .appendField(new Blockly.FieldDropdown([["一回のみ", "once"], ["継続", "continue"]]), "continuous") - .appendField(new Blockly.FieldCheckbox("TRUE"), "interim") - .appendField("未確定も取得"); - this.appendStatementInput("isFinal_do") - .setCheck(null) - .appendField("確定したら"); - this.appendStatementInput("isInterim_do") - .setCheck(null) - .appendField("未確定なら"); - this.appendStatementInput("onStart_do") - .setCheck(null) - .appendField("開始したら"); - this.appendStatementInput("onError_do") - .setCheck(null) - .appendField("停止したら"); - this.setInputsInline(true); - this.setPreviousStatement(true); - this.setStyle('multimedia_blocks') - this.setTooltip("Web Speech API による音声認識を行います。言葉を検知したらステートメントが実行されます。認識途中の暫定結果を取得することもできます。※Web版のみの機能です。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_multimedia_webspeech_recognition'] = function (block) { - var variable_transcript = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('transcript'), Blockly.Variables.NAME_TYPE); - var dropdown_continuous = block.getFieldValue('continuous'); - var checkbox_interim = block.getFieldValue('interim') == 'TRUE'; - var statements_isfinal_do = Blockly.JavaScript.statementToCode(block, 'isFinal_do'); - var statements_isinterim_do = Blockly.JavaScript.statementToCode(block, 'isInterim_do'); - var statements_onStart_do = Blockly.JavaScript.statementToCode(block, 'onStart_do'); - var statements_onEnd_do = Blockly.JavaScript.statementToCode(block, 'onError_do'); - var code = [ - `SpeechRecognition = webkitSpeechRecognition;`, - `let recognizer = new SpeechRecognition();`, - `recognizer.lang = 'ja-JP';` - ].join('\n'); - if (dropdown_continuous == 'continue') code += 'recognizer.continuous = true;\n'; - if (checkbox_interim == true) code += 'recognizer.interimResults = true;\n'; - code += [ - `recognizer.onresult = (event) => {`, - `let result = event.results[event.resultIndex];`, - `${variable_transcript} = result[0].transcript;`, - `if (result.isFinal) {`, - statements_isfinal_do, - `} else {`, - statements_isinterim_do, - `}`, - `}`, - `recognizer.onstart = () => {`, - statements_onStart_do, - `}`, - `recognizer.onend = () => {`, - statements_onEnd_do, - `}`, - `recognizer.start();`, - '' - ].join('\n'); - return code; -}; @@ -3168,183 +2994,3 @@ Blockly.JavaScript['ugj_control_button'] = function (block) { return code; }; - -/** Unused Blocks **********************************************************************************************/ - -/** Junk: ごみ置き場 廃止になったブロックを、必要なワークスペースの修正が完了するまで保持します。 *********************/ - -Blockly.Blocks['ugj_gpio_startstop'] = { - init: function () { - this.appendDummyInput() - .appendField("dummy"); - this.appendStatementInput("do") - .setCheck(null); - this.setColour(230); - this.setTooltip(""); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_gpio_startstop'] = function (block) { - var statements_do = Blockly.JavaScript.statementToCode(block, 'do'); - // TODO: Assemble JavaScript into code variable. - var code = '...;\n'; - return code; -}; - -/************ */ -/** Fetch API */ -/************ */ -Blockly.Blocks['ugj_network_fetch'] = { - init: function () { - this.appendValueInput("url") - .setCheck(null); - this.appendDummyInput() - .appendField("にリクエストを送信し、") - .appendField(new Blockly.FieldVariable("レスポンス"), "response") - .appendField("を取得する"); - this.appendStatementInput("do") - .setCheck(null); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setStyle('network_blocks') - this.setTooltip(""); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_network_fetch'] = function (block) { - var value_url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC); - var variable_response = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('response'), Blockly.Variables.NAME_TYPE); - var statements_do = Blockly.JavaScript.statementToCode(block, 'do'); var code = [ - `fetch(${value_url})`, - ` .then(response => {`, - ` if (response.ok) {`, - ` return response.text();`, - ` } else {`, - ` return 'HTTP Status: ' + response.status;`, - ` }`, - ` })`, - ` .then(body => {`, - ` ${variable_response} = body;`, - statements_do, - ` });`, - '' - ].join('\n'); - return code; -}; - - -/********************* */ -/** Print to Blackboard **/ -/********************* */ -Blockly.Blocks['ugj_texts_print'] = { - init: function () { - this.appendValueInput("text") - .setCheck(null) - this.appendDummyInput() - .appendField("を表示"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setColour(0); - this.setTooltip("テキストや数字などを黒板に表示します。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_texts_print'] = function (block) { - var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC); - var code = `ugj_blackboardWrite(${value_text});\n`; - return code; -}; - -/************************************** */ -/** Print Colorized Text to Blackboard ** */ -/************************************** */ -Blockly.Blocks['ugj_text_printcolored'] = { - init: function () { - this.appendValueInput("text") - .setCheck(null) - .appendField("黒板に"); - this.appendValueInput("color") - .setCheck("Colour") - .appendField("を"); - this.appendDummyInput() - .appendField("色で表示"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setColour(0); - this.setTooltip("テキストや数字などを黒板に色付きで表示します。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_text_printcolored'] = function (block) { - var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC); - var value_color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC); - var code = `ugj_blackboardWrite(${value_text}, ${value_color});\n`; - return code; -}; - -/******************************** */ -/** Open and Close Serial Port ** */ -/******************************** */ -Blockly.Blocks['ugj_serial_openclose'] = { - init: function () { - this.appendValueInput("tty") - .setCheck("String") - .appendField("シリアルポート"); - this.appendDummyInput() - .appendField("を速度") - .appendField(new Blockly.FieldDropdown([["9600", "9600"], ["19200", "19200"], ["115200", "115200"]]), "baud") - .appendField("bpsで開く"); - this.appendStatementInput("do") - .setCheck(null); - this.appendDummyInput() - .appendField("終わったらシリアルポートを閉じる"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setStyle('gpio_blocks') - this.setTooltip("シリアルデバイスとの接続を開き、用事が終わったら閉じます。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_serial_openclose'] = function (block) { - var value_tty = Blockly.JavaScript.valueToCode(block, 'tty', Blockly.JavaScript.ORDER_ATOMIC); - var dropdown_baud = block.getFieldValue('baud'); - var statements_do = Blockly.JavaScript.statementToCode(block, 'do'); - // TODO: Assemble JavaScript into code variable. - var code = [ - `let serhand = pi.serial_open(${value_tty}, ${dropdown_baud}, 0);`, - statements_do, - 'pi.serial_close(serhand);', - "" - ].join('\n'); - return code; -}; - -Blockly.Blocks['ugj_gpio_i2copenclose'] = { - init: function () { - this.appendValueInput("i2c_addr") - .setCheck("String") - .appendField("アドレス"); - this.appendDummyInput() - .appendField("の I2C デバイスを開く"); - this.appendStatementInput("do") - .setCheck(null); - this.appendDummyInput() - .appendField("デバイスを閉じる"); - this.setInputsInline(true); - this.setPreviousStatement(true, null); - this.setNextStatement(true, null); - this.setColour(230); - this.setTooltip("I2C接続されたデバイスと通信を行います。"); - this.setHelpUrl(""); - } -}; -Blockly.JavaScript['ugj_gpio_i2copenclose'] = function (block) { - var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC); - var statements_do = Blockly.JavaScript.statementToCode(block, 'do'); - // TODO: Assemble JavaScript into code variable. - var code = statements_do; - return code; -}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 13a202d..a7400d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -64,7 +64,7 @@ "@ocogeclub/bme280@file:local_modules/@ocogeclub/bme280": version "0.0.1" dependencies: - "@ocogeclub/lgpio" "file:../../.cache/yarn/v6/npm-@ocogeclub-bme280-0.0.1-d80e5826-f0f4-4db3-adae-fdd6a16c00e5-1632630994968/node_modules/@ocogeclub/lgpio" + "@ocogeclub/lgpio" "file:../../.cache/yarn/v6/npm-@ocogeclub-bme280-0.0.1-a3a7781d-d04c-4890-9c31-c037b0309492-1633696738699/node_modules/@ocogeclub/lgpio" "@ocogeclub/lgpio@file:local_modules/@ocogeclub/lgpio": version "0.0.1" @@ -72,6 +72,12 @@ bindings "^1.5.0" node-addon-api "^1.7.1" +"@ocogeclub/pigpio@file:local_modules/@ocogeclub/pigpio": + version "0.0.1" + dependencies: + bindings "^1.5.0" + node-addon-api "^1.7.1" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -219,14 +225,14 @@ form-data "^3.0.0" "@types/node@*": - version "16.9.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.6.tgz#040a64d7faf9e5d9e940357125f0963012e66f04" - integrity sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ== + version "16.10.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5" + integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ== "@types/node@^14.6.2": - version "14.17.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.18.tgz#0198489a751005f71217744aa966cd1f29447c81" - integrity sha512-haYyibw4pbteEhkSg0xdDLAI3679L75EJ799ymVrPxOA922bPx3ML59SoDsQ//rHlvqpu+e36kcbR3XRQtFblA== + version "14.17.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.21.tgz#6359d8cf73481e312a43886fa50afc70ce5592c6" + integrity sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA== "@types/offscreencanvas@~2019.3.0": version "2019.3.0" @@ -256,9 +262,9 @@ integrity sha512-oGaKsBbxQOY5+aJFV3KECDhGaXt+yZJt2y/OZsnQGLRkH6Fvr7rv4pCt3SRH1somIHfej/c4u7NSpCyd9x+1Ow== "@vladmandic/face-api@^1.5.3": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@vladmandic/face-api/-/face-api-1.5.3.tgz#517dc18535c537b2f3bb479874775ed4e6cf00ee" - integrity sha512-7u2GI/jeQg6ldGQItSHX/RM36Eic/Wpv14G8RVA3GBhOnkwP+JSfQpEUKtoAGYvvfX58jYy/AJcD2wMF9n24Iw== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@vladmandic/face-api/-/face-api-1.5.4.tgz#1b3e6f0f5e4e79f7e876d5ae32703ec811952e76" + integrity sha512-c7JUioHosPfkDKpj6mciYCrksSokmGCuAInzG6nC94bD5PtxgWFoVHiZpgdmwgX6IIBuXWoJMA2S4IJi9SYbtw== abbrev@1: version "1.1.1" @@ -266,9 +272,9 @@ abbrev@1: integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== adm-zip@^0.5.2: - version "0.5.6" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.6.tgz#c540f4d62b0f07a716bce4c8a24545b1f0b33027" - integrity sha512-nUeYhBHLG08VFOkVwai0pLXge6NNlahH+ccwxXodvl+SLa5l9mXHjg40jRVzofRPz29goiTGze7vIKmCltKtSA== + version "0.5.9" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.9.tgz#b33691028333821c0cf95c31374c5462f2905a83" + integrity sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg== agent-base@6, agent-base@^6.0.2: version "6.0.2" @@ -498,9 +504,9 @@ cli-cursor@^3.1.0: restore-cursor "^3.1.0" cli-spinners@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" - integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cliui@^7.0.2: version "7.0.4" @@ -581,9 +587,9 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= core-js@3, core-js@^3.6.5: - version "3.18.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.0.tgz#9af3f4a6df9ba3428a3fb1b171f1503b3f40cc49" - integrity sha512-WJeQqq6jOYgVgg4NrXKL0KLQhi0CT4ZOCvFL+3CQ5o7I6J8HkT5wd53EadMfqTDp1so/MT1J+w2ujhWcCJtN7w== + version "3.18.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.2.tgz#63a551e8a29f305cd4123754846e65896619ba5b" + integrity sha512-zNhPOUoSgoizoSQFdX1MeZO16ORRb9FFQLts8gSYbZU5FcgXhp24iMWMxnOQo5uIaIG7/6FA/IqJPwev1o9ZXQ== core-util-is@~1.0.0: version "1.0.3" @@ -926,9 +932,9 @@ globalthis@^1.0.1: define-properties "^1.1.3" google-protobuf@^3.9.2: - version "3.18.0" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.18.0.tgz#687449d8e858305d658dc1145852c306d8222f5a" - integrity sha512-WlaQWRkUOo/lm9uTgNH6nk9IQt814RggWPzKBfnAVewOFzSzRUSmS1yUWRT6ixW1vS7er5p6tmLSmwzpPpmc8A== + version "3.18.1" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.18.1.tgz#31de10b65e833aa5bbd44680e8a748fa54c920f6" + integrity sha512-cDqSamZ8rGs+pOzhIsBte7wpezUKg/sggeptDWN5odhnRY/eDLa5VWLeNeQvcfiqjS3yUwgM+6OePCJMB7aWZA== got@^11.7.0: version "11.8.2" @@ -1240,17 +1246,17 @@ matcher@^3.0.0: dependencies: escape-string-regexp "^4.0.0" -mime-db@1.49.0: - version "1.49.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" - integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== +mime-db@1.50.0: + version "1.50.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" + integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== mime-types@^2.1.12: - version "2.1.32" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" - integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== + version "2.1.33" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" + integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== dependencies: - mime-db "1.49.0" + mime-db "1.50.0" mimic-fn@^2.1.0: version "2.1.0" @@ -1751,9 +1757,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.4.tgz#366a4684d175b9cab2081e3681fda3747b6c51d7" - integrity sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q== + version "3.0.5" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" + integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== smart-buffer@^4.1.0: version "4.2.0" @@ -2037,9 +2043,9 @@ yargs@^16.0.3: yargs-parser "^20.2.2" yargs@^17.0.1: - version "17.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.0.tgz#ec529632b2cb9044f3927f4b45f9cc4ae2535653" - integrity sha512-UPeZv4h9Xv510ibpt5rdsUNzgD78nMa1rhxxCgvkKiq06hlKCEHJLiJ6Ub8zDg/wR6hedEI6ovnd2vCvJ4nusA== + version "17.2.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea" + integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q== dependencies: cliui "^7.0.2" escalade "^3.1.1"