mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-23 08:09:48 +00:00
[update] 指紋認証モジュール用ブロックを追加, rgpioモジュールのバグ修正, ファイル保存ダイアログの内部的変更など
This commit is contained in:
parent
8ac385c074
commit
8b8e01903e
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
node_modules/
|
node_modules*/
|
||||||
.shared/
|
.shared/
|
||||||
bin/
|
bin/
|
||||||
build/
|
build/
|
||||||
|
@ -50,6 +50,12 @@ class appTool {
|
|||||||
this.mascotFilePath = this.path.join(this.app_path, ugj_const.mascot_dirname, ugj_const.mascot_defname);
|
this.mascotFilePath = this.path.join(this.app_path, ugj_const.mascot_dirname, ugj_const.mascot_defname);
|
||||||
this.library_path = this.path.join(this.app_path, ugj_const.library_dirname);
|
this.library_path = this.path.join(this.app_path, ugj_const.library_dirname);
|
||||||
// this.blocks_dir = this.path.join(this.app_path, ugj_const.blocks_dir);
|
// this.blocks_dir = this.path.join(this.app_path, ugj_const.blocks_dir);
|
||||||
|
let ocogerc = this.path.join(process.env["HOME"], '.ocogerc');
|
||||||
|
if (this.fs.existsSync(ocogerc))
|
||||||
|
this.rghost = this.fs.readFileSync(ocogerc, 'utf8');
|
||||||
|
else
|
||||||
|
this.rghost = undefined;
|
||||||
|
this.breakout_table = JSON.parse(this.fs.readFileSync(this.path.join(this.library_path, 'breakout.json'), 'utf8'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0で数値の桁合わせ : NUM=値 LEN=桁数
|
// 0で数値の桁合わせ : NUM=値 LEN=桁数
|
||||||
@ -196,6 +202,7 @@ class appTool {
|
|||||||
// ファイル書き込み
|
// ファイル書き込み
|
||||||
writeToFile(filepath, data) {
|
writeToFile(filepath, data) {
|
||||||
try {
|
try {
|
||||||
|
console.log('Save file!!');
|
||||||
this.fs.writeFileSync(filepath, data);
|
this.fs.writeFileSync(filepath, data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,29 @@ python.pythonGenerator.forBlock['ugj_dectohex'] = function (block, generator) {
|
|||||||
/** GPIO 関連共通コード */
|
/** GPIO 関連共通コード */
|
||||||
// var require_gpio = [`const _rg = require('${apptool.gpio_lib}');`,
|
// var require_gpio = [`const _rg = require('${apptool.gpio_lib}');`,
|
||||||
// `await _rg.rgpio_sbc();`];
|
// `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 */
|
/** GPIO Open */
|
||||||
@ -209,12 +232,15 @@ Blockly.defineBlocksWithJsonArray([{
|
|||||||
"helpUrl": "",
|
"helpUrl": "",
|
||||||
"style": "gpio_blocks"
|
"style": "gpio_blocks"
|
||||||
}]);
|
}]);
|
||||||
javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator, generator) {
|
// javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator, generator) {
|
||||||
// javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
|
javascript.javascriptGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
|
||||||
Blockly.JavaScript.provideFunction_(
|
Blockly.JavaScript.provideFunction_(
|
||||||
'require_gpio', [`const _rg = require('${apptool.gpio_lib}');`]
|
'require_gpio', [`const _rg = require('${apptool.gpio_lib}');`]
|
||||||
);
|
);
|
||||||
|
if (apptool.rghost === undefined)
|
||||||
var code = `await _rg.rgpio_sbc();\n`; //
|
var code = `await _rg.rgpio_sbc();\n`; //
|
||||||
|
else
|
||||||
|
var code = `await _rg.rgpio_sbc(host="${apptool.rghost}");\n`;
|
||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
python.pythonGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
|
python.pythonGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
|
||||||
@ -224,6 +250,34 @@ python.pythonGenerator.forBlock['ugj_gpio_open'] = function (block, generator) {
|
|||||||
var code = `_pin = {}\n`; //
|
var code = `_pin = {}\n`; //
|
||||||
return code;
|
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 */
|
/** GPIO Close */
|
||||||
@ -378,13 +432,13 @@ var ugjGpioWriteDefinition = {
|
|||||||
"args0": [
|
"args0": [
|
||||||
{
|
{
|
||||||
"type": "input_value",
|
"type": "input_value",
|
||||||
"name": "gpio",
|
"name": "gpio"
|
||||||
"check": "Number"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "field_dropdown",
|
"type": "field_dropdown",
|
||||||
"name": "level",
|
"name": "level",
|
||||||
"options": [
|
"options":
|
||||||
|
[
|
||||||
[
|
[
|
||||||
"0",
|
"0",
|
||||||
"0"
|
"0"
|
||||||
|
@ -27,6 +27,7 @@ const registerCategory = (category_dir, subcategories) => {
|
|||||||
// センサーカテゴリ
|
// センサーカテゴリ
|
||||||
registerCategory('sensors', [ // サブカテゴリファイル名
|
registerCategory('sensors', [ // サブカテゴリファイル名
|
||||||
"amg8833.js",
|
"amg8833.js",
|
||||||
|
"sfmv17.js",
|
||||||
"paj7620.js",
|
"paj7620.js",
|
||||||
"bme280.js",
|
"bme280.js",
|
||||||
"ssd1306.js",
|
"ssd1306.js",
|
||||||
|
287
blocks/sensors/sfmv17.js
Normal file
287
blocks/sensors/sfmv17.js
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/****************************** */
|
||||||
|
/** SFM-V1.7 Fingerprint Sensor */
|
||||||
|
/****************************** */
|
||||||
|
|
||||||
|
// 初期化
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_init",
|
||||||
|
"message0": "指紋センサ(ポート %1 )に接続",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "port",
|
||||||
|
"check": "String"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "指紋センサ SFM-V1.7 とのシリアル通信を開始します。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_init'] = function (block, generator) {
|
||||||
|
var value_port = generator.valueToCode(block, 'port', javascript.Order.ATOMIC);
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_sfmv17', [`const _sfm = require('@ocoge/sfmv17');`]
|
||||||
|
);
|
||||||
|
var code = `await _sfm.init(_rg, ${value_port}, 115200);\n`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
// リングカラー
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_setringcolor",
|
||||||
|
"message0": "指紋センサ LED リング色: %1 ~ %2 %3 周期 %4 秒",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "start_color",
|
||||||
|
"options": [
|
||||||
|
[
|
||||||
|
"OFF",
|
||||||
|
"0x07"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"赤",
|
||||||
|
"0x03"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"緑",
|
||||||
|
"0x05"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"青",
|
||||||
|
"0x06"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"黄",
|
||||||
|
"0x01"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"紫",
|
||||||
|
"0x02"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"青緑(シアン)",
|
||||||
|
"0x04"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "end_color",
|
||||||
|
"options": [
|
||||||
|
[
|
||||||
|
"OFF",
|
||||||
|
"0x07"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"赤",
|
||||||
|
"0x03"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"緑",
|
||||||
|
"0x05"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"青",
|
||||||
|
"0x06"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"黄",
|
||||||
|
"0x01"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"紫",
|
||||||
|
"0x02"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"青緑(シアン)",
|
||||||
|
"0x04"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_dummy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "period_sec",
|
||||||
|
"check": "Number"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "指紋センサの LED リングの色を一定周期で切り替えます。周期は 0.3 秒から 2 秒までを指定できます。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_setringcolor'] = function (block, generator) {
|
||||||
|
var dropdown_start_color = block.getFieldValue('start_color');
|
||||||
|
var dropdown_end_color = block.getFieldValue('end_color');
|
||||||
|
var value_period_sec = generator.valueToCode(block, 'period_sec', javascript.Order.ATOMIC);
|
||||||
|
var code = `await _sfm.setRingColor(${dropdown_start_color}, ${dropdown_end_color}, ${value_period_sec}*1000);\n`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 記録済みユーザ数取得
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_getusercount",
|
||||||
|
"message0": "指紋登録数",
|
||||||
|
"output": "Number",
|
||||||
|
"tooltip": "データベースに記録された指紋の登録数を返します。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_getusercount'] = function (block, generator) {
|
||||||
|
var code = `await _sfm.getUserCount()`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 指紋認識
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_recognize",
|
||||||
|
"message0": "指紋 ID",
|
||||||
|
"output": "Number",
|
||||||
|
"tooltip": "指紋を認識します。データベースの指紋と一致した場合その ID を、一致しなければ 0 を、エラーの場合は -1 を返します。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_recognize'] = function (block, generator) {
|
||||||
|
var code = 'await _sfm.recognition_1vN()';
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 指紋登録
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_registration",
|
||||||
|
"message0": "指紋登録 %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "step",
|
||||||
|
"options": [
|
||||||
|
[
|
||||||
|
"#1",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"#2",
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"#3",
|
||||||
|
"3"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": null,
|
||||||
|
"tooltip": "指紋をモジュール内データベースに登録します。ステップ1からステップ3を行います。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_registration'] = function (block, generator) {
|
||||||
|
var dropdown_step = block.getFieldValue('step');
|
||||||
|
var code = `await _sfm.register_3c3r(${dropdown_step})`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全ユーザ一括削除
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_deletealluser",
|
||||||
|
"message0": "指紋一括削除",
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "指紋センサに登録されている指紋を全て削除します。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_deletealluser'] = function (block, generator) {
|
||||||
|
var code = `await _sfm.deleteAllUser();\n`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 切断
|
||||||
|
Blockly.defineBlocksWithJsonArray([{
|
||||||
|
"type": "oc_sfmv17_stop",
|
||||||
|
"message0": "指紋センサから切断",
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "指紋センサとのシリアル通信を終了してポートを開放します。",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
}]);
|
||||||
|
javascript.javascriptGenerator.forBlock['oc_sfmv17_stop'] = function (block, generator) {
|
||||||
|
var code = `await _sfm.stop();\n`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
flyout_contents = flyout_contents.concat([
|
||||||
|
{
|
||||||
|
"kind": "label",
|
||||||
|
"text": "指紋センサ SFM-V1.7",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_init",
|
||||||
|
"inputs": {
|
||||||
|
"port": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "text",
|
||||||
|
"fields": {
|
||||||
|
"TEXT": "/dev/ttyS0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_setringcolor",
|
||||||
|
"fields": {
|
||||||
|
"start_color": "0x03"
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"end_color": "0x07"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"period_sec": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "math_number",
|
||||||
|
"fields": {
|
||||||
|
"NUM": "0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_getusercount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_recognize"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_registration",
|
||||||
|
"fields": {
|
||||||
|
"step": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_deletealluser"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "oc_sfmv17_stop"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
10
index.html
10
index.html
@ -340,6 +340,13 @@
|
|||||||
<category name="GPIO" css-icon="customIcon fab fa-raspberry-pi" categorystyle="gpio_category">
|
<category name="GPIO" css-icon="customIcon fab fa-raspberry-pi" categorystyle="gpio_category">
|
||||||
<label text="基本"></label>
|
<label text="基本"></label>
|
||||||
<block type="ugj_gpio_open"></block>
|
<block type="ugj_gpio_open"></block>
|
||||||
|
<!-- <block type="oc_gpio_open_remote">
|
||||||
|
<value name="host">
|
||||||
|
<shadow type="text">
|
||||||
|
<field name="TEXT">192.168.0.120</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
</block> -->
|
||||||
<block type="ugj_gpio_close"></block>
|
<block type="ugj_gpio_close"></block>
|
||||||
<block type="oc_gpio_set_output">
|
<block type="oc_gpio_set_output">
|
||||||
<value name="ugpio">
|
<value name="ugpio">
|
||||||
@ -371,6 +378,9 @@
|
|||||||
</shadow>
|
</shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
|
<block type="oc_breakout">
|
||||||
|
<field name="gpio">35</field>
|
||||||
|
</block>
|
||||||
<label text="I2C" web-line="4.0" web-line-width="200"></label>
|
<label text="I2C" web-line="4.0" web-line-width="200"></label>
|
||||||
<block type="oc_i2c_open">
|
<block type="oc_i2c_open">
|
||||||
<field name="i2c_hand">I2Cデバイス</field>
|
<field name="i2c_hand">I2Cデバイス</field>
|
||||||
|
7
json.js
Normal file
7
json.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const foo = [["CE1", "35"], ["CE0", "52"], ["SCLK", "50"], ["MISO", "48"], ["MOSI", "49"], ["RXD", "132"], ["TXD", "131"], ["SCL", "46"], ["SDA", "47"], ["P0", "138"], ["P1", "29"], ["P2", "139"], ["P3", "28"], ["P4", "59"], ["P5", "58"], ["P6", "92"], ["P7", "54"]];
|
||||||
|
|
||||||
|
// console.log(foo["CE0"]);
|
||||||
|
|
||||||
|
let bar = JSON.stringify(foo);
|
||||||
|
|
||||||
|
console.log(bar);
|
1
lib/breakout.json
Executable file
1
lib/breakout.json
Executable file
@ -0,0 +1 @@
|
|||||||
|
["Raspberry Pi GPIO Extension Board V3.0 のピン名を Orange Pi 5 の GPIO 番号に変換します",[["CE1","35"],["CE0","52"],["SCLK","50"],["MISO","48"],["MOSI","49"],["RXD","132"],["TXD","131"],["SCL","46"],["SDA","47"],["P0","138"],["P1","29"],["P2","139"],["P3","28"],["P4","59"],["P5","58"],["P6","92"],["P7","54"]]]
|
@ -62,18 +62,21 @@ module.exports.serial_open = async (tty, baud, ser_flags = 0) => {
|
|||||||
module.exports.serial_close = async handle => {
|
module.exports.serial_close = async handle => {
|
||||||
await module.exports._serial_close(sbc, handle);
|
await module.exports._serial_close(sbc, handle);
|
||||||
}
|
}
|
||||||
module.exports.serial_read = async (handle, count = 0) => {
|
module.exports.serial_read = async (handle, count = 0, raw = false) => {
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
count = await module.exports._serial_data_available(sbc, handle);
|
count = await module.exports._serial_data_available(sbc, handle);
|
||||||
if (count === 0) return '';
|
if (count === 0) return '';
|
||||||
}
|
}
|
||||||
|
if (raw)
|
||||||
|
return await module.exports._serial_read(sbc, handle, count);
|
||||||
|
else
|
||||||
return new TextDecoder().decode(await module.exports._serial_read(sbc, handle, count));
|
return new TextDecoder().decode(await module.exports._serial_read(sbc, handle, count));
|
||||||
}
|
}
|
||||||
module.exports.serial_write = async (handle, data) => {
|
module.exports.serial_write = async (handle, data) => {
|
||||||
return await module.exports._serial_write(sbc, handle, Buffer.from(data), -1);
|
return await module.exports._serial_write(sbc, handle, Buffer.from(data), -1);
|
||||||
}
|
}
|
||||||
module.exports.serial_data_available = async handle => {
|
module.exports.serial_data_available = async handle => {
|
||||||
await module.exports._serial_data_available(sbc, handle);
|
return await module.exports._serial_data_available(sbc, handle);
|
||||||
}
|
}
|
||||||
module.exports.i2c_open = async (i2c_bus, i2c_address, i2c_flags = 0) => {
|
module.exports.i2c_open = async (i2c_bus, i2c_address, i2c_flags = 0) => {
|
||||||
return await module.exports._i2c_open(sbc, i2c_bus, i2c_address, i2c_flags);
|
return await module.exports._i2c_open(sbc, i2c_bus, i2c_address, i2c_flags);
|
||||||
|
7
local_modules/sfmv17/package.json
Normal file
7
local_modules/sfmv17/package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "@ocoge/sfmv17",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "sfmv17.js",
|
||||||
|
"private": true,
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
165
local_modules/sfmv17/sfmv17.js
Normal file
165
local_modules/sfmv17/sfmv17.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Private constance
|
||||||
|
|
||||||
|
const err_msg = 'Serial port already opened. Please close old connection to use new one.';
|
||||||
|
|
||||||
|
const SFM_SERIAL_TIMEOUT = 8000 // serial timeout (ms)
|
||||||
|
const SFM_DEFAULT_USERROLE = 0x03 // Default user role for register
|
||||||
|
|
||||||
|
const SFM_ACK_SUCCESS = 0x00 // Command successful
|
||||||
|
const SFM_ACK_FAIL = 0x01 // Command failed
|
||||||
|
const SFM_ACK_FULL = 0x04 // Database full
|
||||||
|
const SFM_ACK_NOUSER = 0x05 // User does not exist
|
||||||
|
const SFM_ACK_USER_EXIST = 0x07 // User exists
|
||||||
|
const SFM_ACK_TIMEOUT = 0x08 // Image collection timeout
|
||||||
|
const SFM_ACK_HWERROR = 0x0A // Hardware error
|
||||||
|
const SFM_ACK_IMGERROR = 0x10 // Image error
|
||||||
|
const SFM_ACK_BREAK = 0x18 // Stop current cmd
|
||||||
|
const SFM_ACK_ALGORITHMFAIL = 0x11 // Film/Mask attack detected
|
||||||
|
const SFM_ACK_HOMOLOGYFAIL = 0x12 // Homology check fail
|
||||||
|
const SFM_ACK_SERIALTIMEOUT = 0x13 // Serial receive time exceeds SFM_SERIAL_TIMEOUT
|
||||||
|
const SFM_ACK_IDLE = 0x14 // Module idle
|
||||||
|
|
||||||
|
// Public constance
|
||||||
|
|
||||||
|
exports.SFM_RING_OFF = 0x07 // Ring LED Off
|
||||||
|
exports.SFM_RING_RED = 0x03 // Ring Color Red
|
||||||
|
exports.SFM_RING_GREEN = 0x05 // Ring Color Green
|
||||||
|
exports.SFM_RING_BLUE = 0x06 // Ring Color Blue
|
||||||
|
exports.SFM_RING_YELLOW = 0x01 // Ring Color Yellow
|
||||||
|
exports.SFM_RING_PURPLE = 0x02 // Ring Color Purple
|
||||||
|
exports.SFM_RING_CYAN = 0x04 // Ring Color Cyan
|
||||||
|
|
||||||
|
// Public variables
|
||||||
|
|
||||||
|
exports.last_status = 0;
|
||||||
|
|
||||||
|
// Private variables
|
||||||
|
|
||||||
|
let rg;
|
||||||
|
let ser_hand = -1;
|
||||||
|
|
||||||
|
// Private Functions
|
||||||
|
|
||||||
|
// Delay usec
|
||||||
|
const delay = microsec =>
|
||||||
|
new Promise(r => setTimeout(r, microsec));
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
const getCheckSum = buffer => {
|
||||||
|
let result = 0;
|
||||||
|
for (let i = 1; i <= 5; i++) {
|
||||||
|
result ^= buffer[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send command to uart and retruns responce tuple
|
||||||
|
const sendCmd = async (cmdType, p1, p2, p3) => {
|
||||||
|
while (await rg.serial_data_available(ser_hand)) rg.serial_read(ser_hand);
|
||||||
|
let cmdBuffer = [0xF5, cmdType, p1, p2, p3, 0, 0, 0xF5];
|
||||||
|
cmdBuffer[6] = getCheckSum(cmdBuffer);
|
||||||
|
await rg.serial_write(ser_hand, cmdBuffer);
|
||||||
|
|
||||||
|
let ackBuffer = Buffer.from([]);
|
||||||
|
let timer = SFM_SERIAL_TIMEOUT;
|
||||||
|
while (timer--) {
|
||||||
|
if (await rg.serial_data_available(ser_hand)) {
|
||||||
|
ackBuffer = Buffer.concat([ackBuffer, await rg.serial_read(ser_hand, 0, true)]);
|
||||||
|
}
|
||||||
|
else if (ackBuffer.length >= 8) {
|
||||||
|
// console.log(ackBuffer);
|
||||||
|
if (ackBuffer[6] == getCheckSum(ackBuffer))
|
||||||
|
return [ackBuffer[4], ackBuffer[1], ackBuffer[2], ackBuffer[3]];
|
||||||
|
else
|
||||||
|
return [SFM_ACK_FAIL];
|
||||||
|
}
|
||||||
|
await delay(1);
|
||||||
|
}
|
||||||
|
return [SFM_ACK_SERIALTIMEOUT];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rapping sendCmd... Returns tuple
|
||||||
|
const getCmdReturn = async (cmdType, p1 = 0, p2 = 0, p3 = 0) => {
|
||||||
|
let [q3, ackType, q1, q2] = await sendCmd(cmdType, p1, p2, p3);
|
||||||
|
this.last_status = q3; // コマンド実行結果ステータスを保存
|
||||||
|
if (ackType == cmdType) return [q3, ackType, q1, q2];
|
||||||
|
else return [SFM_ACK_FAIL, 0, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize module... just connect uart
|
||||||
|
exports.init = async (_rg, serial_port, baud = 115200) => {
|
||||||
|
rg = _rg;
|
||||||
|
if (ser_hand >= 0) { throw new Error(err_msg); return; }
|
||||||
|
ser_hand = await rg.serial_open(serial_port, baud);
|
||||||
|
return ser_hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LED ring
|
||||||
|
exports.setRingColor = async (start_color, end_color = -1, period = 500) => {
|
||||||
|
period /= 10;
|
||||||
|
if (period < 30) period = 30;
|
||||||
|
else if (period > 200) period = 200;
|
||||||
|
if (end_color == -1) end_color = start_color;
|
||||||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0xC3, start_color, end_color, period);
|
||||||
|
return q3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count users
|
||||||
|
exports.getUserCount = async () => {
|
||||||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x09, 0x00, 0x00, 0x00);
|
||||||
|
let userCount = -1;
|
||||||
|
if (q3 != SFM_ACK_FAIL) userCount = (q1 << 8) | q2;
|
||||||
|
// else userCount = -1;
|
||||||
|
return userCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recognize fingerprint... returns userID / 0: not found / -1: error
|
||||||
|
exports.recognition_1vN = async () => {
|
||||||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x0C, 0x00, 0x00, 0x00);
|
||||||
|
let uid = (q1 << 8) | q2;
|
||||||
|
if (uid == 0 && q3 != SFM_ACK_SUCCESS) return -1;
|
||||||
|
else return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registration :
|
||||||
|
// step 1... returns success: 0 / fail: -1
|
||||||
|
// step 2... returns success: 0 / fail: -1
|
||||||
|
// step 3... returns new userID / fail: -1
|
||||||
|
exports.register_3c3r = async (step, uid = 0) => {
|
||||||
|
let q3, ackType, q1, q2;
|
||||||
|
if (step == 1) {
|
||||||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x01, (uid >> 8) & 0xFF, uid & 0xFF, SFM_DEFAULT_USERROLE);
|
||||||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||||||
|
else return -1;
|
||||||
|
} else if (step == 2) {
|
||||||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x02);
|
||||||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||||||
|
else return -1;
|
||||||
|
} else if (step == 3) {
|
||||||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x03, 0x00, 0x00, 0x00);
|
||||||
|
let uid = -1;
|
||||||
|
if (q3 == SFM_ACK_SUCCESS) uid = (q1 << 8) | q2;
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all users
|
||||||
|
exports.deleteAllUser = async () => {
|
||||||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x05);
|
||||||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect from uart
|
||||||
|
exports.stop = async () => {
|
||||||
|
if (ser_hand >= 0) {
|
||||||
|
await rg.serial_close(ser_hand);
|
||||||
|
ser_hand = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This library is forked from https://github.com/Matrixchung/SFM-V1.7/
|
||||||
|
*/
|
7
main.js
7
main.js
@ -285,14 +285,13 @@ ipcMain.handle('open_dialog', (ev, title, dpath, filter) => {
|
|||||||
})
|
})
|
||||||
return filepaths
|
return filepaths
|
||||||
})
|
})
|
||||||
ipcMain.handle('save_dialog', (ev, title, defName, filter) => {
|
ipcMain.handle('save_dialog', async (ev, title, defName, filter) => {
|
||||||
let filename = dialog.showSaveDialogSync(win, {
|
let save_file = await dialog.showSaveDialog(win, {
|
||||||
title: title,
|
title: title,
|
||||||
defaultPath: defName,
|
defaultPath: defName,
|
||||||
filters: [filter]
|
filters: [filter]
|
||||||
})
|
})
|
||||||
console.log(filename)
|
return save_file.filePath
|
||||||
return filename
|
|
||||||
})
|
})
|
||||||
ipcMain.handle('get_app_path', (ev) => {
|
ipcMain.handle('get_app_path', (ev) => {
|
||||||
return app.getAppPath()
|
return app.getAppPath()
|
||||||
|
7186
package-lock.json
generated
7186
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@ -22,29 +22,29 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://git.ocoge.club/ocoge.club/ocoge#readme",
|
"homepage": "https://git.ocoge.club/ocoge.club/ocoge#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron-forge/cli": "^7.2.0",
|
"@electron-forge/cli": "^7.4.0",
|
||||||
"@electron-forge/maker-deb": "^7.2.0",
|
"@electron-forge/maker-deb": "^7.4.0",
|
||||||
"@electron/rebuild": "^3.4.1",
|
"@electron/rebuild": "^3.6.0",
|
||||||
"electron": "^28.1.0"
|
"electron": "^30.0.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blockly/field-slider": "^6.1.4",
|
"@blockly/field-slider": "^6.1.10",
|
||||||
"@ocoge/amg8833": "file:local_modules/amg8833",
|
"@ocoge/amg8833": "file:local_modules/amg8833",
|
||||||
"@ocoge/bme280": "file:local_modules/bme280",
|
"@ocoge/bme280": "file:local_modules/bme280",
|
||||||
"@ocoge/paj7620": "file:local_modules/paj7620",
|
"@ocoge/paj7620": "file:local_modules/paj7620",
|
||||||
|
"@ocoge/sfmv17": "file:local_modules/sfmv17",
|
||||||
"@ocoge/ssd1306": "file:local_modules/ssd1306",
|
"@ocoge/ssd1306": "file:local_modules/ssd1306",
|
||||||
"@tensorflow-models/blazeface": "^0.1.0",
|
"@tensorflow-models/blazeface": "^0.1.0",
|
||||||
"@tensorflow-models/knn-classifier": "^1.2.6",
|
"@tensorflow-models/knn-classifier": "^1.2.6",
|
||||||
"@tensorflow-models/mobilenet": "^2.1.1",
|
"@tensorflow-models/mobilenet": "^2.1.1",
|
||||||
"@tensorflow-models/speech-commands": "^0.5.4",
|
"@tensorflow-models/speech-commands": "^0.5.4",
|
||||||
"@tensorflow/tfjs-node": "^4.15.0",
|
"@tensorflow/tfjs-node": "^4.19.0",
|
||||||
"axios": "^1.6.3",
|
"axios": "^1.6.8",
|
||||||
"blockly": "^10.3.0",
|
"blockly": "^10.4.3",
|
||||||
"canvas": "^2.11.2",
|
"canvas": "github:Automattic/node-canvas",
|
||||||
"dracula-prism": "^2.1.13",
|
"dracula-prism": "^2.1.16",
|
||||||
"js-beautify": "^1.14.11",
|
"js-beautify": "^1.15.1",
|
||||||
"node-abi": "^3.52.0",
|
"nodemailer": "^6.9.13",
|
||||||
"nodemailer": "^6.9.8",
|
|
||||||
"oled-font-pack": "^1.0.1",
|
"oled-font-pack": "^1.0.1",
|
||||||
"pngjs": "^7.0.0",
|
"pngjs": "^7.0.0",
|
||||||
"prismjs": "^1.29.0"
|
"prismjs": "^1.29.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user