Raspberry Piで先取りHomekit 新

先日ウチのホームサーバー(Raspberrypi4)にnode.jsを新しいバージョンすると反応しなくなる問題を解決すべく半日試行錯誤したあげくaptが動かなくなってしまい、仕方なくOSの再インストールする事となりました。
Raspbianはwheezy(7)からbullseye(11)までは順繰り使ってたけど、ホームサーバーにはbuster(10)を入れてたので最新のBookworm(12)にすると二世代違うので各所で色々と違いがあり手こずりました。以前投稿したRaspberry Piで先取りHomekit 追記のスクリプトも使えなくなったので修正していきます。

Pythonは未だにあまり触って無いので下のようにChatGPTに投げたら修正したコードを返してくれました。
下記のコードをpython3でも動作するように修正して下さい。
厳密には全ての問題点を修正はしてくれなかったので直ってはないのですが同様に変更点を全て反映すると直すと動作しました。
色々修正してくれたのですが動作しない問題は「主な変更点」としてChatGPTが書いてくれた「ir_serial.write の引数を bytes オブジェクトに変更しました。」が原因でした。
具体的には
ir_serial.write(“I,1\r\n”)」を「ir_serial.write(b”I,1\r\n”)」にしたり
ir_serial.write(“n,%d\r\n” % recNumber)」を「ir_serial.write((“n,%d\r\n” % recNumber).encode())
にする感じで修正漏れを埋めると動作しましたので再掲載させて頂きます。

$ vi ~/.homebridge/data/irm.py

# -*- coding: utf-8 -*-

import sys
import serial
import time
import json
import argparse
import os

here = os.path.abspath(os.path.dirname(__file__))
#ir_serial = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
#ir_serial = serial.Serial("/dev/tty.usbmodem01231", 9600, timeout = 1)

def captureIR(path):
  ir_serial = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
  print("Capturing IR...")
  ir_serial.write(b"c\r\n")
  time.sleep(3.0)
  msg = ir_serial.readline().decode()
  print(msg)
  if path and not 'Time Out' in msg:
    saveIR(path, ir_serial)
  ir_serial.close()

def playIR(path,delay):
  time.sleep(delay)
  ir_serial = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
  if path and os.path.isfile(path):
    print("Playing IR with %s ..." % path)
    f = open(path)
    data = json.load(f)
    f.close()
    recNumber = len(data['data'])
    rawX = data['data']

    ir_serial.write(("n,%d\r\n" % recNumber).encode())
    ir_serial.readline()

    postScale = data['postscale']
    ir_serial.write(("k,%d\r\n" % postScale).encode())
    #time.sleep(1.0)
    msg = ir_serial.readline()
    #print msg

    for n in range(recNumber):
        bank = n // 64
        pos = n % 64
        if (pos == 0):
          ir_serial.write(("b,%d\r\n" % bank).encode())

        ir_serial.write(("w,%d,%d\n\r" % (pos, rawX[n])).encode())

    ir_serial.write(b"p\r\n")
    msg = ir_serial.readline().decode()
    print(msg)
    #ir_serial.close()
  else:
    print("Playing IR...")
    ir_serial.write(b"p\r\n")
    time.sleep(1.0)
    msg = ir_serial.readline().decode()
    print(msg)
  ir_serial.close()

def saveIR(path):
  ir_serial = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
  print ("Saving IR data to %s ..." % path)
  rawX = []
  ir_serial.write(b"I,1\r\n")
  time.sleep(1.0)
  recNumberStr = ir_serial.readline()
  recNumber = int(recNumberStr, 16).decode()

  ir_serial.write(b"I,6\r\n")
  time.sleep(1.0)
  postScaleStr = ir_serial.readline().decode()
  postScale = int(postScaleStr, 10)

  #for n in range(640):
  for n in range(recNumber):
      bank = n // 64
      pos = n % 64
      if (pos == 0):
          ir_serial.write(("b,%d\r\n" % bank).encode())

      ir_serial.write(("d,%d\n\r" % pos).encode())
      xStr = ir_serial.read(3).decode()
      xData = int(xStr, 16)
      rawX.append(xData)

  data = {'format':'raw', 'freq':38, 'data':rawX, 'postscale':postScale}

  f = open(path, 'w')
  json.dump(data, f)
  f.close()
  print("Done !")
  ir_serial.close()

if __name__ == "__main__":
  # parse options
  parser = argparse.ArgumentParser(description='irMagician CLI utility.')
  parser.add_argument('-c', '--capture', action="store_true", dest="cap", help="capture IR data", default=False)
  parser.add_argument('-p', '--play', action="store_true", dest="play", help="play IR data", default=False)
  parser.add_argument('-d', '--delay', dest="delay", help="delay for play", type=float, default=0)
  parser.add_argument('-s', '--save', action="store_true", dest="save", help="save IR data", default=False)
  parser.add_argument('-f', '--file', action="store", dest="file", help="IR data file (json)", default=False)

  args = parser.parse_args()

  if args.play:
    playIR(args.file,args.delay)

  if args.save and args.file:
    saveIR(args.file)

  if args.cap:
    captureIR(args.file)

  # release resources
  #ir_serial.close()

詳しい設置方法は下記をご覧下さい。

 

Tags: , ,

トラックバック

コメントを書く