LoginSignup
4
5

More than 5 years have passed since last update.

Raspberry PiからErlangでGoogleスプレッドシートに値を書き込んでみた

Last updated at Posted at 2016-03-19

モチベーション

Raspberry PiでErlang使ってADコンバータでアナログ値取得してみたに同じ

Googleスプレッドシートに値を書き込むAPIを用意

自分で作ったわけではないです。。。
Sheetsuというサービスがあるので、これを使うとほーらできた(3分クッキング)。
使い方はここを参照ください。

ErlangでSheetsu APIを叩く用意

下記コードの、sheetsu:loop(Name, List)は、String型の要素をもつ下記リストをNameに

[ "Column1", "Column2", "Column3" ] 

Nameの各要素に対応する値をString型で要素として持つタプルを、要素としてもつ下記リストをListに渡せば、

[ { "Column1_Value#1", "Column2_Value#1", "Column3_Value#1" } , { "Column1_Value#2", "Column2_Value#2", "Column3_Value#2" }, ... ]

下記のようなJSON形式のStringを出力する(Listの要素がタプル一つなら[]は出力しない)。

[ { "Column1":"Column1_Value#1", "Column2":"Column2_Value#1", "Column3":"Column3_Value#1" } , { "Column1":"Column1_Value#2", "Column2":"Column2_Value#2", "Column3":"Column3_Value#2" }, ... ]

sheetsu.erl
-module(sheetsu).
-compile(export_all).

init() ->
 inets:start(),
 ssl:start().

get(URL) ->
 {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} = httpc:request(URL).

post(URL, Body) ->
 R = httpc:request(post, {URL, [], "application/json", lists:flatten(Body)}, [], []).


%% loop: カラム名のリスト(Name)と、カラム名に対応する値をストリングにして並べたタプルのリスト(List)から、JSON形式のマトリクスを作る。sheetsu APIはpostは1行しか渡せないので冗長だが。。。
loop(Name, List) ->
 case length(List) =:= 1 of %% List長が2以上なら[]で挟む。
  true -> loop(Name, List, []);
  false -> string:concat(string:concat("[ ", loop(Name, List, [])), " ]")
 end.

loop(Name, [], StrList) ->
 string:join(StrList, ", ");

loop(Name, List, StrList) -> %% カラム名のリスト(Name)と、カラム名に対応する値をストリングにして並べたタプルのリストを渡す。
 [H | T] = List,
 AddedStrList = [string:concat(string:concat("{ ", string:join([ io_lib:format("\"~s\":\"~s\"", [Attribute, Element]) || {Attribute, Element} <- lists:zip(Name , tuple_to_list(H)) ], ", ")), " }")] ++ StrList,
 loop(Name, T, AddedStrList).

Raspberry PiにつないだADコンバータの取得値をGoogleスプレッドシートに書く

Raspberry PiでErlang使ってADコンバータでアナログ値取得してみたのコードを上記を使うよう修正。
後に示すよう、Date, Max, Min, Avgのカラム名を持つスプレッドシートなので500msずつのADコンバータからの取得値を30秒(500ms x 60回)に一回、最大、最小、平均値を計算し { "Date":"3/19/2016 8:17:50", "Max":"4321", "Min":"1234", "Avg":"2345" }みたいな感じでPostする。

print2.erl
-module(print2).
-compile(export_all).

-define(SPICLK, "11"). %% GPIOピン番号
-define(SPIMOSI, "10").
-define(SPIMISO, "9").
-define(SPICS, "8").
-define(LED, "25").
-define(URL, "https://sheetsu.com/apis/xxxxxxxx"). %% GoogleスプレッドシートAPIのURL(xxxxxxxxはご自分のものに変更ください)

main() ->
 io:format("initializing...~n"),
 pi_gpio:set_pin_direction(?SPICLK, "out"),
 pi_gpio:set_pin_direction(?SPIMOSI, "out"),
 pi_gpio:set_pin_direction(?SPIMISO, "in"),
 pi_gpio:set_pin_direction(?SPICS, "out"),
 pi_gpio:set_pin_direction(?LED, "out"),
 sheetsu:init(), %% httpc使うためのinitialize
 mainloop([], 60).


mainloop(List, 0) ->
 Sum = lists:sum(List),
 Length = length(List),
 Max = lists:max(List), %Listの最大、最小、平均値を求める。
 Min = lists:min(List),
 Avg = Sum/Length,
 {{Year,Month,Day},{Hour,Minute,Second}} = calendar:now_to_datetime(erlang:now()),
 Date = lists:flatten(io_lib:format("~b/~b/~b ~b:~b:~b", [Month, Day, Year, Hour, Minute, Second])),
 Body = sheetsu:loop(["Date", "Max", "Min", "Avg"], [{Date, integer_to_list(Max), integer_to_list(Min), float_to_list(Avg, [{decimals, 2}])}]), %% カラム名のリストと、カラム名に対応する値をストリングにして並べたタプルを渡す。
 io:format("Post: ~s~n", [Body]),
 sheetsu:post(?URL, Body),
 mainloop([], 60);

mainloop(List, N) ->
 Val = readadc(0),
 io:format("~w~n", [Val]),
 case Val < 2000 of %% 取得値が一定値以上でLED点灯
  true -> pi_gpio:set_pin_value(?LED, "1");
  false -> pi_gpio:set_pin_value(?LED, "0")
 end,
 timer:sleep(500),
 AddedList = [Val] ++ List,
 mainloop(AddedList, N-1).


readadc(Adcnum) ->
...
%%readadc(Adcnum)以下は、「Raspberry PiでErlang使ってADコンバータでアナログ値取得してみた」のprint.erlと同じ

実行

Raspberry PiでErlang使ってADコンバータでアナログ値取得してみたと同様に実行すると、30秒に一回下記のような出力

Googleスプレッドシート上には下記のように書き込まれる。

Raspberry PiでErlang使ってADコンバータでアナログ値取得してみた含め、ここはこう書くと美しいとかあればコメントいただければ

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5