mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-21 15:19:48 +00:00
[update] micropython i2c I/O の一部に対応
This commit is contained in:
parent
5cc7bb9662
commit
073bcd5d78
25
index.html
25
index.html
@ -102,35 +102,26 @@
|
||||
<block type="controls_whileUntil">
|
||||
<field name="MODE">WHILE</field>
|
||||
</block>
|
||||
<block type="ugj_control_for">
|
||||
<field name="crease">+</field>
|
||||
<value name="index">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="CP-q*|4;)+PZj!ExWdjr">番号</field>
|
||||
</block>
|
||||
</value>
|
||||
<value name="from">
|
||||
<block type="controls_for">
|
||||
<field name="VAR" id="oFFZ#D{*XbIVL=!W~X]w">番号</field>
|
||||
<value name="FROM">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="to">
|
||||
<value name="TO">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="by">
|
||||
<value name="BY">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">1</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="ugj_controls_foreach">
|
||||
<value name="item">
|
||||
<block type="variables_get">
|
||||
<field name="VAR" id="}LJbKt^CxR.FJ6a3T23v">項目</field>
|
||||
</block>
|
||||
</value>
|
||||
<block type="controls_forEach">
|
||||
<field name="VAR" id="k4+0elF%?J]_)8fo((-m">項目</field>
|
||||
</block>
|
||||
<block type="controls_flow_statements">
|
||||
<field name="FLOW">BREAK</field>
|
||||
@ -352,7 +343,7 @@
|
||||
<field name="level">1</field>
|
||||
</block>
|
||||
<block type="ugj_gpio_set_input">
|
||||
<field name="lflag">_pi.PULL_DOWN</field>
|
||||
<field name="lflag">PULL_DOWN</field>
|
||||
<value name="gpio">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">6</field>
|
||||
|
78
index.js
78
index.js
@ -76,6 +76,10 @@ var theme = Blockly.Theme.defineTheme('ocoge', {
|
||||
// Customize messages
|
||||
Blockly.Msg["CONTROLS_IF_MSG_THEN"] = "ならば";
|
||||
Blockly.Msg["CONTROLS_REPEAT_INPUT_DO"] = "";
|
||||
Blockly.Msg["CONTROLS_FOR_TITLE"] = "%1 を %2 から %3 まで %4 ずつ増やし(減らし)て";
|
||||
Blockly.Msg["CONTROLS_FOR_TOOLTIP"] = "インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。";
|
||||
Blockly.Msg["CONTROLS_FOREACH_TITLE"] = "リスト%2の各%1について";
|
||||
Blockly.Msg["CONTROLS_FOREACH_TOOLTIP"] = "リストの各項目について、その項目を変数「項目」としてステートメントを実行します。";
|
||||
Blockly.Msg["MATH_CHANGE_TITLE"] = "変数 %1 を %2 増やす";
|
||||
Blockly.Msg["VARIABLES_SET"] = "変数 %1 を %2 にする";
|
||||
// Blockly.Msg["TEXT_PRINT_TITLE"] = "ダイアログに %1 を表示";
|
||||
@ -313,22 +317,9 @@ const ugj_loadWorkspace = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// // Python コードフォーマッタ YAPF をコール
|
||||
// const ugj_pyBeautify = (code) => {
|
||||
// let formatted;
|
||||
// formatted = window.ocogeapi.child_process.spawnSync('python3', ['-m', 'yapf'], { input: code }).stdout.toString();
|
||||
// return formatted;
|
||||
// }
|
||||
// Python コードフォーマッタ Black をコール
|
||||
const ugj_pyBeautify = (code) => {
|
||||
let formatted = '';
|
||||
// // formatted = window.ocogeapi.child_process.spawnSync('python3', ['-m', 'black', '-'], { input: code }).stdout.toString();
|
||||
// try {
|
||||
// formatted = require('child_process').spawnSync('python3', ['-m', 'black', '-'], { input: code }).stdout.toString();
|
||||
// } catch (e) {
|
||||
// formatted = code;
|
||||
// console.log('Python formatter "Black" is not found.');
|
||||
// }
|
||||
formatted = require('child_process').spawnSync('python3', ['-m', 'black', '-'], { input: code }).stdout.toString();
|
||||
if (!formatted) formatted = code;
|
||||
return formatted;
|
||||
@ -349,7 +340,6 @@ const ugj_createCode = (args) => {
|
||||
window.alert('Python 非対応のブロックが使用されています。\n' + e.message);
|
||||
code = '';
|
||||
}
|
||||
// code = Blockly.Python.workspaceToCode(workspace);
|
||||
}
|
||||
else { // Javascript コード出力
|
||||
code = Blockly.JavaScript.workspaceToCode(workspace);
|
||||
@ -380,44 +370,6 @@ const ugj_createCode = (args) => {
|
||||
}
|
||||
|
||||
// ブロックスクリプト実行
|
||||
// var is_running = false;
|
||||
// var worker;
|
||||
// const ugj_runCode = async () => {
|
||||
// const {
|
||||
// Worker,
|
||||
// isMainThread,
|
||||
// setEnvironmentData,
|
||||
// getEnvironmentData,
|
||||
// } = require('worker_threads');
|
||||
// const stop_icon = `<i class="fas fa-ban"></i> 停止`;
|
||||
// const run_icon = `<i class="fas fa-play-circle"></i> 実行`;
|
||||
// document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
||||
|
||||
// let btnel = document.getElementById('runbtn');
|
||||
// if (is_running) {
|
||||
// worker.terminate();
|
||||
// } else {
|
||||
// if (isMainThread) {
|
||||
// btnel.innerHTML = stop_icon;
|
||||
// let code = ugj_createCode({});
|
||||
// setEnvironmentData('code', code);
|
||||
// worker = new Worker(__filename);
|
||||
// // worker.on('exit', (excode) => {
|
||||
// // btnel.innerHTML = run_icon;
|
||||
// // });
|
||||
// // } else {
|
||||
// // let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
|
||||
// // let ocogeFunc = new AsyncFunction(getEnvironmentData('code'));
|
||||
// // await ocogeFunc().catch(e => { console.error(e); });
|
||||
// }
|
||||
// }
|
||||
|
||||
// is_running = !is_running;
|
||||
// if (is_running) btnel.innerHTML = stop_icon;
|
||||
// else btnel.innerHTML = run_icon;
|
||||
|
||||
|
||||
// }
|
||||
const ugj_runCode = async () => {
|
||||
if (elutil.lang == 'js') {
|
||||
document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
||||
@ -445,8 +397,8 @@ const ugj_spawnPyboard = (code, mode) => {
|
||||
p.stderr.on('data', d => { console.error(d.toString()) });
|
||||
p.stdout.on('data', d => { console.log(d.toString()) });
|
||||
p.on('close', c => {
|
||||
if (c == 0) console.log(`正常終了`);
|
||||
else window.alert(`エラーが発生しました。詳しくはコンソールを参照してください。`);
|
||||
if (c == 0) console.log(`コード実行 OK`);
|
||||
else _fukidashi(`実行時エラーが発生しました。詳しくはコンソールを参照してください。`, 5);
|
||||
});
|
||||
}
|
||||
|
||||
@ -454,13 +406,11 @@ const ugj_spawnPyboard = (code, mode) => {
|
||||
// エレメントのオブジェクトとかコールバックとか Python対応とか
|
||||
// 色々この中で完結させてみる
|
||||
const ugj_showCode = () => {
|
||||
// var ext = 'js';
|
||||
var ext = elutil.lang;
|
||||
const dialog = document.getElementById('codeDlg');
|
||||
const content = document.getElementById('dlgContent');
|
||||
const btn_close = document.getElementById('dlgClose');
|
||||
const btn_export = document.getElementById('dlgExport');
|
||||
// const chkbox_cli = document.getElementById('dlgCli');
|
||||
|
||||
const dialog_title = document.getElementById('dlgTitle');
|
||||
|
||||
@ -484,7 +434,6 @@ const ugj_showCode = () => {
|
||||
const export_cb = () => {
|
||||
if (ext == 'js') {
|
||||
let code = ugj_createCode({ 'ext': ext, 'async': true, 'beautify': true });
|
||||
// if (elutil.saveFile(code, ext) === false) window.alert('保存できませんでした。');
|
||||
save_to_file(code);
|
||||
} else {
|
||||
let code = ugj_createCode({ 'ext': 'py', 'beautify': true });
|
||||
@ -493,23 +442,18 @@ const ugj_showCode = () => {
|
||||
close_cb();
|
||||
}
|
||||
const keyev_cb = ev => {
|
||||
if (ev.key == 'c' && ext == 'js') {
|
||||
// CLI モード
|
||||
if (ev.key == 's' && ev.ctrlKey) {
|
||||
let code = ugj_createCode({ 'ext': ext, 'async': true, 'beautify': true });
|
||||
if (ext == 'js') {
|
||||
// JS-CLI モード
|
||||
// blackboardWrite()とwindow.alert()、fukidashi()をconsole.log()に書き換え、
|
||||
// document... と ugj_... と elutil... をコメントアウト(ブラウザ関連部分の追放という意味では不完全なので注意)
|
||||
// あと正規表現もいい加減
|
||||
let code = ugj_createCode({ 'ext': ext, 'async': true, 'beautify': true });
|
||||
code = code.replace(/const appendDiv[^#]*\/\/#/gm, 'const blackboardWrite = text => console.log(text);').replace('window.alert', 'console.log').replace(/_fukidashi(.*), \d+(\);)/gm, 'console.log$1$2').replace(/(^(?=.*document.)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*ugj_)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*elutil.)[^;]*;)/gm, '/* $1 */');
|
||||
// if (elutil.saveFile(code, ext) === false) window.alert('保存できませんでした。');
|
||||
save_to_file(code);
|
||||
close_cb();
|
||||
} else if (ev.key == 'f' && ext == 'py') {
|
||||
let code = ugj_createCode({ 'ext': ext, 'beautify': true });
|
||||
// if (elutil.saveFile(code, ext) === false) window.alert('保存できませんでした。');
|
||||
}
|
||||
save_to_file(code);
|
||||
close_cb();
|
||||
}
|
||||
|
||||
}
|
||||
btn_close.addEventListener('click', close_cb);
|
||||
btn_export.addEventListener('click', export_cb);
|
||||
|
@ -229,7 +229,7 @@ class elUtil {
|
||||
filter = { name: 'text file', extensions: ['txt'] };
|
||||
}
|
||||
let filename = await this.ipcRenderer.invoke('save_dialog', title, defName, filter);
|
||||
this.doc_current = this.path.dirname(filename);
|
||||
if (filename) this.doc_current = this.path.dirname(filename);
|
||||
return filename;
|
||||
}
|
||||
// ファイル書き込み
|
||||
|
220
lib/pybfm.py
220
lib/pybfm.py
@ -7,7 +7,16 @@ import os
|
||||
import sys
|
||||
import pyboard
|
||||
import serial.tools.list_ports
|
||||
from tkinter import messagebox
|
||||
from tkinter import filedialog
|
||||
|
||||
##### 引数 #####
|
||||
args = sys.argv
|
||||
try:
|
||||
dev = args[1]
|
||||
except IndexError as err:
|
||||
dev = False
|
||||
else:
|
||||
dev = (dev=='-f')
|
||||
|
||||
##### グローバル変数 #####
|
||||
gport = None
|
||||
@ -16,118 +25,168 @@ gport = None
|
||||
# リストボックスにドロップ
|
||||
def listbox_drop(event):
|
||||
files = listbox.tk.splitlist(event.data)
|
||||
for f in files:
|
||||
if os.path.exists(f):
|
||||
print('Dropped file: "%s"' % f)
|
||||
if os.path.isfile(f):
|
||||
putfile(f)
|
||||
filelist()
|
||||
else:
|
||||
messagebox.showwarning('Warning', 'フォルダは転送できません')
|
||||
else:
|
||||
print('Not dropping file "%s": file does not exist.' % f)
|
||||
|
||||
putfiles(files)
|
||||
# キーボード
|
||||
def input_key(ev):
|
||||
# print(ev)
|
||||
if ev.keysym == 'F5':
|
||||
filelist()
|
||||
reload()
|
||||
elif ev.keysym == 'Delete':
|
||||
selected = listbox.curselection()
|
||||
for i in selected:
|
||||
src = listbox.get(i)
|
||||
call_pybfunc('fs_rm', src)
|
||||
print('Deleted %s' % src)
|
||||
if len(selected):
|
||||
filelist()
|
||||
|
||||
def on_closing(errmsg=''):
|
||||
if errmsg:
|
||||
messagebox.showerror('Error', errmsg)
|
||||
root.destroy()
|
||||
sys.exit(0)
|
||||
rmfiles()
|
||||
# ダブルクリック
|
||||
def dbl_click(ev):
|
||||
run()
|
||||
# 右クリックメニュー
|
||||
def pop_menu(ev):
|
||||
listbox.select_clear(0, END)
|
||||
listbox.select_set(listbox.nearest(ev.y))
|
||||
pmenu.post(ev.x_root, ev.y_root)
|
||||
|
||||
##### pyboard関数 #####
|
||||
|
||||
# 接続・repl開始
|
||||
def connect():
|
||||
global gport
|
||||
try:
|
||||
pyb = pyboard.Pyboard(gport)
|
||||
pyb.enter_raw_repl()
|
||||
except pyboard.PyboardError as err:
|
||||
gport = None
|
||||
listbox.delete(0, END)
|
||||
set_title('Lost device : Please reload')
|
||||
raise pyboard.PyboardError('Lost device')
|
||||
pyb.enter_raw_repl(False)
|
||||
return pyb
|
||||
except:
|
||||
on_closing('デバイスに接続できません')
|
||||
|
||||
# repl終了・切断
|
||||
def disconnect(pyb):
|
||||
try:
|
||||
pyb.exit_raw_repl()
|
||||
pyb.close()
|
||||
except:
|
||||
on_closing('切断に失敗しました')
|
||||
|
||||
|
||||
# コマンド実行
|
||||
def exec_command(cmd):
|
||||
pyb = connect()
|
||||
except Exception as err:
|
||||
pass
|
||||
try:
|
||||
retval = pyb.exec_(cmd)
|
||||
except:
|
||||
on_closing('コマンド実行時にエラーが発生しました')
|
||||
disconnect(pyb)
|
||||
return retval.decode('utf-8')
|
||||
|
||||
# pyboard.py の関数をコール
|
||||
def call_pybfunc(funcname, *args):
|
||||
pyb.close()
|
||||
except Exception as err:
|
||||
pass
|
||||
# ファイル送信 (複数可)(files: list of local filepath)
|
||||
def putfiles(files):
|
||||
pyb = connect()
|
||||
if funcname=='fs_put':
|
||||
pyb.fs_put(args[0], args[1])
|
||||
elif funcname=='fs_rm':
|
||||
pyb.fs_rm(args[0])
|
||||
|
||||
for src in files:
|
||||
if os.path.exists(src):
|
||||
if os.path.isfile(src):
|
||||
dest = os.path.basename(src)
|
||||
print('ファイル "%s" を転送' % src)
|
||||
pyb.fs_put(src, dest)
|
||||
else:
|
||||
print('フォルダは転送できません : %s' % src)
|
||||
else:
|
||||
print('ファイル "%s" は見つかりません。' % f)
|
||||
ls(pyb)
|
||||
disconnect(pyb)
|
||||
|
||||
def initialize():
|
||||
# ポートスキャン:アルファベット順で一番若いポートを返す
|
||||
def find_device():
|
||||
global gport
|
||||
for p in sorted(serial.tools.list_ports.comports()):
|
||||
if p.hwid.startswith('USB'):
|
||||
gport = p.device
|
||||
set_title(gport)
|
||||
filelist()
|
||||
break
|
||||
else:
|
||||
on_closing('デバイスがみつかりません')
|
||||
|
||||
def list_clear():
|
||||
listbox.delete(0, END)
|
||||
|
||||
def filelist():
|
||||
list_clear()
|
||||
files = ls()
|
||||
for f in files:
|
||||
listbox.insert(END, f)
|
||||
|
||||
def ls(src='/'):
|
||||
gport = None
|
||||
set_title('No device')
|
||||
raise OSError('Device not found')
|
||||
# 再読込:ここのみデバイスの再スキャンが入る
|
||||
def reload():
|
||||
if not gport:
|
||||
find_device()
|
||||
if gport:
|
||||
listfiles()
|
||||
# ファイルリスト取得だけを行う
|
||||
def listfiles():
|
||||
pyb = connect()
|
||||
ls(pyb)
|
||||
disconnect(pyb)
|
||||
# ファイルリストを取得し、リストボックスに表示 (pyb: pyboard handle, src: target directory on device)
|
||||
def ls(pyb, src='/'):
|
||||
cmd = (
|
||||
"import uos\nfor f in uos.listdir(%s):\n"
|
||||
" print(f)"
|
||||
% (("'%s'" % src) if src else "")
|
||||
)
|
||||
retval = exec_command(cmd)
|
||||
return retval.splitlines()
|
||||
|
||||
def putfile(src):
|
||||
dest = os.path.basename(src)
|
||||
call_pybfunc('fs_put', src, dest)
|
||||
|
||||
retval = pyb.exec(cmd)
|
||||
files = retval.decode('utf-8').splitlines()
|
||||
listbox.delete(0, END)
|
||||
for f in files:
|
||||
listbox.insert(END, f)
|
||||
# ウィンドウタイトル (title: string)
|
||||
def set_title(title):
|
||||
root.title('PyBfm - ' + title)
|
||||
# デバイス上のファイルを実行
|
||||
def run(follow=False):
|
||||
selected = listbox.curselection()
|
||||
if len(selected):
|
||||
src = listbox.get(selected[0])
|
||||
ext = os.path.splitext(src)[1]
|
||||
if ext == '.py':
|
||||
cmd = 'exec(open("%s").read())' % src
|
||||
pyb = connect()
|
||||
try:
|
||||
if follow:
|
||||
print (pyb.exec(cmd).decode('utf-8'))
|
||||
else:
|
||||
pyb.exec_raw_no_follow(cmd)
|
||||
except Exception as err:
|
||||
print("Runtime error.")
|
||||
print('Done.')
|
||||
disconnect(pyb)
|
||||
else:
|
||||
print('このファイルは実行できません')
|
||||
# ファイル選択ダイアログからファイル送信
|
||||
def putdlg():
|
||||
fpath = filedialog.askopenfilename()
|
||||
if fpath:
|
||||
putfiles([fpath])
|
||||
# ファイル受信
|
||||
def getfile():
|
||||
selected = listbox.curselection()
|
||||
if len(selected):
|
||||
src = listbox.get(selected[0])
|
||||
ext = os.path.splitext(src)[1]
|
||||
dest = filedialog.asksaveasfilename(
|
||||
initialfile=src,
|
||||
defaultextension=ext,
|
||||
filetypes=[('変更なし', ext), ('全てのファイル', '.*')]
|
||||
)
|
||||
if dest:
|
||||
pyb = connect()
|
||||
pyb.fs_get(src, dest)
|
||||
disconnect(pyb)
|
||||
# デバイス上のファイル削除(複数可)
|
||||
def rmfiles():
|
||||
selected = listbox.curselection()
|
||||
if len(selected):
|
||||
pyb = connect()
|
||||
for i in selected:
|
||||
src = listbox.get(i)
|
||||
pyb.fs_rm(src)
|
||||
print('Deleted %s' % src)
|
||||
ls(pyb)
|
||||
disconnect(pyb)
|
||||
# 何もしない関数
|
||||
def do_nothing():
|
||||
pass
|
||||
|
||||
##### メイン #####
|
||||
|
||||
# メインウィンドウの生成
|
||||
root = TkinterDnD.Tk()
|
||||
root.protocol("WM_DELETE_WINDOW", on_closing)
|
||||
root.title('PyBfm')
|
||||
root.geometry('400x300')
|
||||
pmenu = Menu(root, tearoff=0)
|
||||
pmenu.add_command(label="実行", command=run)
|
||||
if dev:
|
||||
pmenu.add_command(label="実行 (追跡)", command=lambda:run(True))
|
||||
pmenu.add_command(label="送る", command=putdlg)
|
||||
pmenu.add_command(label="取得", command=getfile)
|
||||
pmenu.add_command(label="削除", command=rmfiles)
|
||||
pmenu.add_command(label="再読込", command=reload)
|
||||
pmenu.add_command(label="閉じる", command=do_nothing)
|
||||
# root.config(bg='#cccccc')
|
||||
# Frameウィジェットの生成
|
||||
frame = Frame(root)
|
||||
@ -136,6 +195,8 @@ listbox = Listbox(frame, selectmode=EXTENDED)
|
||||
listbox.drop_target_register(DND_FILES)
|
||||
listbox.dnd_bind('<<Drop>>', listbox_drop)
|
||||
listbox.bind("<KeyPress>", input_key)
|
||||
listbox.bind("<Double-Button-1>", dbl_click)
|
||||
listbox.bind("<Button-3>", pop_menu)
|
||||
# スクロールバーの生成
|
||||
scroll = Scrollbar(frame, orient=VERTICAL)
|
||||
listbox.configure(yscrollcommand=scroll.set)
|
||||
@ -145,6 +206,11 @@ frame.pack(expand=True,fill=BOTH)
|
||||
listbox.pack(expand=True,fill=BOTH, side=LEFT)
|
||||
scroll.pack(side=RIGHT, fill=Y)
|
||||
|
||||
initialize()
|
||||
try:
|
||||
find_device()
|
||||
except Exception as err:
|
||||
pass
|
||||
else:
|
||||
listfiles()
|
||||
|
||||
root.mainloop()
|
@ -26,7 +26,7 @@ pyb.enter_raw_repl()
|
||||
|
||||
if mode == 'r':
|
||||
print('Run code', flush=True)
|
||||
pyb.exec(src)
|
||||
pyb.exec_raw_no_follow(src)
|
||||
elif mode == 'd':
|
||||
print('Deploy code', flush=True)
|
||||
pyb.exec("f=open('%s','wb')\nw=f.write" % dest)
|
||||
@ -43,3 +43,4 @@ elif mode == 'd':
|
||||
pyb.exec("f.close()")
|
||||
|
||||
pyb.exit_raw_repl()
|
||||
pyb.close()
|
||||
|
2248
package-lock.json
generated
2248
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ocoge",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"description": "ブロックベースビジュアルプログラム開発・実行環境",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
@ -22,9 +22,9 @@
|
||||
},
|
||||
"homepage": "https://git.ocoge.club/ocoge.club/ocoge#readme",
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.0-beta.64",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.64",
|
||||
"electron": "^19.0.8",
|
||||
"@electron-forge/cli": "^6.0.0-beta.65",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.65",
|
||||
"electron": "^19.0.9",
|
||||
"electron-rebuild": "^3.2.8"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -32,8 +32,8 @@
|
||||
"@tensorflow-models/blazeface": "^0.0.7",
|
||||
"@tensorflow-models/knn-classifier": "^1.2.4",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
"@tensorflow/tfjs": "^3.18.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^3.18.0",
|
||||
"@tensorflow/tfjs": "^3.19.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^3.19.0",
|
||||
"axios": "^0.27.2",
|
||||
"node-abi": "^3.22.0",
|
||||
"nodemailer": "^6.7.7",
|
||||
|
310
ugj_blocks.js
310
ugj_blocks.js
@ -1,101 +1,3 @@
|
||||
/** Fix Basic Blocks ****************************************************************************************/
|
||||
Blockly.Blocks['ugj_control_for'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("index")
|
||||
.setCheck("Variable");
|
||||
this.appendValueInput("from")
|
||||
.setCheck("Number")
|
||||
.appendField("を");
|
||||
this.appendValueInput("to")
|
||||
.setCheck("Number")
|
||||
.appendField("から");
|
||||
this.appendValueInput("by")
|
||||
.setCheck("Number")
|
||||
.appendField("まで");
|
||||
this.appendDummyInput()
|
||||
.appendField("ずつ")
|
||||
.appendField(new Blockly.FieldDropdown([["増やして", "+"], ["減らして", "-"]]), "crease");
|
||||
this.appendStatementInput("do")
|
||||
.setCheck(null);
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('loop_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['ugj_control_for'] = function (block) {
|
||||
var value_index = Blockly.JavaScript.valueToCode(block, 'index', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// var variable_index = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||||
var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_to = Blockly.JavaScript.valueToCode(block, 'to', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_by = Blockly.JavaScript.valueToCode(block, 'by', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var dropdown_crease = block.getFieldValue('crease');
|
||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||
let daishou;
|
||||
if (dropdown_crease == '+') { daishou = '<'; }
|
||||
else { daishou = '>'; }
|
||||
var code = [
|
||||
`for (${value_index} = ${value_from}; ${value_index} ${daishou}= ${value_to}; ${value_index} ${dropdown_crease}= ${Math.abs(value_by)}) {`,
|
||||
statements_do,
|
||||
`}`,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
Blockly.Python['ugj_control_for'] = function (block) {
|
||||
var variable_index = Blockly.Python.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||||
var value_from = Blockly.Python.valueToCode(block, 'from', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_to = Blockly.Python.valueToCode(block, 'to', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_by = Blockly.Python.valueToCode(block, 'by', Blockly.Python.ORDER_ATOMIC);
|
||||
var dropdown_crease = block.getFieldValue('crease');
|
||||
var statements_do = Blockly.Python.statementToCode(block, 'do');
|
||||
if (statements_do === '') statements_do = ' pass';
|
||||
if (dropdown_crease == '+') { value_by = Math.abs(value_by); value_to++; }
|
||||
else { value_by = Math.abs(value_by) * (-1); value_to--; }
|
||||
var code = [
|
||||
`for ${variable_index} in range(${value_from}, ${value_to}, ${value_by}) :`,
|
||||
statements_do,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['ugj_controls_foreach'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("list")
|
||||
.setCheck("Array")
|
||||
.appendField("リスト");
|
||||
this.appendValueInput("item")
|
||||
.setCheck("Variable")
|
||||
.appendField("の各");
|
||||
this.appendDummyInput()
|
||||
.appendField("について");
|
||||
this.appendStatementInput("do")
|
||||
.setCheck(null);
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("リストの各項目について、その項目の内容を変数「項目」に代入してステートメントを実行します。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('loop_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['ugj_controls_foreach'] = function (block) {
|
||||
var value_list = Blockly.JavaScript.valueToCode(block, 'list', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_item = Blockly.JavaScript.valueToCode(block, 'item', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||
var code = [
|
||||
`for (let _index in ${value_list}) {`,
|
||||
`${value_item} = ${value_list}[_index];`,
|
||||
statements_do,
|
||||
`}`,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
|
||||
// Custom Color Picker
|
||||
Blockly.FieldColour.COLOURS = [
|
||||
'#ffffff', '#808000', '#ffff00', '#ff00ff', '#ff4500',
|
||||
@ -193,6 +95,11 @@ Blockly.JavaScript['ugj_bintodec'] = function (block) {
|
||||
var code = `parseInt (${value_bin}, 2)`;
|
||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||
};
|
||||
Blockly.Python['ugj_bintodec'] = function (block) {
|
||||
var value_bin = Blockly.Python.valueToCode(block, 'bin', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `int(${value_bin}, 2)`;
|
||||
return [code, Blockly.Python.ORDER_NONE];
|
||||
};
|
||||
|
||||
var ugjHextodecDefinition = {
|
||||
"type": "ugj_hextodec",
|
||||
@ -254,7 +161,7 @@ Blockly.JavaScript['ugj_dectohex'] = function (block) {
|
||||
};
|
||||
Blockly.Python['ugj_dectohex'] = function (block) {
|
||||
var value_dec = Blockly.Python.valueToCode(block, 'dec', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `'0x' + format(${value_dec}, 'X')`;
|
||||
var code = `f'{${value_dec}:#04x}'`;
|
||||
return [code, Blockly.Python.ORDER_NONE];
|
||||
};
|
||||
/** GPIO *****************************************************************************************************/
|
||||
@ -371,15 +278,15 @@ var ugjGpioSetInputDefinition = {
|
||||
"options": [
|
||||
[
|
||||
"%{BKY_GPIO_SET_INPUT_PULLUP}",
|
||||
"_pi.PULL_UP"
|
||||
"PULL_UP"
|
||||
],
|
||||
[
|
||||
"%{BKY_GPIO_SET_INPUT_PULLDOWN}",
|
||||
"_pi.PULL_DOWN"
|
||||
"PULL_DOWN"
|
||||
],
|
||||
[
|
||||
"%{BKY_GPIO_SET_INPUT_PULLNONE}",
|
||||
"_pi.PULL_NONE"
|
||||
"PULL_NONE"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -399,15 +306,18 @@ Blockly.Blocks['ugj_gpio_set_input'] = {
|
||||
Blockly.JavaScript['ugj_gpio_set_input'] = function (block) {
|
||||
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var dropdown_lflag = block.getFieldValue('lflag');
|
||||
var code = `await _pi.gpio_set_input(${value_gpio}, ${dropdown_lflag});\n`;
|
||||
var code = `await _pi.gpio_set_input(${value_gpio}, _pi.${dropdown_lflag});\n`;
|
||||
return code;
|
||||
};
|
||||
Blockly.Python['ugj_gpio_set_input'] = function (block) {
|
||||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
var dropdown_lflag = block.getFieldValue('lflag');
|
||||
let lflag;
|
||||
if (dropdown_lflag == 'PULL_NONE') { lflag = 'None'; }
|
||||
else { lflag = `Pin.${dropdown_lflag}`; }
|
||||
var code = `_pin[${value_gpio}] = Pin(${value_gpio}, Pin.IN, ${lflag})\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_gpio_set_input'] = function (block) {
|
||||
// var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
// var dropdown_lflag = block.getFieldValue('lflag');
|
||||
// var code = `\n`;
|
||||
// return code;
|
||||
// };
|
||||
|
||||
/********************* */
|
||||
/** Read GPIO Value ** */
|
||||
@ -438,11 +348,11 @@ Blockly.JavaScript['ugj_gpio_read'] = function (block) {
|
||||
var code = `await _pi.gpio_read(${value_gpio})`;
|
||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||
};
|
||||
// Blockly.Python['ugj_gpio_read'] = function (block) {
|
||||
// var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
// var code = ``;
|
||||
// return [code, Blockly.Python.ORDER_NONE];
|
||||
// };
|
||||
Blockly.Python['ugj_gpio_read'] = function (block) {
|
||||
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `_pin[${value_gpio}].value()`;
|
||||
return [code, Blockly.Python.ORDER_NONE];
|
||||
};
|
||||
|
||||
/*******************************************/
|
||||
/** GPIO Write Value - Common GPIO on/off **/
|
||||
@ -775,14 +685,15 @@ Blockly.JavaScript['ugj_i2c_open'] = function (block) {
|
||||
var code = `await _pi.i2c_open(${elutil.i2c_bus}, ${value_i2c_address});\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_i2c_open'] = function (block) {
|
||||
// var value_i2c_address = Blockly.Python.valueToCode(block, 'i2c_address', Blockly.Python.ORDER_ATOMIC);
|
||||
// Blockly.Python.provideFunction_(
|
||||
// 'import_lgpio', ['import lgpio as pi']
|
||||
// );
|
||||
// var code = `i2c_hand = pi.i2c_open(1, ${value_i2c_address})\n`;
|
||||
// return code;
|
||||
// };
|
||||
Blockly.Python['ugj_i2c_open'] = function (block) {
|
||||
var value_i2c_address = Blockly.Python.valueToCode(block, 'i2c_address', Blockly.Python.ORDER_ATOMIC);
|
||||
Blockly.Python.provideFunction_(
|
||||
'import_i2c', ['from machine import I2C']
|
||||
);
|
||||
var code = `_addr = ${value_i2c_address}
|
||||
_i2c_hand = I2C(0,sda=Pin(0),scl=Pin(1))\n`;
|
||||
return code;
|
||||
};
|
||||
/********************** */
|
||||
/** Close I2C Device ** */
|
||||
/********************** */
|
||||
@ -805,10 +716,10 @@ Blockly.JavaScript['ugj_i2c_close'] = function (block) {
|
||||
var code = `await _pi.i2c_close();\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_i2c_close'] = function (block) {
|
||||
// var code = `await pi.i2c_close(i2c_hand)\n`;
|
||||
// return code;
|
||||
// };
|
||||
Blockly.Python['ugj_i2c_close'] = function (block) {
|
||||
var code = ``;
|
||||
return code;
|
||||
};
|
||||
|
||||
/****************************************************************** */
|
||||
/** Writes a single byte to the specified register of the device ** */
|
||||
@ -846,12 +757,12 @@ Blockly.JavaScript['ugj_i2c_write_byte_data'] = function (block) {
|
||||
var code = `await _pi.i2c_write_byte_data(${value_reg}, ${value_byte_val});\n`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_i2c_write_byte_data'] = function (block) {
|
||||
// var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
// var value_byte_val = Blockly.Python.valueToCode(block, 'byte_val', Blockly.Python.ORDER_ATOMIC);
|
||||
// var code = `await pi.i2c_write_byte_data(i2c_hand, ${value_reg}, ${value_byte_val})\n`;
|
||||
// return code;
|
||||
// };
|
||||
Blockly.Python['ugj_i2c_write_byte_data'] = function (block) {
|
||||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_byte_val = Blockly.Python.valueToCode(block, 'byte_val', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `_i2c_hand.writeto_mem(_addr, ${value_reg}, (${value_byte_val}).to_bytes(1,'big'))\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
/****************************************************************** */
|
||||
/** Read a single byte from the specified resister of the device ** */
|
||||
@ -882,11 +793,11 @@ Blockly.JavaScript['ugj_i2c_read_byte_data'] = function (block) {
|
||||
var code = `await _pi.i2c_read_byte_data(${value_reg})`;
|
||||
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||
};
|
||||
// Blockly.Python['ugj_i2c_read_byte_data'] = function (block) {
|
||||
// var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
// var code = `await pi.i2c_read_byte_data(i2c_hand, ${value_reg})\n`;
|
||||
// return [code, Blockly.Python.ORDER_ATOMIC];
|
||||
// };
|
||||
Blockly.Python['ugj_i2c_read_byte_data'] = function (block) {
|
||||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `int.from_bytes(_i2c_hand.readfrom_mem(_addr, ${value_reg}, 1), 'big')\n`;
|
||||
return [code, Blockly.Python.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
Blockly.Blocks['ugj_i2c_read_word_data'] = {
|
||||
init: function () {
|
||||
@ -941,13 +852,12 @@ Blockly.JavaScript['ugj_i2c_write_i2c_block_data'] = function (block) {
|
||||
var code = `await _pi.i2c_write_i2c_block_data (${value_reg}, ${value_data});`;
|
||||
return code;
|
||||
};
|
||||
// Blockly.Python['ugj_i2c_write_i2c_block_data'] = function (block) {
|
||||
// var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
// var value_name = Blockly.Python.valueToCode(block, 'NAME', Blockly.Python.ORDER_ATOMIC);
|
||||
// // TODO: Assemble Python into code variable.
|
||||
// var code = '...\n';
|
||||
// return code;
|
||||
// };
|
||||
Blockly.Python['ugj_i2c_write_i2c_block_data'] = function (block) {
|
||||
var value_reg = Blockly.Python.valueToCode(block, 'reg', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_data = Blockly.Python.valueToCode(block, 'data', Blockly.Python.ORDER_ATOMIC);
|
||||
var code = `_i2c_hand.writeto_mem(_addr, ${value_reg}, bytearray(${value_data}))\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
/************************************************************************** */
|
||||
/** Returns count bytes read from the raw device associated with handle. ** */
|
||||
@ -2833,6 +2743,118 @@ Blockly.JavaScript['testblock'] = function (block) {
|
||||
|
||||
/** 互換性 */
|
||||
|
||||
/** Fix Basic Blocks ****************************************************************************************/
|
||||
Blockly.Blocks['ugj_control_for'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("index")
|
||||
.setCheck("Variable");
|
||||
this.appendValueInput("from")
|
||||
.setCheck("Number")
|
||||
.appendField("を");
|
||||
this.appendValueInput("to")
|
||||
.setCheck("Number")
|
||||
.appendField("から");
|
||||
this.appendValueInput("by")
|
||||
.setCheck("Number")
|
||||
.appendField("まで");
|
||||
this.appendDummyInput()
|
||||
.appendField("ずつ")
|
||||
.appendField(new Blockly.FieldDropdown([["増やして", "+"], ["減らして", "-"]]), "crease");
|
||||
this.appendStatementInput("do")
|
||||
.setCheck(null);
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("インデックス番号を決められた数ずつ増やし(減らし)ながら、ステートメントを実行します。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('loop_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['ugj_control_for'] = function (block) {
|
||||
var value_index = Blockly.JavaScript.valueToCode(block, 'index', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
// var variable_index = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||||
var value_from = Blockly.JavaScript.valueToCode(block, 'from', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_to = Blockly.JavaScript.valueToCode(block, 'to', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_by = Blockly.JavaScript.valueToCode(block, 'by', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var dropdown_crease = block.getFieldValue('crease');
|
||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||
let daishou;
|
||||
if (dropdown_crease == '+') { daishou = '<'; }
|
||||
else { daishou = '>'; }
|
||||
var code = [
|
||||
`for (${value_index} = ${value_from}; ${value_index} ${daishou}= ${value_to}; ${value_index} ${dropdown_crease}= ${Math.abs(value_by)}) {`,
|
||||
statements_do,
|
||||
`}`,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
Blockly.Python['ugj_control_for'] = function (block) {
|
||||
var value_index = Blockly.Python.valueToCode(block, 'index', Blockly.Python.ORDER_ATOMIC);
|
||||
// var variable_index = Blockly.Python.nameDB_.getName(block.getFieldValue('index'), Blockly.Variables.NAME_TYPE);
|
||||
var value_from = Blockly.Python.valueToCode(block, 'from', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_to = Blockly.Python.valueToCode(block, 'to', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_by = Blockly.Python.valueToCode(block, 'by', Blockly.Python.ORDER_ATOMIC);
|
||||
var dropdown_crease = block.getFieldValue('crease');
|
||||
var statements_do = Blockly.Python.statementToCode(block, 'do');
|
||||
if (statements_do === '') statements_do = ' pass';
|
||||
if (dropdown_crease == '+') { value_by = Math.abs(value_by); value_to++; }
|
||||
else { value_by = Math.abs(value_by) * (-1); value_to--; }
|
||||
var code = [
|
||||
`for ${value_index} in range(${value_from}, ${value_to}, ${value_by}) :`,
|
||||
statements_do,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
|
||||
Blockly.Blocks['ugj_controls_foreach'] = {
|
||||
init: function () {
|
||||
this.appendValueInput("list")
|
||||
.setCheck("Array")
|
||||
.appendField("リスト");
|
||||
this.appendValueInput("item")
|
||||
.setCheck("Variable")
|
||||
.appendField("の各");
|
||||
this.appendDummyInput()
|
||||
.appendField("について");
|
||||
this.appendStatementInput("do")
|
||||
.setCheck(null);
|
||||
this.setInputsInline(true);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip("リストの各項目について、その項目の内容を変数「項目」に代入してステートメントを実行します。");
|
||||
this.setHelpUrl("");
|
||||
this.setStyle('loop_blocks');
|
||||
}
|
||||
};
|
||||
Blockly.JavaScript['ugj_controls_foreach'] = function (block) {
|
||||
var value_list = Blockly.JavaScript.valueToCode(block, 'list', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var value_item = Blockly.JavaScript.valueToCode(block, 'item', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||
var code = [
|
||||
`for (let _index in ${value_list}) {`,
|
||||
`${value_item} = ${value_list}[_index];`,
|
||||
statements_do,
|
||||
`}`,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
Blockly.Python['ugj_controls_foreach'] = function (block) {
|
||||
var value_list = Blockly.Python.valueToCode(block, 'list', Blockly.Python.ORDER_ATOMIC);
|
||||
var value_item = Blockly.Python.valueToCode(block, 'item', Blockly.Python.ORDER_ATOMIC);
|
||||
var statements_do = Blockly.Python.statementToCode(block, 'do');
|
||||
if (statements_do === '') statements_do = ' pass';
|
||||
var code = [
|
||||
`for ${value_item} in ${value_list}:`,
|
||||
statements_do,
|
||||
''
|
||||
].join('\n');
|
||||
return code;
|
||||
};
|
||||
|
||||
|
||||
// /******************/
|
||||
// /** Set Interval **/
|
||||
// /******************/
|
||||
|
Loading…
Reference in New Issue
Block a user