太陽光発電の発電量をロギングしてみた。(4)Salesforseでリアルタイム監視

[【太陽光発電の発電量をロギングしてみた。目次】](https://qiita.com/takoyakiya/items/6b318ab83bcac86c966c)
## Salesforseでリアルタイム監視

前回まででINA260で測定した電流・電圧値をRaspberryPiでロギングできるようになったが、せっかくなので、インターネット上にアップロードして発電量をどこからでも確認できるようにしたい。

その方法の選択肢は様々あると思うが、今回はSalesforceのDeveloper Editionを利用した。

#### ● Salesforceを利用するメリット

1. PaaS (Platform as a Service)であること
   　クラウドサービスには大きく分けて、IaaS(Infrastracture as a Service),PaaS (Platform as a Service),SaaS (Software as a Service)の３つが存在する。
　SalesforceはPaaSに属している。
　PaaSは、IaaSのような環境構築が不要で、かつ、SaaSよりも自由度が高く、リッチな機能を自由に簡単にカスタマイズ可能である。

2. Developer Editionは無料であること
   　Salesforceは基本的には有料ライセンスを購入する必要があるが、Developer Editionならフル機能使えて無料で利用可能である。
　ただし、以下の制限がある。

　　・ 作成できるユーザー数は2
　　・ 利用可能なデータストレージ 5MByte
　　・ 利用可能なファイルストレージ 20MByte

　　詳細は、「[Salesforce の機能とエディションの割り当て - Salesforce Help]
(https://help.salesforce.com/articleView?id=overview_limits_general.htm&type=5)」「[データストレージとファイルストレージの割り当て](https://help.salesforce.com/articleView?id=overview_storage.htm&type=5)」を参照

データストレージ5Mが小さいと思われるかもしれないが、BigObjectを活用すれば100万件までレコードを格納できる。こちらについては後ほど説明する。

#### ● Salesforce Developer Editionの登録

Salesforce Developer Editionは、以下のサイトからユーザー登録すれば、使用できるようになる。
登録からメールが届くまでタイムラグがあることがあるので注意すること。

[Salesforce Developersユーザー登録](https://developer.salesforce.com/signup)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/09aab22d-b59f-1cf8-5dbe-59d4baef85d0.png" width="80%">

#### ● Salesforceへのログイン

Salesforceにログインするには、以下のサイトにアクセスする。

[Salesforce ログイン](https://login.salesforce.com/?locale=jp)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/16d93380-5300-6460-f265-d463b776c6ee.png" width="80%">

登録したユーザ名とパスワードを入力し、ログインする。
最初のログイン時には、ガイダンスの後、基本的には下記の画面(サービスの設定)が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/09797fc2-b64f-251c-9d5b-ec24e2f85a43.png)

いろいろとメニューが多く、何をすればよいのかわからないかもしれないが、ここでは以下の手順で設定していく。

1. カスタムオブジェクトの作成
2. OAuth設定とAPIの有効化
3. SOAP API経由でテストデータの投入
4. レポートの作成
5. ダッシュボードの作成

#### ● カスタムオブジェクトの作成

Salesforceには、標準オブジェクトとカスタムオブジェクトが存在する。
これらはデータベースのテーブルに該当する。

標準オブジェクト：最初からCRM等のアプリケーションのために用意されているオブジェクト。カスタマイズ可能。
カスタムオブジェクト：完全にユーザーが自由に定義できるオブジェクト。

以下、カスタムオブジェクトの作成手順である。

1. 画面右上の歯車アイコンをクリックし。「設定」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/70377a95-1cf5-0464-f2b3-35edc9590e7a.png)

2. 画面左のメニューから
プラットフォームツール-「オブジェクト及び項目」-「オブジェクトマネージャ」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/4dc1cb2c-9f6c-5eb6-50d4-0a938669044c.png)

3. 画面右側の「作成」をクリックし、ドロップダウンメニューから「カスタムオブジェクト」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/831c6b51-ae36-c42c-db47-0b2e8cbfc24b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/cf4e71b6-5479-df53-898d-8ab56ee69023.png)


