ミツバチの行動パターンを画像にした時の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):この追記時点で、このコードは認証エラーとなって動かない。ワークアラウンド。