編集履歴一覧に戻る
eucalyのアイコン画像

eucaly が 2022年01月23日17時24分36秒 に編集

コメント無し

本文の変更

こんにちは、ゆうかりです。 今回は、以下の記事で中途半端に使ってみたけど放置していたWi-SUN関連機材を使って。 消費電力計を作ってみた、というお話です。 Bルート契約周りとかは、以下記事をご確認くださいな。 obnizでスマートメーターにちょっかいを出してみる https://elchika.com/article/142b9500-8c1c-4b7d-8d38-b515c752925b/ ## 消費電力の可視化 まあ、プロダクトベースだとタブレットだの太陽電池コントローラ上に表示する系の「HEMS」機器や。 ![キャプションを入力できます](https://camo.elchika.com/c0300a69a14062138c72aa88f59703720a55d53e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f32316363616131352d653961612d343237392d613866632d356237313066353966353237/) https://sumai.panasonic.jp/aiseg/hems/index.html m5stack系オプションに、m5stickCな画面に表示するステキさんとかがあります。 ![キャプションを入力できます](https://camo.elchika.com/e9b0b2a56091f7ae28d80c834e556a827d668f51/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f31323039363831302d653231342d346163612d386366322d313766383864356564666535/) https://booth.pm/ja/items/1650727 ・・・まあこのヘン使うのが、気軽でいいですよ、と。 このお話は、そのへんぶっちぎって適当にWi-SUNモジュールをobniz案件だ!っつーて買った挙句に放置してしまって勿体ないので使いましょう、という、かなりこう意識が低いお話です。 買って放置してたWi-SUNモジュール、ROHMのBP35C0という、まあ比較的使い辛いやーつ。 ![キャプションを入力できます](https://camo.elchika.com/ebf6fffab108101712b5be2415f4bb9efdabaa22/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f65663037393033382d303430622d343135352d613330622d393163623134356635393661/) ## ラズパイでとりあえず制御できるか ラズパイと、秋月のFT232基板使って、適当に組みました。 通信はUSB変換してUSB経由にする方向で。 ![キャプションを入力できます](https://camo.elchika.com/94156c6194fbece5bd087db531e80c9a0a6a78e5/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f61643535373238332d656564612d346262382d386361642d303737623833633230323033/) 注意点としては、FT232はIOをスイッチで3.3Vにすることが出来ますが、3.3V電源は搭載していない為、別途用意する必要があること、くらいです。 適当に組んでる時は、ラズパイから3.3Vを貰ってましたとさ。 で、動作確認。 スクリプトは以下URLなどを参照に。 https://qiita.com/rukihena/items/82266ed3a43e4b652adb https://github.com/katsumin/python-echonet-lite なんだけど、、、最近のRaspberry Pi OSはpythonが3系しか搭載しておらず。 まあ結構大胆にスクリプト書き替えが必要でしたとさ、メンディー・・・。 ![キャプションを入力できます](https://camo.elchika.com/101512a01fe3dc7a4f56cbd611ca01af32a50296/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f38646335623337322d666639392d343038322d623463652d393137363562646237633265/) ## 基板作製 ま、動作確認はうまくいったので。 サクッと基板を作りましょう。 ![キャプションを入力できます](https://camo.elchika.com/f2705462b3eb2f9db201ed502766241787466699/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f33363935393931342d363332612d346163332d386566322d363165656538383465656665/) 秋月のUSBシリアル変換、東芝の3.3V LDO、そして秋月C基板です。 適当に配置検討して。 ![キャプションを入力できます](https://camo.elchika.com/5de95f245f362d4b27b94f26dc7f34cfaca723de/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f61396138643366642d306566322d346663652d396265332d396564343737393034616363/) 配線!。 ![キャプションを入力できます](https://camo.elchika.com/ea0a8bf8a15b3a27127b762cefbca2d9652e6c73/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f34633066353762322d316231652d346338312d626434352d336237303162666630643062/) ま、配線は以下を参考に。 ![キャプションを入力できます](https://camo.elchika.com/1bda450ec002249bd37be0ad68dfe4ce62a68d94/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f30303634383863662d343563622d343137382d383933652d646133313038393836353737/) こんなかんじで。 RESET端子、制御必要かと思いきや、単純にVCCに吊っちゃっていいみたいです。 |CN No|端子名|接続| |---|---|---| |CN1 1|GND|GND| |CN1 2|ADC1|未接続| |CN1 3|ADC2|未接続| |CN1 4|VCC|3.3V| |CN1 5|VCC|3.3V|