4.カスタムオブジェクトの作成

カスタムオブジェクトの名前とAPIアクセス名を設定する。
カスタムオブジェクトのAPIアクセス名は、保存後、末尾に「__c」が付く。
ここでは以下のように設定している。

![SF1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/60d81f0f-bb1a-a1bd-b72f-ac968cdb86b0.png)


5.カスタムタブの作成

4で、「カスタムオブジェクトの保存後、新規カスタムタブウィザードを起動する」をチェックすると、カスタムオブジェクト保存後、自動的に「新規カスタムタブ画面」が表示される。
もし、チェックを入れ忘れた場合は、
設定-プラットフォームツール-「ユーザーインターフェース」-「タブ」から「新規」ボタンをクリックすると新規カスタムタブ作成画面が起動する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/343359e3-34ea-b998-1cf5-6891125746aa.png)

ここでは、タブスタイルを選択し、「次へ」をクリック。
その後、表示するユーザー・表示するアプリケーションの設定があるが、デフォルトのまま「次へ」で進み、保存する。

6.カスタム項目の作成

再度、設定-プラットフォームツール-「オブジェクト及び項目」-「オブジェクトマネージャ」から、先ほど作成したカスタムオブジェクトを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/ce45209a-d66e-e2fb-4193-f3f86199f1ea.png)

左メニューより、「項目とリレーション」を選択する。
![SF2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/e0e821a0-b838-0975-5660-b487afc07d31.png)


画面右上の「新規」ボタンをクリック。

![SF3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/1d815e32-dc92-aca9-5bfb-80ea49fa87d5.png)

項目のデータ型等を選択する。
ここでは例として電流値の項目を作るので、「数値」を選択して「次へ」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/8e03b883-4494-3dc6-b86d-c7940d38001e.png)


項目名、桁数等設定して「次へ」をクリックする。

![SF4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/958e3d94-0efa-e20e-dcc1-b477f266145c.png)

項目レベルセキュリティの設定はデフォルトのまま「次へ」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/b8dbb5d2-6964-7b00-6762-e1893321726f.png)

ページレイアウトへの追加もデフォルトのままでよい。
「保存」あるいは「保存＆新規」をクリックする。

上記と同様の手順で、必要な項目を追加していく。

#### ● OAuth設定とAPIの有効化

RaspberryPiから測定値をSalesforceにアップロードするには、REST APIかSOAP APIを使用する。
これを使用可能にするには、ユーザープロファイルの「APIの有効化」にチェックを入れる必要がある。

「設定」-「ユーザー」でユーザー一覧を表示。
DBアクセスに使用するユーザーのプロファイルを開き、「編集」ボタンを押す。そして、「APIの有効化」にチェックを入れて保存する。

あと、外部からAPIアクセス時に、パスワードとは別にセキュリティトークンを求められる。
セキュリティトークンがわからない場合は、以下の手順で再発行できる。

1. 画面右上のキャラクターアイコンをクリックし、「設定」をクリック。
2. 左側メニューから、「私のセキュリティトークンをリセット」を選択。
3. 「セキュリティトークンをリセット」ボタンを押す。

上記を実施すると、登録したメールアドレスにセキュリティートークンが記載されたメールが送られてくる。

次に、OAuth設定をするために「接続アプリケーション」を作成する。
「設定」-「アプリケーション」-「接続アプリケーション」から作成できる。

これについては、以下のサイトに詳しく書かれているので参照させていただいた。

