SORACOM Harvest FilesにNode-REDからCSVファイルをアップロードする

# はじめに
以前、[SORACOM HarvestのデータをAPIでダウンロードし、CSVにする方法](https://qiita.com/ozk009/items/c880d234a4b91f4882d0)と[SORACOM Funkを使ってAmazon S3にCSV保存する方法](https://qiita.com/ozk009/items/86f198c001a914cac9e7)を紹介しましたが、「1日分のデータをCSVで保存しといて、ストレージにアップロードすればいいんじゃない？」ということでやってみました。
この記事では、以下のように（私が個人的に好きな）Node-REDを使って、CSVファイルを作成し、[SORACOM Harvest Files](https://soracom.jp/services/harvest/)にアップロードする方法、[SORACOM CLI](https://users.soracom.io/ja-jp/tools/cli/)で別のパソコンからそのファイルをダウンロードする手順について説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/e4b84181-ee87-04a0-5ed2-95ea72011b27.png)
1. Node-REDでCSVファイルを作成する
1. Node-REDでCSVファイルをSORACOM HarvestFilesにアップロードする
1. 遠隔地のオフィスからSORACOM CLIを使ってCSVファイルをダウンロードする

**SORACOM CLIを使っている理由は、将来的に自動化（定時のバッチ処理による）を検討しているためです。**

なお、この記事は既にSORACOMとNode-REDをお使いの方を対象としており、[アカウント作成](https://users.soracom.io/ja-jp/guides/getting-started/create-account/)などの基礎的な作業は省いていますので、ご了承ください。
また、利用するSORACOMのサービスは無償の範囲もありますが、<font color="red">基本的に有償となります</font>。数百円単位であまり多くはありませんが<font color="red">費用が発生します</font>ので、各サービスのサイトで費用をご確認ください。

また、検証に当たっては[私の過去の記事](https://qiita.com/ozk009/items/52ef82063b5a4b579628)を参考に環境構築していただくと手軽かと思います。

# CSVファイルの作成
まずはNode-REDでCSVファイルを作成する方法です。
## Node-REDフロー
テスト用に正弦波を出力する以下のようなフローを作ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/34f34fbc-e2b3-d7f7-959e-a0b24168e49a.png)
- injectノードは1秒おきに動くよう設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/a54ddc48-af87-3aa2-086a-e698167dd67c.png)
- functionノードは日時と正弦波の値をJSONで作ります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/c50dfa61-2505-c771-8318-b70b6fbf4912.png)
    ```javascript
    var now = new Date();
    var timestamp = now.getFullYear() + "-" +
        ("0" + (now.getMonth() + 1)).slice(-2) + "-" +
        ("0" + now.getDate()).slice(-2) + " " +
        ("0" + now.getHours()).slice(-2) + ":" +
        ("0" + now.getMinutes()).slice(-2) + ":" +
        ("0" + now.getSeconds()).slice(-2);
    var sinValue = Math.sin(msg.payload * 0.0001);
    msg.payload = { timestamp, sinValue };
    return msg;
    ```
- CSVノードでCSVに変換します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/9ee6edcb-88ff-70c3-7c62-58c1836c8f7e.png)
- write fileノードでCSVファイル（例としてC:¥tmp¥test.csv）に出力（追記）します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/d326ec78-dd10-d4ef-c023-7dd7a78330b2.png)
## 動作確認
CSVファイルが指定のパス（本記事ではC:¥tmp¥test.csv）に作成されていればOKです。

# CSVファイルのアップロード
出力したCSVファイルをアップロードする方法です。
## 事前準備
対象のSIMのグループを設定し、[SORACOM Harvest Files](https://users.soracom.io/ja-jp/docs/harvest/enable-files/)を有効化します。
具体的にはSORACOM Harvest Filesのトグルを「ON」にして、保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/526e28fc-e59f-02cc-af86-aca822664ca0.png)
メッセージ画面で「OK」すれば準備完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/34d5528a-14fe-4959-33b9-6cff984e816a.png)

## Node-REDフロー
ファイルアップロードのフローです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/fcf3559d-eb3a-012e-4f7c-258afbf83b73.png)
- とりあえず手動で動かすのでinjectノードはそのままです
- file readノードでCSVファイルをバイナリとして読み込みます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/de821329-633d-0322-c2c3-956b782d054a.png)
- http requestノードでSORACOM Harvest Files（ http://harvest-files.soracom.io/test.csv ）に**PUTメソッド**で送ります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/9534927b-230a-ff8f-b722-b6804f7b7240.png)
- debugノードではとりあえず応答を見るために対象を「msgオブジェクト全体」にしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/8d9f9fcd-a92e-888b-a8a1-b5709b2e1e75.png)