-

|CN1 6|GPIOA7|GND|

+

|CN1 6|GPIOA7|未接続|

|CN1 7|MODE2|GND| |CN1 8|MODE0|GND| |CN1 9|GND|GND| |CN2 1|GND|GND| |CN2 2|RTS|未接続| |CN2 3|CTS|未接続| |CN2 4|RXD|FT232 TX| |CN2 5|TXD|FT232 RX| |CN2 6|SCL|未接続| |CN2 7|RESET|3.3V| |CN2 8|SDA|未接続| |CN2 9|GND|GND| ## 組み立て ま、適当なマトリクスLED板と、接続基板を用意して。 ![キャプションを入力できます](https://camo.elchika.com/bb294bab300fbbf5eab6461b55fd3a6e5a241aab/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f36353435636330642d636262612d343231612d623135372d633263613961356130633031/) できました。 ![キャプションを入力できます](https://camo.elchika.com/e84b05164ab724f41eecd22023521f8da991da92/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f31633566343935612d666630622d343736382d613537372d373730666264333437306130/) ## スクリプト 以下2つを作製。 いずれも、systemdでの自動起動対応、自動リブート用にリセット処理を入れている感じです。 まず、消費電力をメーターから読み取って、「/ramdisk/watt.data」に書き出すスクリプト。 ```python:getwatt.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import serial import time import os # Bルート認証ID rbid = 'BルートのID' # Bルート認証パスワード rbpwd = 'Bルートのパスワード' # シリアルポートデバイス名 serialPortDev = '/dev/ttyUSB0' # リザルトファイル outputfilename = '/ramdisk/watt.data' def debugwrite(data): # print (data) pass def sendcommand(serialobject,data): data = data + '\r\n' serialobject.write(data.encode()) readdata = serialobject.readline() readdata = serialobject.readline() debugwrite (readdata.decode()) def sendcommandraw(serialobject,data): data = data + '\r\n' serialobject.write(data.encode()) def sendcommandbinary(serialobject,data): serialobject.write(data) # serialobject.flush() def receivecommandraw(serialobject): readdata = serialobject.readline() return (readdata) # main loop while True: # シリアルポート初期化 if not (os.path.exists(serialPortDev)): time.sleep(10) continue debugwrite('[init]') ser = serial.Serial(serialPortDev, 115200) # とりあえずバージョンを取得してみる(やらなくてもおk) debugwrite('[version]') sendcommand(ser,'SKVER') # Bルート認証パスワード設定 debugwrite('[password]') sendcommand(ser,'SKSETPWD C ' + rbpwd) # Bルート認証ID設定 debugwrite('[id]') sendcommand(ser,'SKSETRBID ' + rbid) scanDuration = 4; # スキャン時間。サンプルでは6なんだけど、4でも行けるので。(ダメなら増やして再試行) scanRes = {} # スキャン結果の入れ物 debugwrite('[scan]') # スキャンのリトライループ(何か見つかるまで) while not 'Channel' in scanRes: # アクティブスキャン(IE あり)を行う # 時間かかります。10秒ぐらい? sendcommandraw(ser,'SKSCAN 2 FFFFFFFF ' + str(scanDuration) + ' 0') # スキャン1回について、スキャン終了までのループ scanEnd = False while not scanEnd : line = receivecommandraw(ser) debugwrite (line) if line.startswith(b'EVENT 22') : # スキャン終わったよ(見つかったかどうかは関係なく) scanEnd = True elif line.startswith(b' ') : # スキャンして見つかったらスペース2個あけてデータがやってくる # 例 # Channel:39 # Channel Page:09 # Pan ID:FFFF # Addr:FFFFFFFFFFFFFFFF # LQI:A7 # PairID:FFFFFFFF linedecode =line.decode() cols = linedecode.strip().split(':') scanRes[cols[0]] = cols[1] scanDuration+=1 if 10 < scanDuration and not 'Channel' in scanRes: # 引数としては14まで指定できるが、7で失敗したらそれ以上は無駄っぽい continue if scanEnd == False: ser.close() time.sleep(10) continue # スキャン結果からChannelを設定。 debugwrite('[set channnel]') sendcommand(ser,'SKSREG S2 ' + scanRes['Channel']) # スキャン結果からPan IDを設定 debugwrite('[set panid]') sendcommand(ser,'SKSREG S3 ' + scanRes['Pan ID']) # MACアドレス(64bit)をIPV6リンクローカルアドレスに変換。 # (BP35A1の機能を使って変換しているけど、単に文字列変換すればいいのではという話も??) debugwrite('[set localaddress]') sendcommandraw(ser,'SKLL64 ' + scanRes['Addr']) readdata = receivecommandraw(ser) ipv6Addr = receivecommandraw(ser).decode().strip() # print(ipv6Addr) # PANA 接続シーケンスを開始します。 debugwrite('[join]') sendcommand(ser,'SKJOIN ' + ipv6Addr) # PANA 接続完了待ち(10行ぐらいなんか返してくる) debugwrite('[wait panaconnect]') bConnected = False bCount = 0 while not bConnected : line = receivecommandraw(ser) debugwrite(line) if line.startswith(b'EVENT 24') : continue elif line.startswith(b'EVENT 25') : # 接続完了! bConnected = True bCount = bCount + 1 if bCount > 30: continue if bConnected == False: ser.close() time.sleep(10) continue # これ以降、シリアル通信のタイムアウトを設定 ser.timeout = 2 # スマートメーターがインスタンスリスト通知を投げてくる # (ECHONET-Lite_Ver.1.12_02.pdf p.4-16) readdata = receivecommandraw(ser) # 無視 readdata = receivecommandraw(ser) # 無視 time.sleep(2) debugwrite('[start]') protime = time.time() while True: ntime = time.time() ptime = ntime - protime if ptime > 120: break # ECHONET Lite フレーム作成 #  参考資料 #  ・ECHONET-Lite_Ver.1.12_02.pdf (以下 EL) #  ・Appendix_H.pdf (以下 AppH) echonetLiteFrame = b'' echonetLiteFrame += b'\x10\x81' # EHD (参考:EL p.3-2) echonetLiteFrame += b'\x00\x01' # TID (参考:EL p.3-3) # ここから EDATA echonetLiteFrame += b'\x05\xFF\x01' # SEOJ (参考:EL p.3-3 AppH p.3-408~) echonetLiteFrame += b'\x02\x88\x01' # DEOJ (参考:EL p.3-3 AppH p.3-274~) echonetLiteFrame += b'\x62' # ESV(62:プロパティ値読み出し要求) (参考:EL p.3-5) echonetLiteFrame += b'\x01' # OPC(1個)(参考:EL p.3-7) echonetLiteFrame += b'\xE7' # EPC(参考:EL p.3-7 AppH p.3-275) echonetLiteFrame += b'\x00' # PDC(参考:EL p.3-9) # コマンド送信 command = 'SKSENDTO 1 {0} 0E1A 1 0 {1:04X} '.format(ipv6Addr, len(echonetLiteFrame)) command = command.encode() + echonetLiteFrame + b'\r\n' sendcommandbinary(ser,command) for loopi in range(10): line = receivecommandraw(ser) # 受信データはたまに違うデータが来たり、 # 取りこぼしたりして変なデータを拾うことがあるので # チェックを厳しめにしてます。 if line.startswith(b'ERXUDP') : cols = line.strip().split(b' ') res = cols[9] # UDP受信データ部分 seoj = res[4:7] ESV = res[10:11] if seoj == b'\x02\x88\x01' and ESV == b'\x72' : # スマートメーター(028801)から来た応答(72)なら EPC = res[12:13] if EPC == b'\xe7' : # 内容が瞬時電力計測値(E7)だったら hexPower = res[14:18] # 最後の4バイト(16進数で8文字)が瞬時電力計測値 intPower = int.from_bytes(hexPower, 'big') strPower = str(intPower) if len(strPower) > 0: f = open(outputfilename,'w') f.write (str(intPower)) f.close() protime = time.time() time.sleep(5) break ser.close() ``` rpi-rgb-led-matrixライブラリを使って、「/ramdisk/watt.data」の内容を表示するスクリプト。 ```python:ledoutput.py from PIL import Image, ImageDraw, ImageOps, ImageFont, ImageFilter, ImageChops, ImageColor from rgbmatrix import RGBMatrix, RGBMatrixOptions import time outputfilename = '/ramdisk/watt.data' class ledworker(object): def ledinit(self): self.options = RGBMatrixOptions() self.options.hardware_mapping = "regular" self.options.led_rgb_sequence = "RGB" self.options.rows = 32 self.options.chain_length = 2 self.options.parallel = 1 self.options.pwm_bits = 11 self.options.brightness = 70 self.options.pwm_lsb_nanoseconds = 130 self.options.gpio_slowdown = 3 self.matrix = RGBMatrix(options = self.options) self.fontdata = ImageFont.truetype('/data/Envy Code R Bold.ttf', 32) self.fontdatasmall = ImageFont.truetype('/data/Envy Code R Bold.ttf', 12) def ledoutput(self,data): image = Image.new('RGB', (64, 32), (0, 0, 0)) draw = ImageDraw.Draw(image) outputdata = float(data) / 1000 outputdata = '{:.04f}'.format(outputdata) draw.text((8,-5), '.', (192, 192, 192),font=self.fontdata) draw.text((52,20), 'kw', (192, 192, 192),font=self.fontdatasmall) draw.text((0,-5), outputdata[0], (255, 255, 255),font=self.fontdata) draw.text((17,-5), outputdata[2], (255, 255, 255),font=self.fontdata) draw.text((33,-5), outputdata[3], (255, 255, 255),font=self.fontdata) draw.text((49,-5), outputdata[4], (255, 255, 255),font=self.fontdata) self.matrix.SetImage(image) led = ledworker() led.ledinit() while True: try: f = open(outputfilename, 'r') data = f.read() f.close() led.ledoutput(data) time.sleep(1) except: pass ``` フォントは、「Envy Code」を使っています。 https://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released/ ## アンテナの選定 さて、今回使用しているWi-SUNモジュールには。 アンテナが付属しておりません。 で、Wi-SUNの物理層には、「LQI(Link Quality Indication)」という、リンク品質を確認する項目が定義されており、まあそれを使ってアンテナの簡易的な評価をすることができます。 手持ちのアンテナや、そのへんに売っているアンテナを使って、比較してみました。 比較ラインアップは、以下の通り。 ### 適当な2.4GHz用アンテナ NUC的なパソコンについてきたやーつ。 多分WiFiだのBTだの用。 ![キャプションを入力できます](https://camo.elchika.com/073e29a87f82f7ccb8a1e79aa30e128284827b68/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f64656539373430352d666535332d343736632d616164392d336437663038623233363563/) ### 適当なリグ用の標準アンテナ 八重洲のVX-8だそうです。 ![キャプションを入力できます](https://camo.elchika.com/515327320715c1beed1e8c2e9044bf8b3740f2ab/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f32643137656230392d353565362d346366652d393735612d633562623866373035343162/) ### 900MHz帯受信にも対応しているホイップアンテナ ダイヤモンドアンテナの、SRHF10、アキバの富士無線さんで購入。 ![キャプションを入力できます](https://camo.elchika.com/56303c1e81b8bac0fdcff25a18bd23b529a86fe9/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f39666133613531382d616263642d343637332d623261382d663833663464386562386532/) ### 秋月のラバーダックアンテナ 広帯域で、お安い!。 ![キャプションを入力できます](https://camo.elchika.com/a34cc3e3c08618379f2e0c58468e7e98cb4794c6/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f31373931636330622d663336372d343031302d616636642d623935363663643963386436/) ## アンテナは、秋月最強でした ほぼ同一条件で、アンテナだけ変更して。 ま、サクッと測ってみたら。 |アンテナ|LQI| |---|---| | 2.4GHzアンテナ | 28 | | VX-8アンテナ | 9C | | SRHF10 | 60 | | 秋月アンテナ | B1 | うむ、高くないし、秋月アンテナ使いましょう!。  *アンテナ感度とか確認してないので、よいこはまねしないでくださいね・・・。 ## というわけで、出来ました! おおきいことはいいことだ!。 ![キャプションを入力できます](https://camo.elchika.com/5cab77cb07ab50f33f2a823195a666da5375ed76/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38666637633237372d646465642d343333632d393736342d6162303436346433326631302f33616564666666662d326139312d346535342d393762392d326537366337323537623037/) いやあ、消費電力がバーンと出てるので、エアコンつけっぱなしとか一発で分かっていい感じです!。 ま、消費電力自体はファイルに書き出しているので、FirebaseだのZabbixだの連携も組もうと思えば組めますが。 とりあえず「その場でパッと分かって節電」的な用途は、満たせた感じ!。 分かりやすいって大事よね!。 ま、つーわけで。 なかなかに満足のいけるものができましたとさ!。 以上です。