Created
July 5, 2020 07:17
-
-
Save steev/330336c08d13a779f1ab5805174479ba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from numpy import * | |
import subprocess | |
import time | |
POSITIVE=True | |
NEGATIVE=False | |
HINGE_ALIGNED_WITH_GRAVITY_THRESHOLD = cos(radians(15)) | |
HINGE_AXIS = array((0,1,0), dtype=float) | |
ROT_HINGE_90 = array(( | |
( 0, 0, 1), | |
( 0, 1, 0), | |
( -1, 0, 0) | |
), dtype=float) | |
ROT_HINGE_180 = array(( | |
( -1, 0, 0), | |
( 0, 1, 0), | |
( 0, 0, -1) | |
), dtype=float) | |
class NotReliable(ValueError): | |
pass | |
def read_axis_sysfs(location, axis): | |
return int(open("/sys/bus/iio/devices/iio:device0/in_accel_%s_%s_raw" % (axis, location)).read()) / 1024.0 | |
def read_values(): | |
try: | |
# lines = subprocess.check_output("sudo ectool motionsense", shell=True).split(b"\n") | |
base = array([int(value)/1024.0 for value in lines[1].split(b":")[1].split(b"\t")]) | |
lid = array([int(value)/1024.0 for value in lines[2].split(b":")[1].split(b"\t")]) | |
except Exception: | |
base = array(( | |
read_axis_sysfs("base","x"), | |
read_axis_sysfs("base","y"), | |
read_axis_sysfs("base","z") | |
)) | |
lid = array(( | |
read_axis_sysfs("lid","x"), | |
read_axis_sysfs("lid","y"), | |
read_axis_sysfs("lid","z") | |
)) | |
return base, lid | |
def cosine_of_angle_diff(v1, v2): | |
return (v1.dot(v2)) / (linalg.norm(v1) * linalg.norm(v1)) | |
def rotate(v, matrix): | |
rotated = v.dot(matrix) | |
rotated /= linalg.norm(rotated) #normalize | |
return rotated | |
def lid_angle(base, lid): | |
lid_to_base = cosine_of_angle_diff(base, lid) | |
base_to_hinge = cosine_of_angle_diff(base, HINGE_AXIS) | |
if abs(base_to_hinge) > HINGE_ALIGNED_WITH_GRAVITY_THRESHOLD: | |
raise NotReliable("Hinge too close to vertical") | |
base_to_hinge **= 2 | |
denominator = 1 - base_to_hinge | |
if denominator < 0.01: | |
raise NotReliable("denominator too small") | |
ang_lid_to_base = arccos((lid_to_base - base_to_hinge) / denominator) | |
if isnan(ang_lid_to_base): | |
raise NotReliable("arccos is nan for some reason") | |
#since we have 2 solutions for this problem, we have to determine which side the lid is on | |
v = rotate(base, ROT_HINGE_90) | |
cos_lid_90 = cosine_of_angle_diff(v, lid) | |
v = rotate(v, ROT_HINGE_180) | |
cos_lid_270 = cosine_of_angle_diff(v, lid) | |
if cos_lid_270 > cos_lid_90: | |
ang_lid_to_base = -ang_lid_to_base; | |
if ang_lid_to_base < 0: | |
ang_lid_to_base += pi*2 | |
return ang_lid_to_base | |
xrandr_rotation = "" | |
old_xrandr_rotation = "" | |
ctm = { | |
"normal": " 1 0 0 0 1 0 0 0 1", | |
"left": " 0 -1 1 1 0 0 0 0 1", | |
"inverted": "-1 0 1 0 -1 1 0 0 1", | |
"right": " 0 1 0 -1 0 1 0 0 1", | |
} | |
while 1: | |
base, lid = read_values() | |
try: | |
angle_spot = "%6.02fdeg" % degrees(lid_angle(base, lid)) | |
except ValueError as e: | |
angle_spot = repr(e) | |
max_axis, max_value = max(enumerate(lid), key=lambda axis: abs(axis[1])) | |
max_axis = "xyz"[max_axis] | |
screen_direction_str = "%s%s" % (max_axis, "-+"[max_value>0]) | |
try: | |
if screen_direction_str.startswith("y") or float(angle_spot[:-3]) > 200.0: | |
subprocess.call("florence show", shell=True) # Show Florence | |
subprocess.call("xinput disable 8", shell=True) # Disable Touchpad | |
subprocess.call("xinput disable 6", shell=True) # Disable cros_ec kb | |
else: | |
subprocess.call("xinput enable 8", shell=True) # Enable Touchpad | |
subprocess.call("xinput enable 6", shell=True) # Enable cros_ec kb | |
subprocess.call("florence hide", shell=True) # Hide Florence | |
except ValueError: | |
# probably being opened, so don't die on arcos is nan. | |
pass | |
try: | |
xrandr_rotation = { | |
("x", NEGATIVE): "normal", | |
("y", NEGATIVE): "left", | |
("x", POSITIVE): "inverted", | |
("y", POSITIVE): "right", | |
#("z", NEGATIVE): , #up | |
#("z", POSITIVE): , #down | |
}[(max_axis,max_value > 0)] | |
if old_xrandr_rotation != xrandr_rotation: | |
subprocess.call("xrandr --display :0 --output eDP-0 --rotate %s" % xrandr_rotation, shell=True) | |
subprocess.call("xinput set-prop 'Elan Touchscreen' 'Coordinate Transformation Matrix' %s" % ctm[xrandr_rotation], shell = True) | |
old_xrandr_rotation = xrandr_rotation | |
except KeyError: | |
#screen probably pointing up or down | |
pass | |
print(screen_direction_str, angle_spot, base, lid) | |
time.sleep(0.20) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment