cryptic-clock/take_screenshots.py

141 lines
4.6 KiB
Python

# A simple script to automatically take app screenshots
# Hopefully some day it'll grow into an actual testing framework
from uuid import UUID
from datetime import datetime, timezone
from time import sleep
import os
import png
import json
from pebble_tool.util.logs import PebbleLogPrinter
from pebble_tool.sdk.emulator import ManagedEmulatorTransport
from pebble_tool.commands.emucontrol import send_data_to_qemu
from libpebble2.communication import PebbleConnection
from libpebble2.communication.transports.qemu.protocol import QemuButton, QemuTimeFormat
from libpebble2.services.install import AppInstaller
from libpebble2.services.appmessage import AppMessageService, Uint32
from libpebble2.services.screenshot import Screenshot
from libpebble2.protocol.system import TimeMessage, SetUTC
package_json = None
with open('package.json', 'r') as file:
package_json = json.load(file)
app_uuid = UUID(package_json['pebble']['uuid'])
appname = package_json['name']
target_platforms = package_json['pebble']['targetPlatforms']
msg_keys = {
key: 10000 + i
for i, key in enumerate(package_json['pebble']['messageKeys'])
}
def emulator(platform):
print(f'Launching `{platform}` emulator')
pebble = PebbleConnection(ManagedEmulatorTransport(platform))
pebble.connect()
pebble.run_async()
print(f'Installing `{appname}.pbw`')
AppInstaller(pebble, f'./build/{appname}.pbw').install()
sleep(1)
return pebble
def for_all_platforms(fn, logs=True):
for platform in target_platforms:
pebble = emulator(platform)
if logs:
logger = PebbleLogPrinter(pebble)
fn(pebble)
logger.stop()
else:
fn(pebble)
def is_color(pebble):
return pebble.watch_platform in ['basalt', 'chalk', 'emery']
def send_app_message(pebble, msg):
ams = AppMessageService(pebble)
tid = ams.send_message(app_uuid, msg)
# unfortunately the following doesn't work
# wait_for_event assumes only one value is returned
# but ack returns 2 :(
# tid2, uuid = ams.wait_for_event('ack')
# assert uuid == app_uuid
# assert tid2 == tid
def set_time(pebble, hour, minute, year=2013, month=1, day=23, tzinfo=timezone.utc):
dt = int(datetime(year, month, day, hour, minute, tzinfo=tzinfo).timestamp())
pebble.send_packet(TimeMessage(message=SetUTC(unix_time=dt, utc_offset=0, tz_name="UTC")))
def press_buttons(pebble, buttons, duration=0.1):
send_data_to_qemu(pebble.transport, QemuButton(state=buttons))
sleep(duration)
send_data_to_qemu(pebble.transport, QemuButton(state=0))
sleep(0.1)
def press_back(pebble, duration=0.1):
press_buttons(pebble, QemuButton.Button.Back, duration)
def press_up(pebble, duration=0.1):
press_buttons(pebble, QemuButton.Button.Up, duration)
def press_select(pebble, duration=0.1):
press_buttons(pebble, QemuButton.Button.Select, duration)
def press_down(pebble, duration=0.1):
press_buttons(pebble, QemuButton.Button.Down, duration)
def set_24_hour_mode(pebble, is_24_hour=True):
send_data_to_qemu(pebble.transport, QemuTimeFormat(is_24_hour=is_24_hour))
def screenshot(pebble, name):
filename = f'{pebble.watch_platform}/{name}.png'
path = './screenshots/' + filename
print(f'Taking screenshot `{filename}`')
os.makedirs(os.path.dirname(path), exist_ok=True)
image = Screenshot(pebble).grab_image()
png.from_array(image, 'RGB').save(path)
# ============================================================
# Code above this line is not specific to the watchface and
# should probably be eventually split off into its own library
# ============================================================
def set_colors(pebble, background, digits, frame):
def wrap_color(color):
if isinstance(color, int):
color = hex(color)
color = color.removeprefix('0x').removeprefix('#')
if len(color) == 3:
r, g, b = color
color = r + r + g + g + b + b
return Uint32(int(color, 16))
send_app_message(pebble, {
msg_keys["BACKGROUND_COLOR"]: wrap_color(background),
msg_keys["DIGIT_COLOR"]: wrap_color(digits),
msg_keys["FRAME_COLOR"]: wrap_color(frame),
})
def run(pebble):
set_24_hour_mode(pebble, True)
set_time(pebble, 12, 34)
set_colors(pebble, 'FFF', '000', '000')
sleep(1.25)
screenshot(pebble, '01_white-black-black')
set_24_hour_mode(pebble, False)
set_time(pebble, 16, 59)
set_colors(pebble, '000', 'FFF', 'AAA')
sleep(1.25)
screenshot(pebble, '02_black-white-gray')
if is_color(pebble):
set_24_hour_mode(pebble, True)
set_time(pebble, 4, 20)
set_colors(pebble, 'FF5', '00F', '00A')
sleep(1.25)
screenshot(pebble, '03_yellow-blue-blue')
if __name__ == '__main__':
for_all_platforms(run)