miso-develop / opniz-sdk-nodejs

MIT License
8 stars 0 forks source link

ENV3センサは動かせるのでしょうか #5

Open O2giriOC opened 1 year ago

O2giriOC commented 1 year ago

お久しぶりです、また質問失礼します。 今ENV3センサを使用していまして、センサ値が受信される26番ピンをanalogreadしていたのですが、0としか表示されません。 ENV3は湿度、気圧、温度を測定していて、I2C通信なので、専用の関数じゃないと値を取得できないということでしょうか。 また教えていただければ幸いです。

miso-develop commented 1 year ago

I2Cの場合はI2Cでの通信が必要となりますが、申し訳ございませんが現在opnizはI2Cをサポートしておりません…

ちなみにENV3はこちらの製品でしょうか? 上記の製品でしたらArduinoライブラリが用意されていますでの、opnizで実装する場合はopniz Node.js SDKおよびopniz Arduino Libraryを拡張実装することでArduinoライブラリで用意されている関数をNode.js SDKから使用できるようになります。

拡張実装に関する詳細なドキュメントも用意できておらず恐縮ですが、参考までに「opnizでつくる「CO2センサ(MH-Z19C)データのGoogle Spreadsheetsロギングシステム」」という記事にてArduinoライブラリを用いてopnizを拡張実装した例をご紹介しています。

O2giriOC commented 1 year ago

そのセンサーで間違いないです!説明不足ですみません… なるほど!クラスを実装するイメージですかね? とりあえず記事を参考にさせてもらいます! またしてもありがとうございます!!

miso-develop commented 1 year ago

拡張用ベースクラスを用意していますのでそれを拡張していただくかたちになります! Arduino LibraryのREADMEにはちょろっと書いていましたがNode.js SDK側に拡張方法に関する記載がなかったので、別途解説記事を書いておこうと思います!

miso-develop commented 1 year ago

opnizの拡張実装解説記事を書きました! ご参考になれば幸いです!

opniz拡張実装方法解説#1 Node.jsからデバイスへのリクエスト拡張編(Qiita)

O2giriOC commented 1 year ago

わざわざありがとうございます! ちょうど手詰まっていたところなので、助かりました。 丁寧な解説本当にありがとうございます!!

O2giriOC commented 1 year ago

お久しぶりです、パソコンを修理に出していまして連絡が遅れてしまいすみません。 現在クラスを実装してとりあえずLEDを点滅させようとしたのですが、下のメッセージが表示され、LEDが点滅していない状況です。

スクリーンショット 2023-01-18 154741

Node.jsとの接続自体はできているとは思うのですが、どこか至らないところがあるのでしょうか。 教えていただければ幸いです。

miso-develop commented 1 year ago

お久しぶりです! JSONメッセージが表示されているのでしたら正常に接続、通信は行なえています! drawpixメソッドでLEDが点滅しないとなるとJSONメッセージに対応したハンドラーが存在しないことが考えられます。

おそらくですがクラス拡張された際にEsp32クラスをベースクラスに使用されているのではないかと思います。 drawpixメソッドはM5Atomクラス側で定義されているので、M5Atomクラスをベースクラスとすればdrawpixメソッドも使用できるようになるかと思います。

O2giriOC commented 1 year ago

ありがとうございます!! 言われた通りESP32クラスを使用していました笑。

https://www.youtube.com/watch?v=7n0_f7Z5mFQ 上記の動画のようにブラウザからM5Atomliteを制御したいと考えているのですが、これはopniz-severを使用してwebsocketで動かしているのでしょうか?

miso-develop commented 1 year ago

この動画ではM5ATOMとNode.js間をopnizで繋ぎ、Node.jsとHTMLを別途WebSocketで繋いでいます。 イメージとしてはHTML上のボタンが押されたときにHTMLからNode.jsへWebSocketでイベントを送り、Node.js側でイベントを受けたらopnizのメソッドを実行する感じです。

理想としてはHTMLから直接opnizメソッドを実行したいところなのですが、恐縮ですがこちらも現在対応できていない状況です… (現状のopniz Node.js SDKからWebSocket Server機能と関連ライブラリを外せばブラウザ上でもopnizが動く想定です)

opnizがブラウザ対応できれば、おっしゃる通りopniz-serverを介してHTMLからM5ATOMとやりとりが行えるようになります。

O2giriOC commented 1 year ago

ありがとうございます! この場合M5ATOMを動かすNode.jsとWebsocketでM5ATOMとブラウザを繋ぐNode.jsの2つを用意するということでしょうか?

miso-develop commented 1 year ago

ひとつのNode.js内でM5ATOMを制御するopnizのコードと、HTMLとやりとりするWebSocketのコードを組み合わせます。 イメージとしてはNode.js側は以下のようなコードになります。

const opniz = new Opniz.M5Atom({ port: opnizPort })
await opniz.connectWait()

const wss = new WebSocketServer({ port: wsPort })
wss.on("connection", async ws => {

  // HTMLからWebSocketメッセージを受けてM5ATOMを制御
  ws.on("message", async message => {
    switch(message.toString()) {
      case "green":
        await opniz.drawpix(0, "#00ff00"); break
      case "blue":
        await opniz.drawpix(0, "#0000ff"); break
      case "red":
        await opniz.drawpix(0, "#ff0000"); break
      case "off":
        await opniz.drawpix(0, "#000000"); break
    }
  })

  // M5ATOMからの情報を受けてHTMLへWebSocketメッセージを送信
  opniz.onbutton = () => {
    ws.send(JSON.stringify({ button: true }))
  }
})

