Raspberry Pi にNode-RED MCU開発環境をシェルスクリプトでセットアップする

### 別記事のご案内
この記事とは別のパターンでセットアップするスクリプトを作成して紹介しています。一度こちらもご参照頂き、どちらか適している方法でお試しください。

https://qiita.com/mshioji/items/176a680ceaf73e3c1ca4

### はじめに
Node-REDのフローエディタで作成したフローをESP32のような小さなマイコン(MCU)で実行できるようにするNode-RED MCUはIoTデバイスを開発するのにとても便利なのですが、実は開発環境を用意するのにステップが多くあります。

対応する環境は限定的ですが、子供たちにフロープログラミングを試してもらう機会を増やしたいなとRaspberry Piに簡単に環境を構築するシェルスクリプトを試作して使ってみた内容を紹介します。

新しいマイクロSDカードを用意して、手持ちのRaspberry Pi 4Bでやってみようかな？という方がおられたらお試しください。

:::note alert
重要なデータが入った環境には使用しないでください。
:::

それほど使い込んでいませんので、まだ不十分な点もあるかと思います。マイクロSDカードに新たにOSを書き込んだ状態で、不具合があっても消去してやり直せる環境などリスク覚悟でお願いします。改善点等あればコメント頂けると嬉しいです。

### 動作環境
Hardware : Raspberry Pi 4B　 (Pi 5は未テストです）
Operating System : Raspberry Pi OS Bookworm
Target Device(MCU) : ESP32 series

### インストールステップについて
通常、マイクロSDカードにRaspberry Pi OSを書き込んだだけの状態からセットアップするには次の手順があります。
これをシェルスクリプトで一気にできるようにするのが目標でした。

1. moddable SDK インストール
2. ESP-IDF インストール
3. NodeJS,NPM インストール
4. Node-RED インストール
5. Node-RED MCU Plugin インストール
6. MCU Nodes インストール
7. Additional Nodes インストール
8. Node-RED settings.js の編集


うむむ、やはり書き出すだけでステップの多いのが分かりますね。
シェルスクリプトでは、これを一気にするために普段手動でやっていた手順も少し変更しています。

・通常、moddable SDKとESP-IDFはxs-devを使用するとインストールが楽にできますが、今回はmoddableのgithubの手順に沿っています。

・nodejs, npmのインストールは、nvmのようなバージョン管理ツールを使ってインストールすることがstrongly recommendedのようなので、nvmをインストールしてからnodejsをインストールしています。バージョンは22をセットしています。別のバージョンにしたい場合はシェルスクリプトの内容を修正して実行してください。

・Node-REDのフローエディタのadmin authを念のため自動設定します。
　独自のuser/passで入りたい方はシェルスクリプトの内容を修正して実行してください。そのまま実行した場合の初期値は admin / noderedmcu です。
 ここに書くのもどうかな？ですが、何も設定しないよりは良いかなと思います。

### 準備
 Raspberry Piに新しいOSのはいったSDカードをセットし、起動します。インストールはネットワークからダウンロードしながら行うため、WiFiアクセスポイントに接続するなど、ネットワークが使える状態にしてください。

 ・ホームディレクトリ（でも、どこでも）にファイルを作成します。
 　ホーム直下にnrmcu_install.sh として作成する場合は次のようにします。
```
$ nano ~/nrmcu_install.sh
```
エディタが開きますので、次の内容をコピーしてペーストします。
```
#!/bin/bash

echo '### starting nrmcu_install.sh'

# installing moddable SDK
echo '### Install Moddable SDK'
sudo apt update
sudo apt install -y gcc git wget make libncurses-dev flex bison gperf
sudo apt install -y libgtk-3-dev

export MODDABLE=$HOME/.local/share/moddable
export PATH=$PATH:$MODDABLE/build/bin/lin/release
export IDF_PATH=$HOME/.local/share/esp32/esp-idf-v5.3.1

if ! grep -q 'export MODDABLE=$HOME/.local/share/moddable' ~/.bashrc; then
  echo 'export MODDABLE=$HOME/.local/share/moddable' >> ~/.bashrc
  echo "MODDABLE variable added to ~/.bashrc"
else
  echo "MODDABLE variable already exists in ~/.bashrc"
fi

if ! grep -q 'export PATH=\$PATH:\$MODDABLE/build/bin/lin/release' ~/.bashrc; then
  echo 'export PATH=$PATH:$MODDABLE/build/bin/lin/release' >> ~/.bashrc
  echo "MODDABLE path added to ~/.bashrc"
else
  echo "MODDABLE path already exists in ~/.bashrc"
fi

if ! grep -q 'export IDF_PATH=$HOME/.local/share/esp32/esp-idf-v5.3.1' ~/.bashrc; then
  echo 'export IDF_PATH=$HOME/.local/share/esp32/esp-idf-v5.3.1' >> ~/.bashrc
  echo "IDF_PATH variable added to ~/.bashrc"
else
  echo "IDF_PATH variable already exists in ~/.bashrc"
fi
hash -r
sleep 1

cd $HOME/.local/share
git clone https://github.com/Moddable-OpenSource/moddable

echo '### make and install Moddable SDK...'
cd $MODDABLE/build/makefiles/lin
make
cd $MODDABLE/build/makefiles/lin
make install

# installing ESP-IDF
echo '### Installing ESP-IDF...'
sudo apt install -y flex bison gperf python-is-python3 python3-pip python3-serial python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util

mkdir $HOME/.local/share/esp32
cd $HOME/.local/share/esp32
git clone -b v5.3.1 --recursive https://github.com/espressif/esp-idf.git esp-idf-v5.3.1

cd $IDF_PATH
bash ./install.sh
source ./export.sh

# install nvm,nodejs,npm

echo "### Installing nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

echo "### Installing Node.js v22..."
nvm install 22

# add to ~/.bashrc
if ! grep -q 'export NVM_DIR="$HOME/.nvm"' ~/.bashrc; then
  echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc
  echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc
  echo "nvm configuration added to ~/.bashrc"
else
  echo "nvm configuration already exists in ~/.bashrc"
fi

hash -r
echo "### Node.js version:"
node -v
echo "### npm version:"
npm -v

# install node-red, Node-red-mcu

echo "Installing Node-RED and Node-RED MCU..."
npm install -g --unsafe-perm node-red

# Node-RED user directory
USER_DIR="$HOME/.node-red"
if [ ! -d "$USER_DIR" ]; then
    echo "Creating Node-RED user directory at $USER_DIR..."
    mkdir -p "$USER_DIR"
fi

# log setting
LOG_FILE="$USER_DIR/node-red.log"

# first run Node-RED to create settings.js
echo "Starting Node-RED to generate settings.js..."
node-red --userDir $USER_DIR --safe > "$LOG_FILE" 2>&1 &
NODE_RED_PID=$!
sleep 5

# stop Node-RED
echo "Stopping Node-RED after settings.js generation..."
kill $NODE_RED_PID 2>/dev/null || true

# modify settings.js
SETTINGS_FILE="$USER_DIR/settings.js"
if [ -f "$SETTINGS_FILE" ]; then
    echo "Modifying settings.js..."

    # add "process.env.MODDABLE" setting outside of module.exports
    echo "process.env.MODDABLE = '$HOME/.local/share/moddable';" >> "$SETTINGS_FILE"

    # add "adminAuth" settings
    if grep -q "//adminAuth:" "$SETTINGS_FILE"; then
        sed -i '/module.exports = {/a \  adminAuth: { type: "credentials", users: [{ username: "admin", password: "$2y$08$g4OQQdpKaDVV6q.xUFIx.u0RZtOeENgGEJfLu9D5XvBWO.RkI4gg6", permissions: "*" }] },' "$SETTINGS_FILE"
    fi
else
    echo "Error: settings.js not found in $USER_DIR. Exiting."
    exit 1
fi

# install plugin and nodes
echo "### Installing additional Node-RED nodes..."
cd "$USER_DIR"
npm i @ralphwetzel/node-red-mcu-plugin
npm i @moddable-node-red/mcu
npm i node-red-dashboard

echo "Node-RED MCU installation complete."
```
ペーストしたら、ctrl-oで保存して、ctrl-xで終了します。
指定した場所にファイルはできましたが、このままではシェルスクリプトとして実行できないので、実行権限を付与します。
```
$ sudo chmod +x ~/nrmcu_install.sh
```
これでスクリプトとして実行可能となりました。

### スクリプトの実行
それでは実行しましょう！
ファイルの置き場所を変更した場合は、そちらを指定します。
```
$ ~/nrmcu_install.sh
```
:::note info
たくさんインストールするので、かなり時間がかかります。こちらで試したときは40分程度かかりました。
:::

ネットワークの速度にもよりますが、時間に余裕があるときに、ゆったりお待ちください。

### セットアップが完了したら... 
新しいターミナルを開いてNode-REDを起動します。
```
$ node-red
```
起動メッセージが流れてきます。このターミナルのウインドウを閉じるとNode-REDが停止するので、開いておいてください。
ブラウザを立ち上げて、アドレスバーに下記を入力します。
```
localhost:1880
```
Node-RED フローエディタのログイン画面が表示されるはずです。
先に設定したuser/passでログインしてください。

Node-RED MCUのプラグインも有効になっているはずです。

それでは、Node-REDのフロープログラミングを使ったIoTデバイス開発を楽しみましょう！