前回までの状況はこちら。
最新ソースはこちら。
ラズパイ https://github.com/takishita2nd/RaspiDisplayMonitor
Windows https://github.com/takishita2nd/IroiroMonitor
Windows側からラズパイの情報を取得できるなら、
Windows側からでもラズパイを操作する事も出来ます。
なので、Windows側からスイッチ操作を行う処理を作ってみます。
Windowsにボタンを設置。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="時刻" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Width="239" Height="86" FontSize="48"/>
<Label Grid.Row="1" Grid.Column="0" Content="温度" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Width="239" Height="86" FontSize="48"/>
<Label Grid.Row="2" Grid.Column="0" Content="湿度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
<Label Grid.Row="3" Grid.Column="0" Content="CPU温度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
<Label Grid.Row="4" Grid.Column="0" Content="GPU温度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding DateTime}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
<Label Grid.Row="1" Grid.Column="1" Content="{Binding Temperature}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
<Label Grid.Row="2" Grid.Column="1" Content="{Binding Humidity}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
<Label Grid.Row="3" Grid.Column="1" Content="{Binding CpuTemp}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
<Label Grid.Row="4" Grid.Column="1" Content="{Binding GpuTemp}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
<Button Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="2" Content="ボタン" Command="{Binding ButtonClickCommand}" FontSize="48" />
</Grid>
ボタンを押すと、ラズパイ側にPOSTリクエストを送信するようにします。
今後の拡張性を考えて、コマンド番号みたいなものを送れるようにしましょうか。
[JsonObject("CommandModel")]
class Command
{
[JsonProperty("number")]
public int number { get; set; }
}
public class MainWindowViewModel : BindableBase
{
private const int CommandSwitch = 1;
public DelegateCommand ButtonClickCommand { get; }
public MainWindowViewModel()
{
ButtonClickCommand = new DelegateCommand(async () =>
{
Command cmd = new Command();
cmd.number = CommandSwitch;
var json = JsonConvert.SerializeObject(cmd);
try
{
HttpClient client = new HttpClient();
var content = new StringContent(json, Encoding.UTF8);
await client.PostAsync("http://192.168.1.15:8000/", content);
}
catch (Exception ex)
{
}
});
これで、ラズパイ側にPOSTリクエストを送れるようになりました。
次はラズパイ側のコードを書いていきます。
class StubHttpRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_len = int(self.headers.get('content-length'))
requestBody = json.loads(self.rfile.read(content_len).decode('utf-8'))
if requestBody['number'] == 1:
lock.acquire()
GLCD.GLCDDisplayClear()
lock.release()
pushButton()
response = { 'status' : 200 }
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
responseBody = json.dumps(response)
self.wfile.write(responseBody.encode('utf-8'))
HttpRequestHandlerクラスにdo_POSTメソッドをオーバーライドします。
これを実装することで、POSTリクエストを受診して処理することが出来ます。
受信したデータがボタン操作ならば、ラズパイ側で行っているボタン操作と同じ処理をおこないます。
def pushButton():
global mode
mode += 1
if mode > 4:
mode = 1
しかし、ここで考えなければならないのは、ラズパイ側の周期処理とHTTPサーバ処理は非同期処理を行っていると言うこと。
はい、処理が競合しちゃいます。
なので、スレッド間の待ち合わせ処理を行う必要があります。
方法はいろいろあるのですが、今回は一番簡単な方法を使用します。
Lockを使用する方法です。
lock = threading.Lock()
try:
while True:
lock.acquire()
Humidity = AM2320.GetHum()
Temperature = AM2320.GetTemp()
if sw == True:
GLCD.GLCDDisplayClear()
pushButton()
sw = False
if mode == 1:
-中略-
lock.release()
time.sleep(1)
except KeyboardInterrupt:
GLCD.GLCDDisplayClear()
GPIO.cleanup()
lock = threading.Lock()を定義し、同じlockで周期処理全体と、HTTPのスイッチ処理をlock/releaseで囲みました。
これで、一方がlockされている場合、もう一方はlockがreleaseされるまで処理に待ったがかかります。
これを使用すれば、ラズパイの遠隔操作も可能になります。