Tapoカメラの動体検知データを画像にする

ミツバチの行動パターンを画像にした時のPythonコード。pytapoの注意点については、別エントリーで書いているのでそっちも参照。どう書けば取得できるかだけを検証したものなので、そのうち気が向いたら書き直すw

from pytapo import Tapo
import datetime
import json
from PIL import Image, ImageDraw, ImageFont

def time_to_pix(w, t, st):
    return int(w * (datetime.datetime.fromtimestamp(t) - st).seconds / 3600)

def save_chart(events, st):
    width_per_hour = 100
    width_margin = 40
    bar_height = 87
    image_height = 171
    image_width = width_per_hour * 24 + width_margin * 2
    colors = {
        'white' : (255, 255, 255),
        'pale_grey' : (250, 250, 250),
        'neutral_grey' : (128, 128, 128),
        'dark_blue' : (79, 108, 174),
        'pale_blue' : (101, 132, 186),
        'orange' : (240, 154, 55),
        'green' : (122, 211, 155)
    }
    try:
        font = ImageFont.truetype('/System/Library/Fonts/Monaco.ttf', 24)
    except:
        exit('Could not find Monaco.ttf')

    # draw background
    img = Image.new('RGB', (image_width, image_height), colors['white'])
    dr = ImageDraw.Draw(img)
    dr.rectangle((0, image_height - bar_height, image_width, image_height), colors['pale_grey'])
    # draw scale
    for i in range(25):
        x = i * width_per_hour + width_margin
        dr.line((x, 0, x, 21), fill=colors['dark_blue'], width=3) # long bar for o'clock
        dr.text((x - 36, 32), "{:02d}:00".format(i), fill=colors['neutral_grey'], font=font) # 00:00, 01:00. 02:00...
        if i < 24:
            for j in range(4):
                x = i * width_per_hour + width_margin + width_per_hour / 4 * j
                dr.line((x, 6, x, 15), fill=colors['pale_blue'], width=3) # short bar for every 15 minutes

    # draw bars of events
    for e in events:
        x1 = time_to_pix(width_per_hour, e['start_time'], st)
        x2 = time_to_pix(width_per_hour, e['end_time'], st)
        if x2 < x1: # next day
            x2 = width_per_hour * 24
        if e['alarm_type'] == 2: # detect motion
            bar_color = colors['orange']
        elif e['alarm_type'] == 6: # detect human
            bar_color = colors['green']
        dr.rectangle((x1 + width_margin, image_height - bar_height, x2 + width_margin, image_height), bar_color)
    img.save(st.strftime('%Y%m%d.png'))

host = '192.168.50.6'
user = 'admin'
password = 'your_password'

tapo = Tapo(host, user, password)

begin = datetime.datetime(2023, 6, 17, hour=0, minute=0, second=0)
now = datetime.datetime.now()

delta_days = (now - begin).days

for i in range(delta_days):
    st = begin + datetime.timedelta(days=i)
    ed = st + datetime.timedelta(days=1)
    events = []
    tmp = tapo.getEvents(startTime=int(st.timestamp()), endTime=int(ed.timestamp()))
    while len(tmp) == 100: # possibly exists other events
        print(len(tmp))
        events.append(tmp)
        tmp = tapo.getEvents(startTime=int(tmp[99]['end_time']) + 1, endTime=int(ed.timestamp()))
    events.append(tmp)
    save_chart(events[0], st)

追記(2024.07.30):この追記時点で、このコードは認証エラーとなって動かない。ワークアラウンド

タイトルとURLをコピーしました