[simple_salesforceを使ってPythonからSalesforceのREST APIへアクセスしてみた](https://dev.classmethod.jp/articles/settingup-simple_salesforce-for-python/)

[REST APIを使ってSalesforceのデータを取得する](https://qiita.com/nsuhara/items/19cf8ec89b88fb3deb39)

#### ●REST API経由でテストデータの投入

ここからはRaspberryPi側での作業となる。
前回の記事のソースコードを修正し、測定値をSalesforceのカスタムオブジェクトにアップロードするコードを追加した。
Salesforceへのアクセスには、Salesforce REAST APIを使用する。

[Salesforce REST API開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/quickstart.htm)

Salesforceのpython用のライブラリはいくつかあるようだが、ここでは、simple_salesforceを使用する。
先ほど紹介したサイトにライブラリの導入手順等書かれているので参照させていただいた。

[simple_salesforceを使ってPythonからSalesforceのREST APIへアクセスしてみた](https://dev.classmethod.jp/articles/settingup-simple_salesforce-for-python/)

```python
import serial
import struct
import datetime as dt
import json
from simple_salesforce import Salesforce

USERNAME = "ユーザー名"
PASSWORD = 'パスワード'
SECURITY_TOKEN = "セキュリティトークン"

use_port = "/dev/ttyACM0"

_serial = serial.Serial(use_port)
_serial.baudrate = 115200
_serial.parity = serial.PARITY_NONE
_serial.bytesize = serial.EIGHTBITS
_serial.stopbits = serial.STOPBITS_ONE
_serial.timeout = 15

def Login():
    sf = Salesforce(username=USERNAME, password=PASSWORD,
                    security_token=SECURITY_TOKEN)
    return sf

sf = Login()
try:                                                                                                                        while True:
        rx = _serial.readline()
        #rx = rx.strip()
        st = "{0},{1}".format(dt.datetime.now(), rx)
        print(st)
        with open('/home/pi/current_{}.log'.format(dt.date.today()), mode="a") as f:
            f.write(st)

        datas = st.split(",")
        if len(datas)<3:
            continue

        t1 = datas[0][0:19]                                                                                                     t2 = t1.replace(" ","T") + "Z"                                                                                          print("{0},{1}".format(t1,t2))
        try:
            for i in range(1,len(datas)):
                datas[i] = datas[i].replace("b'","").replace("\\r\\n'","").strip()

            if len(datas[1])==0 or len(datas[2])==0 or len(datas[1])>10 or len(datas[2])>10 :
                continue
            if datas[1][:1].isdigit()==False or datas[2][:1].isdigit()==False:
                continue

            res = sf.GeneratorLog__c.create({'Name': t1, # Name項目を文字列型とし、日時をセットしている
                                             'MeasDate__c': t2, # 日時(Datetime型)
                                             'Current__c': float(datas[1]), # 電流値
                                             'Voltage__c': float(datas[2]), # 電圧値
                                             'Temperature__c': 20.00}) # 温度は将来的に測定予定のため、項目だけ作成したが、固定値を設定
            if res.get('error'):
                raise Exception(response.get('error_description'))

            print(json.dumps(res, indent=4))

        except Exception as e:
                sf = Login() # ログインし続けるとタイムアウトで例外発生するので、再ログインしてリトライ
                res = sf.GeneratorLog__c.create({'Name': t1,
                                                 'MeasDate__c': t2,
                                                 'Current__c': float(datas[1]),
                                                 'Voltage__c': float(datas[2]),
　                                               'Temperature__c': 20.00})
                print(json.dumps(res, indent=4))

except Exception as ex:
    print(ex)
finally:
    _serial.close()
```

INA260に太陽光パネル、あるいはテスト用の電池等を接続して実行すると、Salesforceの画面からデータがアップロードされているのを確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/7597ab18-994f-a352-068f-e0cbf8a7a19b.png)

ちなみに、作成したカスタムタブの表示方法は、Lightning Experienceアプリケーションで、タブ表示欄右端のペンマークをクリックすると、表示させるタブを選択できる。
Classicアプリケーションだとタブ表示のカスタマイズができたくなっているので注意すること。
タブ表示欄左端のアプリケーション選択ボタン押下で、「すべて表示」からでもタブ選択ができた。(最近、Lightning Experienceへの切り替え移行のためか、以前できていたことができなくなることがあるので要注意)

![SF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/00283060-8433-9e96-b2dc-d42375aa7430.png)

どのアプリケーションでもよいので、つぎのタブを追加する。
・発電ログ(作成したカスタムタブ)
・レポート(以下で説明)
・ダッシュボード(以下で説明)

#### ● レポートの作成

データをロギングしても、ただ貯めるだけでは楽しくない。
やはりグラフ化しないと傾向が良くわからない。
グラフ表示するために、レポートを作成する。

レポートタブを選択し、画面上部の「新規レポートの作成」をクリックする。このとき、Classicではない方のボタンをクリックすること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/0cb1466a-03ea-3dff-05f0-9e6cec4328ac.png)

「レポートタイプを選択」画面では、存在するオブジェクトが一覧表示される。自分が作成したカスタムオブジェクト(発電ログ)を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/357b5039-6a41-562a-f1b0-fff6ece61d1b.png)

