KeyInfo
Overview
The KeyInfo
class contains detailed information about a key's state, including timing data, force/pressure, and activity status. It provides methods to query key behavior and detect various input patterns.
The Python KeyInfo class is implemented in Applications/Python/PikaPython/MatrixOS_KeyInfo.py with type hints in Applications/Python/PikaPython/_MatrixOS_KeyInfo.pyi.
Constructor
KeyInfo(*val)
def __init__(self, *val) -> None
Creates a KeyInfo instance with variable arguments.
Parameters:
*val
: Variable arguments for initialization
Methods
State
def State(self) -> int
Gets the current key state value.
Returns:
int
: The key state (corresponds to KeyState enum values)
Force
def Force(self) -> float
Gets the force/pressure applied to the key.
Returns:
float
: Force value (0.0 to 1.0)
Value
def Value(self, index: int = 0) -> float
Gets a specific value from the key information.
Parameters:
index
(int
, optional): Value index (default: 0)
Returns:
float
: Value at specified index
LastEventTime
def LastEventTime(self) -> int
Gets the timestamp of the last key event.
Returns:
int
: Timestamp in milliseconds of the last event
Hold
def Hold(self) -> bool
Checks if the key is being held down.
Returns:
bool
: True if key is being held, False otherwise
Active
def Active(self) -> bool
Checks if the key is currently active (pressed).
Returns:
bool
: True if key is active/pressed, False otherwise
HoldTime
def HoldTime(self) -> int
Gets the duration the key has been held down.
Returns:
int
: Hold duration in milliseconds
__bool__
def __bool__(self) -> bool
Allows KeyInfo to be used in boolean contexts.
Returns:
bool
: True if KeyInfo represents a valid key state
Usage Examples
Force-Based LED Response
def force_led_response():
"""Change LED colors based on key force"""
print("Press keys with different force levels...")
while True:
key_event = MatrixOS.KeyPad.Get(50)
if key_event:
key_info = key_event.KeyInfo()
xy = MatrixOS.KeyPad.ID2XY(key_event.ID())
if key_info.Active():
force = key_info.Force()
# Map force to color intensity
if force > 0.9:
color = Color(255, 255, 255) # White for maximum force
elif force > 0.7:
color = Color(255, 0, 0) # Red for high force
elif force > 0.5:
color = Color(255, 128, 0) # Orange for medium force
elif force > 0.3:
color = Color(255, 255, 0) # Yellow for light force
else:
color = Color(0, 255, 0) # Green for minimal force
MatrixOS.LED.SetColor(xy, color)
print(f"Force: {force:.2f} at ({xy.X()},{xy.Y()})")
else:
# Key released
MatrixOS.LED.SetColor(xy, Color(0, 0, 0))
MatrixOS.LED.Update()
force_led_response()
Hold Time Detection
def hold_time_detector():
"""Perform different actions based on hold time"""
active_keys = {}
def check_hold_actions(key_id, key_info):
"""Check and execute hold-based actions"""
if key_info.Hold():
hold_time = key_info.HoldTime()
xy = MatrixOS.KeyPad.ID2XY(key_id)
if hold_time > 3000:
# Very long hold - white
MatrixOS.LED.SetColor(xy, Color(255, 255, 255))
if key_id not in active_keys or active_keys[key_id] != "very_long":
print(f"Very long hold: {hold_time}ms")
active_keys[key_id] = "very_long"
elif hold_time > 2000:
# Long hold - magenta
MatrixOS.LED.SetColor(xy, Color(255, 0, 255))
if key_id not in active_keys or active_keys[key_id] != "long":
print(f"Long hold: {hold_time}ms")
active_keys[key_id] = "long"
elif hold_time > 1000:
# Medium hold - blue
MatrixOS.LED.SetColor(xy, Color(0, 0, 255))
if key_id not in active_keys or active_keys[key_id] != "medium":
print(f"Medium hold: {hold_time}ms")
active_keys[key_id] = "medium"
elif hold_time > 500:
# Short hold - cyan
MatrixOS.LED.SetColor(xy, Color(0, 255, 255))
if key_id not in active_keys or active_keys[key_id] != "short":
print(f"Short hold: {hold_time}ms")
active_keys[key_id] = "short"
print("Hold time detector - hold keys for different durations")
while True:
key_event = MatrixOS.KeyPad.Get(50)
if key_event:
key_id = key_event.ID()
key_info = key_event.KeyInfo()
xy = MatrixOS.KeyPad.ID2XY(key_id)
if key_info.Active():
check_hold_actions(key_id, key_info)
else:
# Key released
if key_id in active_keys:
del active_keys[key_id]
MatrixOS.LED.SetColor(xy, Color(0, 0, 0))
MatrixOS.LED.Update()
hold_time_detector()
Key State Analysis
def analyze_key_states():
"""Detailed analysis of key state information"""
state_history = {}
def log_key_details(key_id, key_info):
"""Log detailed key information"""
current_time = MatrixOS.SYS.Millis()
info = {
"time": current_time,
"state": key_info.State(),
"active": key_info.Active(),
"hold": key_info.Hold(),
"force": key_info.Force(),
"value": key_info.Value(0),
"last_event": key_info.LastEventTime(),
"hold_time": key_info.HoldTime() if key_info.Hold() else 0
}
# Store in history
if key_id not in state_history:
state_history[key_id] = []
state_history[key_id].append(info)
# Keep only recent history
if len(state_history[key_id]) > 10:
state_history[key_id] = state_history[key_id][-10:]
# Print current state
xy = MatrixOS.KeyPad.ID2XY(key_id)
print(f"Key {key_id} at ({xy.X()},{xy.Y()}):")
print(f" State: {info['state']}")
print(f" Active: {info['active']}")
print(f" Force: {info['force']:.3f}")
print(f" Value[0]: {info['value']:.3f}")
if info['hold']:
print(f" Hold time: {info['hold_time']}ms")
print(f" Last event: {current_time - info['last_event']}ms ago")
print("---")
print("Key state analyzer - detailed key information")
while True:
key_event = MatrixOS.KeyPad.Get(50)
if key_event:
key_id = key_event.ID()
key_info = key_event.KeyInfo()
if key_info: # Check if valid KeyInfo
log_key_details(key_id, key_info)
# Visual feedback based on state
xy = MatrixOS.KeyPad.ID2XY(key_id)
if key_info.Active():
# Color based on force
force = key_info.Force()
red = int(255 * force)
green = int(255 * (1 - force))
MatrixOS.LED.SetColor(xy, Color(red, green, 0))
else:
MatrixOS.LED.SetColor(xy, Color(0, 0, 0))
MatrixOS.LED.Update()
analyze_key_states()
Multi-Value Key Monitoring
def multi_value_monitor():
"""Monitor multiple values from key events"""
print("Multi-value key monitor")
while True:
key_event = MatrixOS.KeyPad.Get(50)
if key_event:
key_info = key_event.KeyInfo()
key_id = key_event.ID()
xy = MatrixOS.KeyPad.ID2XY(key_id)
if key_info.Active():
# Read multiple values
value0 = key_info.Value(0)
value1 = key_info.Value(1)
force = key_info.Force()
print(f"Key {key_id} at ({xy.X()},{xy.Y()}):")
print(f" Force: {force:.3f}")
print(f" Value[0]: {value0:.3f}")
print(f" Value[1]: {value1:.3f}")
# Use force for LED brightness
brightness_factor = max(0.1, force) # Minimum 10% brightness
color = Color(int(255 * brightness_factor), 0, 0)
MatrixOS.LED.SetColor(xy, color)
else:
MatrixOS.LED.SetColor(xy, Color(0, 0, 0))
MatrixOS.LED.Update()
multi_value_monitor()
Performance Timing Analysis
def timing_analysis():
"""Analyze key timing performance"""
timing_data = {}
while True:
key_event = MatrixOS.KeyPad.Get(50)
if key_event:
key_id = key_event.ID()
key_info = key_event.KeyInfo()
current_time = MatrixOS.SYS.Millis()
if key_id not in timing_data:
timing_data[key_id] = {
"press_count": 0,
"total_hold_time": 0,
"max_hold_time": 0,
"last_press_time": 0,
"intervals": []
}
data = timing_data[key_id]
if key_info.Active():
if data["last_press_time"] > 0:
interval = current_time - data["last_press_time"]
data["intervals"].append(interval)
# Keep only recent intervals
if len(data["intervals"]) > 20:
data["intervals"] = data["intervals"][-20:]
data["last_press_time"] = current_time
if key_info.Hold():
hold_time = key_info.HoldTime()
data["max_hold_time"] = max(data["max_hold_time"], hold_time)
else:
# Key released
data["press_count"] += 1
if key_info.Hold():
hold_time = key_info.HoldTime()
data["total_hold_time"] += hold_time
# Print stats every 10 presses
if data["press_count"] % 10 == 0:
xy = MatrixOS.KeyPad.ID2XY(key_id)
avg_hold = data["total_hold_time"] / data["press_count"]
print(f"Key ({xy.X()},{xy.Y()}) Statistics:")
print(f" Presses: {data['press_count']}")
print(f" Avg hold time: {avg_hold:.1f}ms")
print(f" Max hold time: {data['max_hold_time']}ms")
if data["intervals"]:
avg_interval = sum(data["intervals"]) / len(data["intervals"])
print(f" Avg press interval: {avg_interval:.1f}ms")
print("---")
timing_analysis()
Common Patterns
State Checking
# Check if key information is valid
key_info = key_event.KeyInfo()
if key_info: # Uses __bool__ method
# Process key info
pass
Force-Based Actions
def force_based_action(key_info):
"""Perform different actions based on key force"""
if key_info.Active():
force = key_info.Force()
if force > 0.8:
return "strong_press"
elif force > 0.5:
return "medium_press"
else:
return "light_press"
return "not_pressed"
Hold Duration Classification
def classify_hold(key_info):
"""Classify hold duration"""
if key_info.Hold():
hold_time = key_info.HoldTime()
if hold_time > 2000:
return "long_hold"
elif hold_time > 500:
return "short_hold"
else:
return "brief_hold"
return "no_hold"
Value Array Access
def read_multiple_values(key_info):
"""Read multiple values from key info"""
values = []
for i in range(3): # Read first 3 values
values.append(key_info.Value(i))
return values
Comments