## 動作確認
injectノードの左をポチすると、SORACOMにデータが送られる（はず）です（デバッグウィンドウで「statusCodeが20xになっていればOK）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/cffd1f02-feba-d3db-1cfd-eb6b679afd4a.png)

SORACOMコンソールでHarvest Filesを見るとファイルがアップロードされています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916611/f791fba2-c4e5-bfd0-28e7-f909ee8a32f6.png)

# CSVファイルのダウンロード
ここからは現場とは別の場所にあるWindowsパソコンからCSVをダウンロードするための作業となります。
ファイルのダウンロードはユーザーコンソールからもできますが、前述の通り**定期的に自動で動かすことを考慮し**、SORACOM CLIを使ってコマンドでダウンロードする方法にします。

## SAMユーザー作成
SORACOM CLIでSORACOM Harvest FilesからファイルをダウンロードするためのSAMユーザーを作成します。
1. [SORACOMドキュメント](https://users.soracom.io/ja-jp/docs/sam/create-sam-user/)を参考に、SAMユーザーを作成し、[認証キーを取得](https://users.soracom.io/ja-jp/docs/sam/create-sam-user/#%e8%aa%8d%e8%a8%bc%e3%82%ad%e3%83%bc%e3%82%92%e7%94%9f%e6%88%90%e3%81%99%e3%82%8b)します
1. 続いて以下の手順で[SAMユーザーの権限を設定](https://users.soracom.io/ja-jp/docs/sam/set-permissions/)します
    権限設定のJSONは以下となります
    ```json
    {
      "statements": [
        {
          "effect": "allow",
          "api": [
            "FileEntry:listFiles",
            "FileEntry:getFile"
          ]
        }
      ]
    }
    ```

## SORACOM CLIセットアップ
SORACOM CLIのインストールは以下となります。

https://users.soracom.io/ja-jp/tools/cli/getting-started/

Windows環境で、[ステップ3](https://users.soracom.io/ja-jp/tools/cli/getting-started/#%e3%82%b9%e3%83%86%e3%83%83%e3%83%97-3-%e8%aa%8d%e8%a8%bc%e6%83%85%e5%a0%b1%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b)の作業は以下となります。
```
SET LANG=ja

soracom configure --profile harvest-files

--- SORACOM CLI セットアップ ---
C:\Users\xxxx\.soracom ディレクトリがなければ作成し、そこにファイル 'harvest-files.json' を作成します。

カバレッジタイプを選択してください。

1. Global
2. Japan

選択してください (1-2) > 2（お使いのカバレッジタイプを選択します）

認証方法を選択してください。

1. AuthKeyId と AuthKey を入力する (推奨)
2. オペレーターのメールアドレスとパスワードを入力する
3. SAM ユーザーの認証情報を入力する (オペレーターID、ユーザー名、パスワード)
4. スイッチユーザー

選択してください (1-4) > 1 （SAMユーザーの認証キーIDと認証キーシークレットで認証します）
authKeyId: (認証キー ID を入力して、Enter を押します。入力した内容が表示されます)
authKey:(認証キーシークレットを入力して、Enter を押します。入力した内容は表示されません)
```
## ダウンロード
以下コマンドでファイルを保存できます。
```
soracom files get --path test.csv --profile harvest-files > C:\dl\test.csv
```
## 動作確認
ダウンロードしたCSV（本記事ではC:\dl\test.csv）が想定したものであればOKです。

# おまけ
今回、Node-REDでファイルをアップロードしましたが、SORACOM Arcに接続したWindowsパソコンから以下のcurlコマンドでも送れます。
```
curl -v -X PUT http://harvest-files.soracom.io/test.csv -H "Content-type: text/csv" --data-binary @C:\tmp\test.csv
```

# まとめ
過去2回（[ETLツール利用](https://qiita.com/ozk009/items/c880d234a4b91f4882d0)と[AWS利用](https://qiita.com/ozk009/items/86f198c001a914cac9e7)）の方法に比べ、非常にシンプルかつ（電波状況による）欠測にも対応できるので、良い方法だと思います。
どなたかのお役に立てれば幸いです。

そして今回の記事も詳細説明をかなり省いてしまいました。
ここもっと詳しく教えてとかあればコメントいただけると幸いです。