ここから
・表示項目
・検索条件
・グループ化
を設定して、グラフにするためのデータを用意していく。

描きたいグラフは、日別にX軸に時間、Y軸に電流を表示したい。
そのため、表示項目に電流を追加する。
画面左の「列」下の検索欄に「電流」と入力するか、画面左端の「項目」を開き、「電流」を選択する。
すると、画面中央の表に「電流」が追加されるのがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/5f03a231-95bc-10a3-e866-f00f5630a57c.png)

しかし、画面上部の「グラフを追加」ボタンが無効のままである。
グラフを表示させるにはグループ化する必要がある。
そのため、日別に10分毎の平均電流を表示させることにする。

ここで、「サービスの設定」-「オブジェクト及び項目」に戻り、カスタムオブジェクト(発電ログ)にカスタム項目を追加することにする。

| 項目名 | データ型 | 数式 | 備考 |
|---------|-------|--------|--------|
| 日　| 数式　| DATEVALUE( LEFT(Name,10)) | |
| 分時間 | 数式　| VALUE(MID(Name,12,2) & "." & MID(Name,15,1)) | 時間と、分の10の位をセット|

ちなみに、Name項目には測定日時が文字列型で「yyyy-MM-dd HH:mm:ss」で入力されている。

作成したカスタム項目を、早速レポートに追加する。
「行をグループ化」で「日」「分時間」を追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/e6e5ab0e-2edf-b67c-7e10-ff78127d7a4e.png)

また、「列」の「電流」をクリックすると、集計メニューが表示されるので、平均を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/e53b0ff7-5b19-6232-8fba-67f2f4a7e190.png)

ここでようやく、「グラフを追加」ボタンが有効になる。
「グラフの追加」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/b048dbde-4dd9-976e-daa1-87a4c1155c63.png)

グラフ右上のギアボタンをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/c1d9d8be-c516-a22a-a98d-63128132f683.png)

表示グラフ：折れ線
タイトル：電流測定
X軸：分時間
系列：日
Y軸：電流平均

画面上にグラフが正常に表示されていることが確認出来たら保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/90a57be6-6bf5-0ba5-9e0d-a24971b62791.png)

同様に、電圧や電力に関してもレポート作成してみてもよいだろう。

#### ● ダッシュボードの作成

レポートを見やすく表示するために、ダッシュボードに追加する。

ダッシュボードタブを選択し、画面上部の「新規ダッシュボード」をクリック。
ダッシュボードの名前を入力して「作成」をクリック。
画面上部の「＋コンポーネント」ボタンを押すと、レポート一覧が表示されるので、表示したいレポートを選択する。
つぎに、レポートのグラフ作成と同様のフォームが表示されるので、レポートのグラフ作成と同様に設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/5f6d0296-e412-3590-5625-1a8485ee273d.png)

「追加」ボタンを押すと、グラフのコンポーネントが画面上に追加される。
表示したいレポートを同様にどんどん追加して保存すると、こんな感じになる。

![SF5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627239/50b793d2-9357-b1ca-f72f-3a1cbbb8dd08.png)

これで、どこからでもSalesforceにログインしてダッシュボードにアクセスすれば、発電量をリアルタイム監視できるようになった。
ただ、注意点が一つ。
画面右上の更新ボタンを押さないとデータ更新されないので気を付けること。


[【太陽光発電の発電量をロギングしてみた。目次】](https://qiita.com/takoyakiya/items/6b318ab83bcac86c966c)