Python Instrument Panel(10)SampleーTemp & Humidity
Androidアプリ「GUI Maker for ESP8266 & ESP32 – Python Inst. Panel」を使って、温湿度センサーDHT11から取得したデータをグラフに表示します。最後に載せてあるXMLをAndroidのブラウザでコピーしてアプリにペーストすることでインストールできます。
2017/10/17 追記:縦軸を固定レンジにしました。
2017/10/23 追記:mySetup()、myLoop()に独自のコードを追加するようにしました。
先ずは、ESP8266またはESP32のArduinoスケッチを変更します。
スケッチ全体は「Python Instrument Panel(2)Arduinoスケッチ」を見てください。最後にある mySetup()、process() を変更します。Androidアプリから”DHT?″の文字列を送ると温度と湿度を測定して”19.0,74.0″のように温度と湿度をカンマで繋いで返します。数値を返せないときは”nan,nan”のように数値の代わりに”nan”を返します。
今回はDHT11用のライブラリを使うので process() 以外にも変更箇所があります。
Arduino IDEのライブラリマネージャを開いてライブラリをインストールします。
“DHT”でフィルターして表示される”DHT sensor library”をインストールします。
“OneWire”でフィルターして表示される”OneWire”もインストールします。
スケッチを変更します。先ずは、Wifi用のinclude文に下に温湿度センサーDHT11用のinclude文を追加します。
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <DHT.h> // add
次に mySetup() の前に定数、変数を追加し、 mySetup()、process() の内容を変更します。
#define DHTTYPE DHT11 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE); void mySetup() { dht.begin(); } void myLoop() { } String process(String str) { Serial.println(str); if (str == "DHT?") { float t = dht.readTemperature(); float h = dht.readHumidity(); String ret = String(t, 1) + "," + String(h, 1); Serial.println(ret); return ret; } return ""; }
では、パネルを作りましょう。
をタップして編集モードにして、をタップして新規パネルを表示します。
パネルに名前を付けておきます。
ExecCodeアイテムを使ってArduinoスケッチの動作を確認しておきます。をタップしてESP8266またはESP32と接続します。下記のPythonコードをExecCodeアイテムに入力してAndroid入力画面から抜けると、ESP8266またはESP32に”DHT?″という文字列が送信され、温度と湿度をカンマで繋いだ文字列が返ります。
ExecCodeアイテムのPythonコードを変更して、文字列から温度と湿度のfloat変数に変換できることを確認しておきます。
if Remote.Writer != None: Remote.Writer.WriteLine('DHT?') Remote.Writer.Flush() ret = Remote.Reader.ReadLine() slist = ret.split(',', 1) t = float(slist[0]) h = float(slist[1]) print '%.1f, %.1f' % (t, h)
次に、パネルにTextアイテム、Dropdownアイテム、Buttonアイテム、2個目のPlotViewアイテムを配置します。
Start/Stop ButtonのScriptです。Timerが停止しているときタップされると、2つのPlotViewをクリアしてTimerを開始します。Timerが動作しているときタップされるとTimerを停止します。
if Items[1].Value == 0: Items[2].ClearData() Items[2].Invalidate() Items[3].ClearData() Items[3].Invalidate() Items[8].Text = 'Running' Items[8].B = 0x0000ffff Items[1].Value = 1 else: Items[8].Text = 'Stopped' Items[8].B = 0x000000ff Items[1].Value = 0
Interval DropdownのScriptです。
if value == 0: Items[1].Interval = 1 elif value == 1: Items[1].Interval = 10 else: Items[1].Interval = 60
TimerのScriptです。事前にExecCodeアイテムで使ったコードに、表示のためのコードを追加しています。PlotViewの横軸に時刻を表示するため、現在時刻とデータを渡しています。
if Remote.Writer != None: Remote.Writer.WriteLine('DHT?') Remote.Writer.Flush() ret = Remote.Reader.ReadLine() now = DateTime.Now slist = ret.split(',', 1) t = float(slist[0]) h = float(slist[1]) print '%s, %.1f, %.1f' % (now, t, h) Items[10].Text = '%.1f ℃' % t Items[11].Text = '%.1f %%' % h points = int(Items[7].Options[Items[7].Value]) if t != float.NaN and h != float.NaN: if Items[2].DataCount > points: Items[2].RemoveData() Items[2].AddData(now, t) Items[2].Invalidate() if Items[3].DataCount > points: Items[3].RemoveData() Items[3].AddData(now, h) Items[3].Invalidate()
PlotViewの横軸に時刻を表示するには、Panel setup scriptでStringFormatプロパティを設定します。縦軸は固定レンジにします。
完成したパネルのPanel contextは次のようになります。Androidのブラウザでコピーして、で追加した新規パネルのPanel context でペースト、さらにで新規パネルが”Temp & Humidity”パネルになります。
<?xml version="1.0" encoding="utf-8"?> <PanelContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Id>fb2bdeb2-5fec-4425-a2b6-262bf22ba2c0</Id> <PredefinedId>00000000-0000-0000-0000-000000000000</PredefinedId> <Name>Temp & Humidity</Name> <ItemList> <ItemContext> <Id>8c81561f-4b2b-4df4-8ff8-f8acbb465bb1</Id> <Index>1</Index> <ItemType>5</ItemType> <X>10</X> <Y>-20</Y> <TimerValue>true</TimerValue> <TimerInterval>1</TimerInterval> <TimerScript>if Remote.Writer != None: Remote.Writer.WriteLine('DHT?') Remote.Writer.Flush() ret = Remote.Reader.ReadLine() now = DateTime.Now slist = ret.split(',', 1) t = float(slist[0]) h = float(slist[1]) print '%s, %.1f, %.1f' % (now, t, h) Items[10].Text = '%.1f ℃' % t Items[11].Text = '%.1f %%' % h points = int(Items[7].Options[Items[7].Value]) if t != float.NaN and h != float.NaN: if Items[2].DataCount > points: Items[2].RemoveData() Items[2].AddData(now, t) Items[2].Invalidate() if Items[3].DataCount > points: Items[3].RemoveData() Items[3].AddData(now, h) Items[3].Invalidate()</TimerScript> <V1_0_5 /> </ItemContext> <ItemContext> <Id>2b661516-3dbc-4dcf-9e4c-0cc5237d98ed</Id> <Index>2</Index> <ItemType>6</ItemType> <X>10</X> <Y>-80</Y> <PlotViewH>200</PlotViewH> <PlotViewText>Temperature</PlotViewText> <PlotViewScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>0ab1cf7c-4a06-4a8a-b8a1-e1e829b4fc3f</Id> <Index>3</Index> <ItemType>6</ItemType> <X>10</X> <Y>-140</Y> <PlotViewH>200</PlotViewH> <PlotViewText>Humidity</PlotViewText> <PlotViewScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>e29b48d1-c69d-4122-b472-a299c9b8443e</Id> <Index>4</Index> <ItemType>3</ItemType> <X>80</X> <Y>-20</Y> <TextW>100</TextW> <TextH>45</TextH> <TextText>Interval</TextText> <TextFontSize>24</TextFontSize> <TextTextAlignment>2</TextTextAlignment> <TextF>255</TextF> <TextB>0</TextB> <TextScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>04c2893f-29a1-4efd-8149-e7a880b07d99</Id> <Index>5</Index> <ItemType>3</ItemType> <X>80</X> <Y>-70</Y> <TextW>100</TextW> <TextH>45</TextH> <TextText>Points</TextText> <TextFontSize>24</TextFontSize> <TextTextAlignment>2</TextTextAlignment> <TextF>255</TextF> <TextB>0</TextB> <TextScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>b369f922-959e-4565-93c1-d854283ec450</Id> <Index>6</Index> <ItemType>4</ItemType> <X>190</X> <Y>-20</Y> <DropdownW>120</DropdownW> <DropdownH>45</DropdownH> <DropdownText>1s;10s;60s</DropdownText> <DropdownFontSize>24</DropdownFontSize> <DropdownValue>0</DropdownValue> <DropdownScript>if value == 0: Items[1].Interval = 1 elif value == 1: Items[1].Interval = 10 else: Items[1].Interval = 60</DropdownScript> <V1_0_5 /> </ItemContext> <ItemContext> <Id>1123d949-d750-4fc4-9743-e6203cf69586</Id> <Index>7</Index> <ItemType>4</ItemType> <X>190</X> <Y>-70</Y> <DropdownW>120</DropdownW> <DropdownH>45</DropdownH> <DropdownText>100;200;500;1000;2000;5000</DropdownText> <DropdownFontSize>24</DropdownFontSize> <DropdownValue>2</DropdownValue> <DropdownScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>ce5b3c15-624d-4f00-b22a-1969bb9208b9</Id> <Index>8</Index> <ItemType>3</ItemType> <X>170</X> <Y>-140</Y> <TextW>140</TextW> <TextH>50</TextH> <TextText>Running</TextText> <TextFontSize>24</TextFontSize> <TextTextAlignment>1</TextTextAlignment> <TextF>4294967295</TextF> <TextB>65535</TextB> <TextScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>6123d177-da73-415d-b90a-bb6efa3de905</Id> <Index>9</Index> <ItemType>0</ItemType> <X>170</X> <Y>-190</Y> <ButtonW>140</ButtonW> <ButtonH>80</ButtonH> <ButtonText>Start/Stop</ButtonText> <ButtonFontSize>24</ButtonFontSize> <ButtonTextAlignment>1</ButtonTextAlignment> <ButtonScript>if Items[1].Value == 0: Items[2].ClearData() Items[2].Invalidate() Items[3].ClearData() Items[3].Invalidate() Items[8].Text = 'Running' Items[8].B = 0x0000ffff Items[1].Value = 1 else: Items[8].Text = 'Stopped' Items[8].B = 0x000000ff Items[1].Value = 0</ButtonScript> <V1_0_5 /> </ItemContext> <ItemContext> <Id>0cf2d8bd-16e8-48b8-a6de-1c80d1c50c7c</Id> <Index>10</Index> <ItemType>3</ItemType> <X>320</X> <Y>-20</Y> <TextW>300</TextW> <TextH>120</TextH> <TextText>-- ℃</TextText> <TextFontSize>60</TextFontSize> <TextTextAlignment>1</TextTextAlignment> <TextF>4294967295</TextF> <TextB>16711935</TextB> <TextScript /> <V1_0_5 /> </ItemContext> <ItemContext> <Id>a80d8738-bfa7-46bc-b84f-fbbf460a4111</Id> <Index>11</Index> <ItemType>3</ItemType> <X>320</X> <Y>-150</Y> <TextW>300</TextW> <TextH>120</TextH> <TextText>-- %</TextText> <TextFontSize>60</TextFontSize> <TextTextAlignment>1</TextTextAlignment> <TextF>4294967295</TextF> <TextB>16711935</TextB> <TextScript /> <V1_0_5 /> </ItemContext> </ItemList> <CurrentItemId>a80d8738-bfa7-46bc-b84f-fbbf460a4111</CurrentItemId> <SetupScript>Items[2].StringFormat = 'HH:mm:ss' Items[3].StringFormat = 'HH:mm:ss' Items[2].FixedRange(-10, 40) Items[3].FixedRange(0, 100)</SetupScript> <TeardownScript /> </PanelContext>