WebプロジェクトでCOMポートを操作する

プロローグ



Webプロジェクトのクライアントの1人が、バーコードスキャナーを使用してシステム内の注文を検索したいと考えていました。 しかし、残念ながら、私はキーボードシミュレーションモードでそれらを操作するという考えを完全に放棄しました-COMポートエミュレーションのみです。

ソリューションオプションはそれほど多くありませんでした。



幸いなことに、問題を解決する2番目の方法があります。





Chromeアプリケーション



誰も知らない場合、ChromeアプリケーションはJavaScriptで記述されたJavaScriptブラウザーアプリケーションです。 シリアルポートAPIは 、これらのアプリケーションで使用できます。 このオプションは私たちにとってほぼ完璧です。

主な問題は、Chromeアプリケーションに適切なツールがあっても、開いているページを直接操作できないことです。 ここでは、そのような機会を持っている拡張機能が私たちの助けになります。



次に、これらすべてを接続して動作させる方法を詳細に説明します。



COMポートエミュレーション
残念ながら、実際のスキャナーで作業する機会がなかったため、エミュレートする必要がありました。

このために、私はsocatを使用しました:

  1. 以下を開始します。

    socat -d -d pty,raw,echo=0 pty,raw,echo=0
          
          





  2. 次の形式の回答が得られます。

      socat[1473] N PTY is /dev/ttys001 socat[1473] N PTY is /dev/ttys002 socat[1473] N starting data transfer loop with FDs [3,3] and [5,5]
          
          





  3. 別のターミナルウィンドウで、次を実行します。

      cat > /dev/ttys001
          
          





    / dev / ttys001の代わりに、socatが返したパスを示します

    そして、メッセージを書きます。

  4. 確認するには、3番目のウィンドウで:

      cat < /dev/ttys002
          
          





    / dev / ttys002はsocatからの2番目のパスです。

    2番目のウィンドウにメッセージを書くことで、到着した場合は3番目のウィンドウでメッセージを受け取ります-さらに先へ進むことができます。









アプリケーション作成


ドキュメントにはプロセス自体が非常によく記述されています。シリアルポートを操作するためにアクセスする必要があるという事実に注意するだけです。 これを行うには、manifest.jsonファイルで次を指定します。

  "permissions": [ "serial" ]
      
      





background.jsファイルには、アプリケーション自体のコードが含まれています。

リスティング
  chrome.app.runtime.onLaunched.addListener(function() { chrome.serial.connect("/dev/ttys004", {bitrate: 115200}, onConnect); }); var stringReceived = ''; var onConnect = function(connectionInfo) { var connectionId = connectionInfo.connectionId; var onReceiveCallback = function(info) { if (info.connectionId == connectionId) { var str = arrayBufferToString(info.data); if (str.charAt(str.length-1) === '\n') { stringReceived += str.substring(0, str.length-1); chrome.runtime.sendMessage('dbmjhdcnjkeeopcmhbooojabanopplnd', { action: 'scanner', data: { barcode: stringReceived } }); stringReceived = ''; } else { stringReceived += str; } } }; chrome.serial.onReceive.addListener(onReceiveCallback); }; function arrayBufferToString (buffer) { var string = ''; var bytes = new Uint8Array( buffer ); var len = bytes.byteLength; for (var i = 0; i < len; i++) { string += String.fromCharCode( bytes[ i ] ) } return string; }
      
      







もっと詳しく分析してみましょう。



chrome.app.runtime.onLaunched.addListener-アプリケーションの起動時に実行されるリストに関数を追加します。

chrome.serial.connect( "/ dev / ttys001"、{bitrate:115200}、onConnect) -必要なポートに接続します。接続が確立されると、onConnect関数が実行されます。

chrome.serial.onReceive.addListener(onReceiveCallback) -メッセージを受信すると、onReceiveCallbackが呼び出されます

chrome.runtime.sendMessageは、別のアプリケーション/拡張機能にメッセージを送信する関数です。 最初の引数-メッセージを送信する一意の拡張機能ID-は、インストールされている拡張機能のリストで見ることができます( chrome:// extensions /-パーサーがリンクを解除します )、2番目の引数はデータそのものです。



拡張機能を作成



ここでも、すべてが単純であり、 ドキュメントで詳細に説明されています。

マニフェストファイルの主要な設定:

  "permissions": [ "tabs", "file:///*" ], "content_scripts": [ { "matches": ["file:///*"], "js": ["action.js"] } ], "background": { "persistent": false, "scripts": ["js/background.js"] }
      
      





許可 -タブにアクセスする必要があることを示し、次にどのタブを示すかを示します(テストの場合-すべてのローカルファイルファイルが示されます)

content_scripts-ページで実行する追加のスクリプトを説明します

バックグラウンド - バックグラウンドで動作する拡張スクリプトについて説明します



Background.jsには、メッセージを受信して​​特定のタブに送信するコードが含まれています



background.js
  var onMessage = function(data) { switch (data.action) { case 'scanner': { chrome.tabs.query({url: "file:///*"}, function(tab) { for (var i = 0; i < tab.length; i++) { chrome.tabs.sendMessage(tab[i].id, data); } }); } } }; chrome.runtime.onMessageExternal.addListener(onMessage);
      
      









chrome.tabs.query-基準によってタブの選択を行います。この場合、url = "file:/// *"です

拡張機能からページでjsコードを実行するには2つの方法があります



2番目のオプションを選択しました。 拡張機能のタブで実行されるコードは、特別な環境で実行されることに注意してください。 これは、DOM要素には完全にアクセスできるが、タブで作成された変数にはアクセスできないことを意味します。 詳細。

拡張機能からタブコードにデータを転送する最良の方法は、 CustomEvent を使用することです



action.jsファイルでは、backgroud.jsからメッセージを取得し、ドキュメントのイベントを作成します。

action.js
  chrome.runtime.onMessage.addListener( function(data) { var event = new CustomEvent(data.action, {detail: data.data}); document.dispatchEvent(event); } );
      
      









メッセージを受け入れる



残された最も簡単なことは、メッセージを受け入れ、それを使用して目的のアクションを実行することです。たとえば、単に入力に貼り付けるだけです。

index.html
  <html> <head> <script type="text/javascript"> document.addEventListener("scanner", function(e) { document.getElementById('barcode').value = e.detail.barcode; }); </script> </head> <body> <input id="barcode"> </body> </html>
      
      









エピローグ



一般的に、クロムは、読み取りだけでなく書き込みも含め、ハードウェアを操作するためのAPIを提供していることに驚きました。

残念ながら、ほぼすべての作業が完了した後、クライアントはスキャナーをキーボードシミュレーションモードに移行すると言いました。 これは最終的には助けにはなりませんでしたが、この資料が誰かに役立つことを願っています。



PS

興味のある方は、バックボーンを使用していくつかの1ページの大規模プロジェクトを作成およびサポートする方法、クライアント側でレイアウト全体をキャッシュする方法について説明できます。



All Articles