Skip to main content
Version: Latest 🚧

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