HTML側のWebSocketからgreenblueといったメッセージを受け取ると対応するopniz.drawpixメソッドを実行します。 またopniz.onbuttonメソッドにてws.sendでHTML側にメッセージを送信すればM5ATOMのボタンイベントの発火をHTML側に伝えられます。

O2giriOC commented 1 year ago

ありがとうございます! websocketとそのように組み合わせればいいんですね!! わざわざサンプルコードまで教えていただきまして、本当に感謝しかありません!! ありがとうございます!!

O2giriOC commented 1 year ago

お久しぶりです。 ENVⅢのクラスを拡張でき、実際にNode.js SDKで動かすことができました。 今現在、上記のコードを参考にしてHTMLからwebsocket経由でatomliteを動かそうとしているのですが、websocketハンドシェイクが完了したタイミングでatomliteとの接続が切れてしまいます。 ポート番号を一緒にしているのが問題かなと思い変更してみたのですが、特に変わらず「Opniz Error: Connection timeout.」と表示されました。 他の原因が思いつかず、また質問させていただきました。回答していただければ幸いです。

miso-develop commented 1 year ago

お久しぶりです。 確かに同じポート番号だとだめなのですが、その場合はError: listen EADDRINUSEといったポート番号が使用済みというエラーとなるはずなので問題は別にありそうですね… ひとまず以下をチェックしてみてもらえますでしょうか。

O2giriOC commented 1 year ago

回答ありがとうございます。とりあえずチェックしてみました。

・クライアント側(opnizデバイス、ブラウザ)のポート番号も重複しないものになっているか  両サイドのポート番号を別の値にしましたが同じようにopnizとの接続ができないという結果でした。また一緒な番号にしたとしても「listen EADDRINUSE」とは出ませんでした。

・opnizのコード単体で動作するか  READMEのようなサンプルコードのように、opnizのコードだけが書かれたjsファイルを動かしたのですが、正常に動きました。Lチカは勿論、クラス拡張を行ったENVⅢも動いたので特に問題はないように思えます。

・WebScoketのコード単体で動作するか  こちらもwebsocketでhtmlとNode.jsサーバの双方向通信を行うコード単体を動かしました。こちらも特に問題なく動きました。

もしかしたらですが、expressモジュールを使ってサーバ構築を行っているのに問題があるのでしょうか。  

miso-develop commented 1 year ago

ご確認ありがとうございます! それぞれ単体で動いているのであれば組み合わせ方の問題ですかね…

もしかしたらですが、expressモジュールを使ってサーバ構築を行っているのに問題があるのでしょうか。

expressもポートが絡みますがEADDRINUSEが出ていないなら(ポート番号を分けているなら)ポートの問題ではなさそうですね… opniz、WebSocket、Expressそれぞれのlistenタイミングも少し気になるので可能であればソース共有できそうでしょうか?

O2giriOC commented 1 year ago
const WebSocketServer = require("ws").Server;
const http = require("http");
const express = require("express");
const app = express();
const {Opniz} = require("opniz");
const Opniz_PORT = process.env.PORT || 4000; 
const Server_PORT = process.env.PORT || 3000;

//M5Atomクラスを追加
class ExtendOpniz extends Opniz.M5Atom{
    async getTmp(){
       return Number( await this.exec("getTmp") )
    }
}
const opniz = new ExtendOpniz({Opniz_PORT});

//HTML
app.get("/", (req,res)=>{
    res.sendFile(__dirname + "/views/index.html");
});

//WebScoket起動
const server = http.createServer(app);
const wss = new WebSocketServer({server:server});

//opniz接続
const connect = async()=>{
    console.log("opniz start");
    while (!(await opniz.connectWait())) console.log("connect...")
    console.log("[connect]");
    await opniz.dis.drawpix(0, 0x0ff000);
}

//websocket
wss.on("connection", async (ws)=>{
    console.log("CONNECT");
    //確立したらopniz開始
    connect();

    //ブラウザを閉じたとき
    ws.on("close",()=>{
        console.log("END");
    });

    //メッセージを受けたとき
    ws.on("message", async (msg)=>{
        console.log("message:"+ msg);
        ws.send(msg.toString());  //toString()で文字列に変換
    });
});

//サーバの構築
server.listen(Server_PORT,()=>{
    console.log(Server_PORT);
});

jsのコードは今の所このような感じです。見づらくてすみません。 動作の流れとしては サーバの構築 → HTMLの表示&WebSocket開始 → opniz開始 といったものを想定しています。

miso-develop commented 1 year ago

ありがとうございます! ひとまずopnizのポート指定部分を以下のように変更してみてください!

// const opniz = new ExtendOpniz({Opniz_PORT});
const opniz = new ExtendOpniz({ port: Opniz_PORT });
O2giriOC commented 1 year ago

言われた通りに変更したら実行できました!! 文法を間違えていたのですか... 別にサーバを構築?するときにはポート番号の指定が大事ということがわかりました! ありがとうございます!!