Module Python-Screen-Stack-Manager.devices.emulator.device
Expand source code
#!/usr/bin/env python
import sys
import os
import socket
import threading
from time import sleep
# Load Pillow
from PIL import Image, ImageDraw, ImageFont, ImageOps
import numpy as np
import cv2
delay_emulateEInk_Sluggishness = 0.001
screen_width=600
screen_height=800
view_width=screen_width
view_height=screen_height
h_offset = screen_height - view_height
w_offset = screen_width - view_width
emulator_windows_scale = 0.8 # Scale the emulator window
isEmulator= True
isRGB = True
colorType = "L"
is_nightmode=False
cv2.namedWindow("PSSM_Emulator")
isRunning = True
last_printed_PIL = Image.new('RGB', (screen_width,screen_height), color=(255,255,255))
# ####################### - TOOLS - ##########################################
def setFrontlightLevel(level):
print("setFrontlightLevel - Not supported on the emulator")
def readBatteryPercentage():
print(" readBatteryPercentage - Not supported on the emulator")
return 100
def readBatteryState():
print("readBatteryState - Not supported on the emulator")
return "Discharging"
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# isWifiOn = True
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except:
print("Error gettin IP")
finally:
s.close()
return IP
def wifiDown():
print("wifiDown - Not supported on the emulator")
def wifiUp():
print("wifiUp - Not supported on the emulator")
def wait(time_seconds):
#Reminder : When using 'wait' in the emulator, you can skip the wait by pressing any keyboard key
cv2.waitKey(int(time_seconds*1000))
def startMainLoop():
global isRunning
# Somehow necessary for it not to be killed in the emulator
while isRunning:
wait(0) # We tell openCV to keep the window open until a key is pressed
# ##################### - PRINT STUFF - #####################################
def print_openCV(img):
# Convert to np array
opencvImage = np.array(img)
# Convert RGB to BGR
opencvImage = opencvImage[:, :, ::-1].copy()
# Rescale
rescale_dim = (int(screen_width*emulator_windows_scale), int(screen_height*emulator_windows_scale))
opencvImage_Re = cv2.resize(opencvImage, rescale_dim)
# Print
cv2.imshow('PSSM_Emulator',opencvImage_Re)
cv2.waitKey(1)
def print_pil(imgData,x,y,isInverted=False):
sleep(delay_emulateEInk_Sluggishness)
#TODO : honor is inverted
global last_printed_PIL
pil_image = imgData.convert("RGB")
last_printed_PIL.paste(pil_image,(x,y))
print_openCV(last_printed_PIL)
def set_waveform(mode):
return True
def do_screen_refresh(isInverted=False,isFlashing=True,isInvertionPermanent=True,area=None, useFastInvertion=False):
"""
Does the screen refresh.
Args:
isInverted (bool): ...
isFlashing (bool): ...
isInvertionPermanent (bool): ...
area (list): ...
"""
#TODO: Honor inversion
global last_printed_PIL
global is_nightmode
if isInverted:
is_nightmode = not is_nightmode
if area:
if is_nightmode or not isInvertionPermanent:
(x,y),(w,h) = area
last_printed_PIL_crop = last_printed_PIL.crop(box=(x,y,x+w,y+h))
last_printed_PIL_crop_invert = ImageOps.invert(last_printed_PIL_crop)
last_printed_PIL.paste(last_printed_PIL_crop_invert,box=(x,y))
print_openCV(last_printed_PIL)
else:
if is_nightmode or not isInvertionPermanent:
last_printed_PIL = ImageOps.invert(last_printed_PIL)
print_openCV(last_printed_PIL)
if not isInvertionPermanent and isInverted:
is_nightmode = not is_nightmode
def do_screen_clear():
pil_image = Image.new('RGB', (screen_width,screen_height), color=(255,255,255))
last_printed_PIL = pil_image
print_openCV(last_printed_PIL)
def closePrintHandler():
cv2.destroyWindow("PSSM_Emulator")
print("Closed")
################################# - Click - ####################################
eventCallbackFct = None
isInputThreadStarted = False
def eventBindings(callbackFct, isThread=False,grabInput=False):
"""
This function is started as another thread, and calls 'callbackFct(x,y)'
When a click or touch event is recorded
"""
print("[PSSM_OpenCV - Click handler] : Let's do this")
global eventCallbackFct
if grabInput:
print('Using an emulator - nothing to be grabbed')
eventCallbackFct = callbackFct
cv2.setMouseCallback("PSSM_Emulator", cv2Link)
def closeInteractionHandler():
global isRunning
isRunning = False
print("Closed interactionHandler")
def cv2Link(event, x, y, flags, param):
global eventCallbackFct
if event == cv2.EVENT_LBUTTONUP:
scaled_x = int(x/emulator_windows_scale)
scaled_y = int(y/emulator_windows_scale)
eventCallbackFct(scaled_x,scaled_y)
Functions
def closeInteractionHandler()
-
Expand source code
def closeInteractionHandler(): global isRunning isRunning = False print("Closed interactionHandler")
def closePrintHandler()
-
Expand source code
def closePrintHandler(): cv2.destroyWindow("PSSM_Emulator") print("Closed")
def cv2Link(event, x, y, flags, param)
-
Expand source code
def cv2Link(event, x, y, flags, param): global eventCallbackFct if event == cv2.EVENT_LBUTTONUP: scaled_x = int(x/emulator_windows_scale) scaled_y = int(y/emulator_windows_scale) eventCallbackFct(scaled_x,scaled_y)
def do_screen_clear()
-
Expand source code
def do_screen_clear(): pil_image = Image.new('RGB', (screen_width,screen_height), color=(255,255,255)) last_printed_PIL = pil_image print_openCV(last_printed_PIL)
def do_screen_refresh(isInverted=False, isFlashing=True, isInvertionPermanent=True, area=None, useFastInvertion=False)
-
Does the screen refresh.
Args
isInverted
:bool
- …
isFlashing
:bool
- …
isInvertionPermanent
:bool
- …
area
:list
- …
Expand source code
def do_screen_refresh(isInverted=False,isFlashing=True,isInvertionPermanent=True,area=None, useFastInvertion=False): """ Does the screen refresh. Args: isInverted (bool): ... isFlashing (bool): ... isInvertionPermanent (bool): ... area (list): ... """ #TODO: Honor inversion global last_printed_PIL global is_nightmode if isInverted: is_nightmode = not is_nightmode if area: if is_nightmode or not isInvertionPermanent: (x,y),(w,h) = area last_printed_PIL_crop = last_printed_PIL.crop(box=(x,y,x+w,y+h)) last_printed_PIL_crop_invert = ImageOps.invert(last_printed_PIL_crop) last_printed_PIL.paste(last_printed_PIL_crop_invert,box=(x,y)) print_openCV(last_printed_PIL) else: if is_nightmode or not isInvertionPermanent: last_printed_PIL = ImageOps.invert(last_printed_PIL) print_openCV(last_printed_PIL) if not isInvertionPermanent and isInverted: is_nightmode = not is_nightmode
def eventBindings(callbackFct, isThread=False, grabInput=False)
-
This function is started as another thread, and calls 'callbackFct(x,y)' When a click or touch event is recorded
Expand source code
def eventBindings(callbackFct, isThread=False,grabInput=False): """ This function is started as another thread, and calls 'callbackFct(x,y)' When a click or touch event is recorded """ print("[PSSM_OpenCV - Click handler] : Let's do this") global eventCallbackFct if grabInput: print('Using an emulator - nothing to be grabbed') eventCallbackFct = callbackFct cv2.setMouseCallback("PSSM_Emulator", cv2Link)
def get_ip()
-
Expand source code
def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # isWifiOn = True # doesn't even have to be reachable s.connect(('10.255.255.255', 1)) IP = s.getsockname()[0] except: print("Error gettin IP") finally: s.close() return IP
def print_openCV(img)
-
Expand source code
def print_openCV(img): # Convert to np array opencvImage = np.array(img) # Convert RGB to BGR opencvImage = opencvImage[:, :, ::-1].copy() # Rescale rescale_dim = (int(screen_width*emulator_windows_scale), int(screen_height*emulator_windows_scale)) opencvImage_Re = cv2.resize(opencvImage, rescale_dim) # Print cv2.imshow('PSSM_Emulator',opencvImage_Re) cv2.waitKey(1)
def print_pil(imgData, x, y, isInverted=False)
-
Expand source code
def print_pil(imgData,x,y,isInverted=False): sleep(delay_emulateEInk_Sluggishness) #TODO : honor is inverted global last_printed_PIL pil_image = imgData.convert("RGB") last_printed_PIL.paste(pil_image,(x,y)) print_openCV(last_printed_PIL)
def readBatteryPercentage()
-
Expand source code
def readBatteryPercentage(): print(" readBatteryPercentage - Not supported on the emulator") return 100
def readBatteryState()
-
Expand source code
def readBatteryState(): print("readBatteryState - Not supported on the emulator") return "Discharging"
def setFrontlightLevel(level)
-
Expand source code
def setFrontlightLevel(level): print("setFrontlightLevel - Not supported on the emulator")
def set_waveform(mode)
-
Expand source code
def set_waveform(mode): return True
def startMainLoop()
-
Expand source code
def startMainLoop(): global isRunning # Somehow necessary for it not to be killed in the emulator while isRunning: wait(0) # We tell openCV to keep the window open until a key is pressed
def wait(time_seconds)
-
Expand source code
def wait(time_seconds): #Reminder : When using 'wait' in the emulator, you can skip the wait by pressing any keyboard key cv2.waitKey(int(time_seconds*1000))
def wifiDown()
-
Expand source code
def wifiDown(): print("wifiDown - Not supported on the emulator")
def wifiUp()
-
Expand source code
def wifiUp(): print("wifiUp - Not supported on the emulator")