2017-12-28

raspberry pi zero wとダイソーのリモートシャッターとrubyで遊ぶ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
raspberry pi zero wを買ったのは、bluetooth機器とつないで、ちょっと遊んでみたいなぁと思っていたことも一つの理由だったりします。

お手軽に遊ぶ材料として、ダイソーで売っているリモートシャッターがよさげかと思ってみました。以下と同じもののようです。



これを利用した例を以下のサイトを紹介していたので、参考にさせてもらいました。
https://qiita.com/vimyum/items/8b7548ca8cf45383c5b0

こちらでは、bluebuttonというツールを利用しているのですが、ソースは以下にあります。
https://github.com/kinnalru/bluebutton

こちらのソースを見て、ちょっと遊んでみました。
こちらでは、二つのボタンを特に区別してなくて、押したことと長押しを検出していたので、ボタンを識別できるよう改造してみました。

上のIOSボタンは、押すとVolumeUpが送られてきているようです。
下のandoridボタンは、押すとEnterが来て、さらにVolumeUpが送られてきてるようです。

これで識別できそうなので、改造したのは以下のものになります。
rootで実行する必要があります。
これは、二つのボタンとそれぞれの長押しを検出して、さらにLINEに特定のメッセージを送るようにしてみました。

require 'device_input'
require 'rest-client'
require 'json'
class LineBot
TOKEN = "Channel Access Token"
TO = "送信先のID"
def self.send(msg)
headers = {
"Content-Type" => "application/json; charser=UTF-8",
"Authorization" => "Bearer #{TOKEN}",
}
params = {
to: TO,
messages: [
{
type: "text",
text: msg,
}
]
}
RestClient.post "https://api.line.me/v2/bot/message/push", params.to_json, headers
end
end
class Bluebutton
attr_accessor :device
def initialize name
finded = Dir.glob("/sys/**/name").select do |file|
File.read(file).downcase[name.downcase]
end.first
raise "Can't find device info '#{name}' in /sys/**/*" if finded.nil?
@device = "/dev/" + Dir.glob("#{File.dirname(finded)}/**/uevent").map do |file|
File.read(file).split("\n").select{|s| s['DEVNAME']}.compact.first
end.compact.flatten.first.split("=")[1] rescue nil
@msg = {"VolumeUp" => "iOSボタンを押したよ",
"Enter" => "androidボタンを押したよ"}
@long_msg = {"VolumeUp" => "iOSボタンを長く押したよ",
"Enter" => "androidボタンを長く押したよ"}
puts "Device #{name} find at #{@device}"
end
def run
File.open(@device, 'rb' ) do |input|
puts "Connected"
DeviceInput.read_loop(input) do |event|
if event.type == 'EV_KEY'
if event.value > 0
key_down event
else
key_up event
end
end
end
end
end
def key_down event
if @pressed.nil?
@pressed = Time.now
@code = event.code
LineBot.send(@msg[@code])
puts "push #{@code}"
elsif @long.nil? && @pressed < (Time.now - 1)
LineBot.send(@long_msg[@code])
puts "long push #{@code}"
@long = true
end
end
def key_up event
@long = nil
@pressed = nil
@code = nil
end
end
device = "AB Shutter3"
puts "Try to find device #{device}..."
button = Bluebutton.new(device)
puts "Reading events from #{button.device}..."
button.run

とりあえずIoTな気分を感じてみました。


0 件のコメント: