はじめまして!
この記事はAkerun Advent Calendar の記念すべき1日目の記事です。 今回はAkerunをつくっている会社フォトシンスのCTOのkazuphが担当します!(`・ω・´)ゞ
IoTツール開発
弊社のメインプロダクトはAkerunというスマートロックですが、その開発や工場での生産の過程で様々なIoTツールを開発しています。
つまり、ネットワークに接続するツールを開発することで、開発生産性を高めたり工場での作業フローを改善して、品質と原価削減を行っています。
去年のbuildersconやAdvent Calendarではその一部を発表させていただきました。
あれから1年
ちょこちょこ自分がつくったツールを晒してみます。詳しくは、別記事で掘るかも。
[mqtt-eater]MQTTの流れを保存し画面表示+Slackに通知する君
うちの開発だと登場人物が多くてテストをするときなどは、信号の発信役、中継役、受け取り役などパートごとに開発者が違うので、わざわざ動作を確認してもらうのが億劫なときがあります。そういうときに、Slackとかで見れると便利だろうということでつくりました。
今回は情報の発信元のログ(MQTTのPublish)をSlackに流し、中継役(ゲートウェイ)、受け取り役(スマートロック本体)の開発者がそれを見ます。
使用gemは以下(あ、rubyが前提になってる)。
ソースコードのイメージは以下のような感じです。
class Mqtt def self.run t = Thread.new do MQTT::Client.connect( remote_host: "<mqtt.broker.domain>", remote_port: <XXXX>, username: "<user_name>", password: "<password>", ssl: true, ) do |client| client.subscribe('<your_topic>/#') client.get do |topic,message| Slack.post "#dev-mqtt-log , "[MQTT] pub #{topic}: #{message}" ary = topic.split('/') DB.create_or_update ary.last, ary.first, message end end end end end
開発用にPOSTも付けるといいかなと思いましたが、社内向け管理画面に"Chamber"という名前のカッコいいツールがあるので、そっちと統合してもいいかなと思い一旦最低限までやってペンディング中。
Sinatraの部分は一旦僕がニヤニヤするためだけに、今後も開発を続けてもいいかなという感じです。
[auto-wifi-setting-changer]APの管理画面から自動でWi-Fi設定を更新する君
Wi-Fiの周波数・チャネルが切り替わるものが増えてきているので、それを連続で試験するためにつくりました。 APの管理画面はWebベースなことが多いので、スクレイピングすればほぼなんでもできます。
使用gem
- capybara
- selenium-webdriver
- chromedriver-helper
- pry
スクレイピングしたいと思う度にcapybaraは未だ顕在だし、調べれば調べるほどに簡単な書き方が出てきて本当に素晴らしいですね(無駄なsleepを徹底的に解除できる)。
最近はChromeDriverも安定していて、開発中はpryで止めてChromeのインスペクターでDOMを確認しながら、pryのconsoleにclick_on
とか打ち込みながらどんどんつくれるので、一瞬でつくれていいです。
ソースコードのイメージは以下みたいな感じ。
#!/usr/bin/env ruby # coding : utf-8 require 'capybara' require 'capybara/dsl' require 'selenium-webdriver' require 'pry' require 'logger' class WifiSetting include Capybara::DSL def initialize() Capybara.run_server = false Capybara.default_driver = Capybara.javascript_driver = :selenium_chrome # or :rack_test, :selenium, :selenium_chrome, :selenium_chrome_headless, :mobile, :webkit Capybara.app_host = "https://ap.ip" @log = Logger.new(STDOUT) @log.info "initialize" end def login visit("/") fill_in('username', with: ENV['ID']) fill_in('password', with: ENV['PASS']) click_button('Login') @log.info "login" end def change_channel(number) select "Channel #{number}", from: 'channel' click_button('Update') @log.info "Update Channel #{number}" end def change_state(enable: nil) click_on "Wireless9" if enable choose "Enabled", name: "wireless" else choose "Disabled", name: "wireless" end click_button('Update') @log.info "Update Enable #{enable}" end end if __FILE__ == $0 o = WifiSetting.new() o.login loop do o.change_state enable: true o.change_channel o.random_channel o.change_state enable: false end end
これの派生で、サクッとAkerunのユーザー向け管理画面からユーザー追加や鍵発行をして、ハード側にその情報がちゃんと伝搬するかなどのテストとかも行っております。
[akerun-api]Rubyを使ってバイナリ書き換えーる君
これは、ツールというか、Akerun API本体についに組み込みました。
もともと、工場で動くツール(shellでperlでワンライナー)でバイナリ置換を行っていたのですが、Rails(Ruby)側で置換して単にダウンロードすればいいんじゃね?IoTっぽいしということで、クラウド側に置換処理を持っていきました。置換のくだりは、冒頭に紹介したリンク先の記事をご覧ください。
置換部分のソースコードはこんだけ。BINARY形式で読み込むと普通にsubで置換できる。知らなかった。。。shellでperlでワンライナーしていたのはなんだったのか。
# バイナリの文字列置換 def binary_str_replace(path, org, new) binary = File.read(path).force_encoding('BINARY') binary.sub!(org, new) File.binwrite path, binary end # バイナリの数字置換 def binary_num_replace(path, org, new) binary = File.read(path).force_encoding('BINARY') binary.sub!([org].pack("H*"), [new].pack("H*")) File.binwrite path, binary end
まとめ
僕がこの1年でつくったツールの一部を紹介してみました。 気分が乗ったら深掘りや別のツールの紹介をしたいと思います。
明日は非エンジニアも含め多くの従業員が使いこなしているSlack絵文字を量産する技術について書きたいと思います! お楽しみに!
株式会社フォトシンスでは、急成長するIoT製品「Akerun」を進化させるエンジニアを募集しております!