見出し画像

BabylonJSとIoT機器の組み合わせ案

この記事は、Babylon.js Advent Calendar 2022 の 21日分の記事です。

お疲れ様です、かーでぃです。11月にG検定があり、そちらの勉強のためBabylonJSとは少し離れていたのですが、試験も終わり、またこちらに戻ってくる気満々で、AdventCalendarもがっつり書いてやるぜ!と思っていたら、なんだかんだでやること多く、結局、何も出来ぬまま今日を迎えてしまいました^^;
ということで、ホントはIoT機器と連携させて、部屋の変化(温度とか、ドアが開いた/閉まった)をBabylonJSを使ってデジタルツインっぽく再現しようかと思っていたのですが、ちょっとコードを書く時間が無くなってしまったので、アイデアベースだけです、スイマセン。。。

https://playground.babylonjs.com/#IL33QB

作ろうと思って、自分の部屋だけレイアウトしてみました。
奥にある茶色がドアになります。
正面の壁にあるのが、時計と温度計になります。日付と時間はシステム日付を表示しておりますが、温度はIoT機器が取得しクラウドにUPしたものをJavaScriptで取得して表示します。
この「クラウドからデータを取得する」仕組みができれば、IoT機器からさまざまな情報を取得してブラウザ上にリアルタイムで表現できるよういなります。
AIを絡めてないので、デジタルツインとは言えないですが、それっぽい仕組みを構築することも可能です。

IoT機器から値を取得しようとすると、一旦クラウドに上がったデータをJSON形式で取得します。
下記のfetchのところに実際のURLが入ります。取得したdataを変数tempに代入するところをコメントアウトしておりますが、実際にはここにJSON解析処理を加えて、温度を取得することとなります。
※ので、上の”温度 16度"というのは、コードベタ打ちの表示ですね(笑)

    (async () => {
        const response = await fetch('https://hogehoge.com/hoge');
        const data =  await response.json();
        //temp=data;
    })()

ということで、ホントはラズパイに温度センサーつけて、BabylonJSからその値を取得して表示する、みたいなのを実際に構築して、こんな風にやりました!と書きたかったのですが、時間がなくてこんな形になってしまいました。。スイマセン。。。

BabylonJSは、複雑な処理をフレームワークがやってくれるので、簡単にWeb3Dを実装できる仕組みです。
個人的にはクリエイティブなツールとしてだけではなく、もっとビジネスよりの仕組みとして、広く一般化して行って欲しいと思っています。
今回のIoT機器との連携についても、事務所や工場の状況を見守るツールとして活用できるのでは?と思って、トライしています。

これからBabylonJSを始められるかたは、ちょまどさんが書かれている下記サイトが入門編としては非常にありがたいサイトです。自分もここからスタートしました!

また、BabylonJS勉強会では、Discordで情報共有をしております。
BabylonJSを始められる方は是非是非ご参加ください。

以下、Playgroundに記載したコードです。

var createScene = function () {
    var scene = new BABYLON.Scene(engine);
    const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, new BABYLON.Vector3(0, 0, 0));
    camera.attachControl(canvas, true);
    const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));


    buildRoom();
    buildTemp();
    return scene;
}

const buildRoom = () => {
    var wall01 = BABYLON.MeshBuilder.CreateBox("wall01",{width:10,height:3,depth:0.1});
    wall01.position.y = 1.5;
    wall01.position.x = 0;
    wall01.position.z = 3;

    var wall02 = BABYLON.MeshBuilder.CreateBox("wall02",{width:0.1,height:3,depth:6});
    wall02.position.y = 1.5;
    wall02.position.x = 5;
    wall02.position.z = 0;

    var door01Mate = new BABYLON.StandardMaterial("door01Mate");
    door01Mate.diffuseColor = new BABYLON.Color3(1,0.5,0.0);
    var door01 = BABYLON.MeshBuilder.CreateBox("door01",{width:0.2,height:2.8,depth:2});
    door01.material=door01Mate;    
    door01.position.y = 1.4;
    door01.position.x = 4.97;
    door01.position.z = -1.8

    // Our built-in 'ground' shape.
    var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 10, height: 6});
}

const buildTemp = () => {
    // -------------------------------------------------------------
    const font_type = "Arial";
    const size = 0.6;
    const dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", {width:90, height:30});
    const ctx = dynamicTexture.getContext();
    ctx.font = "1px " + font_type;
    const textWidth = ctx.measureText("Type A").width;
    const ratio = textWidth/size;
    const font_size = Math.floor(90 / (ratio * 1));
    const font = font_size + "px " + font_type;

    const temp="16";

    (async () => {
        const response = await fetch('https://hogehoge.com/hoge');
        const data =  await response.json();
        //temp=data;
    })()

    const day = new Date();

    buildPlate("日付 "+(day.getMonth()+1)+"/"+day.getDate(),font, 0,2.0,2.9,"#000000", "#88ff00");
    buildPlate("時間 "+day.getHours()+":"+day.getMinutes() ,font, 0,1.5,2.9,"#000000", "#88ff00");
    buildPlate("温度 "+temp+"度",font, 0,1.0,2.9,"#000000", "#88ff00");

}

const buildPlate = (text,font,posX,posY,posZ,fontColor,plateColor) =>{
    const dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", {width:90, height:30});
    dynamicTexture.drawText(text, null, null, font, fontColor, plateColor, true);
    const mat = new BABYLON.StandardMaterial("mat");
    mat.diffuseTexture = dynamicTexture;
    const plane = BABYLON.MeshBuilder.CreatePlane("plane", {width:1.8, height:0.6});
    plane.material = mat;
    plane.position.x=posX;
    plane.position.z=posZ;
    plane.position.y=posY;
}

この記事が気に入ったらサポートをしてみませんか?