2020年7月6日月曜日

棚卸パッケージをクラウド対応できなかった話

このブログはほとんど〇〇してみた、□□できましたっていう記事で占められていると思うのですが、今日はうまくいかなかった話。

以前にも棚卸パッケージをクラウド対応するっていう話がありました。その概要はGoogle Apps ScriptでAPIを作成して、Androidアプリを改造して通信先をそのAPIに向けるというものでした。今回はちょっとアプローチを変えて、Androidアプリはそのままで、この記事で試したように、WebとはBluetooth経由で通信しようと考えました。

使ったもの


やったこと

クラウド側にはGoogle Spreadsheetを使用しました。アドオンでSpreadsheetに機能を追加できるので、これを使用しました。アドオンでは、呼び出し元をgsで記述、UIをhtmlで作成して、動作をJavascriptで記述することができます。こんな感じです。

呼び出し元
function onInstall(e) {
  onOpen(e);
}
function onOpen(e) {
  var ui = SpreadsheetApp
    .getUi()
    .createAddonMenu()
    .addItem('リーダ', 'showSidebar')
    .addToUi();
}
function showSidebar() {
  var sidebarUi = HtmlService
    .createTemplateFromFile('Sidebar')
    .evaluate()
    .setTitle('MANICA');
  SpreadsheetApp
    .getUi()
    .showSidebar(sidebarUi);
}

UI
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
  </head>
  <body>
    <div>
      <form>
      <p>
      <select id="inputMode">
      <option value="fill">セルへ入力する</option>
      <option value="findTag">ICタグを探す</option>
      <option value="findCell" selected>セルを探す</option>
      </select>
      </p>
      </form>
      <button id="connect" onclick="readerLibrary.start();">接続</button>
    </div>
    <?!= HtmlService.createHtmlOutputFromFile('ReaderLibrary').getContent(); ?>
  </body>
</html>

Javascript(GAS上では拡張子はhtmlしか設定できないみたいです)
<script>
window.readerLibrary = {
    writer: undefined,
    encoder: undefined,
    start: async function () {
        const requestOptions = {};
        let port;
        try {
            port = await navigator.serial.requestPort(requestOptions);
            await port.open({ baudrate: 115200 });
        } catch (err) {
            console.log(err);
            return;
        }
        console.log('connected: ' + port);
        while (port.readable && port.writable) {
            console.log('readable and writable');
            this.encoder = new TextEncoder();
            this.writer = port.writable.getWriter();
            const decoder = new TextDecoder();
            const reader = port.readable.getReader();
            while (true) {
                console.log('while loop');
                let value, done;
                try {
                    ({ value, done } = await reader.read());
                } catch (err) {
                    console.log(err);
                    break;
                }
                if (done) {
                    break;
                }
                //this.handleChunk(decoder.decode(value));
               // this.dotNet.invokeMethod('OnReceived', value);
               console.log(value);
            }
            this.writer.releaseLock();
            reader.releaseLock();
            await port.close();
            console.log('disconnected');
        }
        console.log('while loop done');
    }
};
</script>

メニューから作ったアドオンを選択すると、こんな感じで表示されます。


あとは接続ボタンを押せばつながるはずと思ったのですが、残念ながら下記のエラーが表示されて、うまくいきませんでした。


userCodeAppPanel:9 [Violation] Feature policy violation: serial is not allowed in this document.

エラーメッセージを基に調べてみると、下記のIssueが見つかりました。(下記はgeolocationに関するIssueですが、今回のとエラーの原因は同じと思います)

feature policyでserialを許可する必要があるみたいなのですが、Spreadsheetのアドオンからですと、iframeを使った方法もresponse headerを使う方法もどちらも提供されていないようです。そのため、このやり方ではうまく行かず、まったく別の方法を考える必要があるようです。という訳で、うまくいかなかった話でした。

実は上記のあと、Office 365でもチャレンジしてみたのですが、チュートリアルでエラーが出てしまい、挫折しました。

1 件のコメント:

  1. https://issuetracker.google.com/issues/68032861#comment8
    去年の11月にコメントが付いてました。もしかして変わるのかも。

    返信削除