モチベーション
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" }, ... ]
-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する。
-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コンバータでアナログ値取得してみた含め、ここはこう書くと美しいとかあればコメントいただければ