UIFlow2 & M5Paper
-
Hi,
I'm trying to get my m5paper up and running with a basic app to toggle a device.
The code displays temperature, humidity, co2, IAQ Level all correctly, but the touch interaction with the device is not working - any tips? Also, am I correctly implementing the sleep?
Thanks so much in advance!
D
import os, sys, io import M5 from M5 import * import requests2 import time import json # Global data variable data = {} data['grow_lamp_state'] = "Unknown" # To store current state # Configuration ha_url = "xxx" # Change this to your HA instance ha_token = "xxx" screenTitle = 'Office Environment' # Title to display wakeup_interval = 300 # 5 minutes in seconds # Button positioning button_x = 270 # Center X position of button button_y = 480 # Y position for button (adjust as needed) button_width = 200 # Width of button button_height = 60 # Height of button # Define constants for e-ink (black and white) WHITE = 0xffffff BLACK = 0x000000 def fetchHomeAssistantData(entity_id): url = f"{ha_url}/api/states/{entity_id}" headers = { 'Authorization': f'Bearer {ha_token}', 'Content-Type': 'application/json' } try: response = requests2.get(url, headers=headers) if response.status_code == 200: return json.loads(response.text) else: print(f"Error: {response.status_code}") return None except Exception as e: print(f"Error fetching data: {e}") return None def toggleGrowLamp(): url = f"{ha_url}/api/services/light/toggle" headers = { 'Authorization': f'Bearer {ha_token}', 'Content-Type': 'application/json' } payload = { "entity_id": "light.grow_lamp" } try: response = requests2.post(url, headers=headers, data=json.dumps(payload)) if response.status_code == 200: print("Toggled grow lamp successfully") # Update our stored state (will be refreshed next time) data['grow_lamp_state'] = "on" if data['grow_lamp_state'] == "off" else "off" # Force a re-render render() return True else: print(f"Error toggling grow lamp: {response.status_code}") return False except Exception as e: print(f"Error toggling grow lamp: {e}") return False def aggregateData(): global data # Device data try: data['batteryPercentage'] = str(M5.Power.getBatteryLevel()) + '%' data['voltage'] = f"{M5.Power.getBatVoltage() / 1000:.2f}V" except: data['batteryPercentage'] = "N/A" data['voltage'] = "N/A" # Check WiFi try: data['isWifiConnected'] = True # Assume connected except: data['isWifiConnected'] = True data['currentTime'] = time.localtime() # Fetch Home Assistant data try: # Temperature from Aranet4 temp_data = fetchHomeAssistantData("sensor.aranet4_2836d_temperature") if temp_data: data['ha_temperature'] = temp_data.get("state", "Unknown") data['ha_temperature_unit'] = temp_data.get("attributes", {}).get("unit_of_measurement", "°C") else: data['ha_temperature'] = "Error" data['ha_temperature_unit'] = "" # Humidity from Aranet4 humidity_data = fetchHomeAssistantData("sensor.aranet4_2836d_humidity") if humidity_data: data['ha_humidity'] = humidity_data.get("state", "Unknown") data['ha_humidity_unit'] = humidity_data.get("attributes", {}).get("unit_of_measurement", "%") else: data['ha_humidity'] = "Error" data['ha_humidity_unit'] = "" # CO2 from Aranet4 co2_data = fetchHomeAssistantData("sensor.aranet4_2836d_carbon_dioxide") if co2_data: data['ha_co2'] = co2_data.get("state", "Unknown") data['ha_co2_unit'] = co2_data.get("attributes", {}).get("unit_of_measurement", "ppm") else: data['ha_co2'] = "Error" data['ha_co2_unit'] = "" # IAQ from office sensor iaq_data = fetchHomeAssistantData("sensor.office_iaq_level") if iaq_data: data['ha_iaq'] = iaq_data.get("state", "Unknown") else: data['ha_iaq'] = "Error" # Grow lamp state lamp_data = fetchHomeAssistantData("light.grow_lamp") if lamp_data: data['grow_lamp_state'] = lamp_data.get("state", "Unknown") else: data['grow_lamp_state'] = "Unknown" except Exception as e: print(f"Error in aggregateData: {e}") def addZero(x): if int(x) < 10: return '0' + str(x) return str(x) def isButtonPressed(x, y): return (x >= button_x - button_width//2 and x <= button_x + button_width//2 and y >= button_y - button_height//2 and y <= button_y + button_height//2) def render(): # Clear screen M5.Lcd.fillScreen(WHITE) M5.Lcd.setTextColor(BLACK, WHITE) # Header M5.Lcd.setTextSize(2) M5.Lcd.setCursor(12, 10) M5.Lcd.print(screenTitle) M5.Lcd.drawLine(0, 40, 540, 40, BLACK) # Current time in header t = data['currentTime'] time_str = f"{addZero(t[3])}:{addZero(t[4])}" date_str = f"{t[0]}-{addZero(t[1])}-{addZero(t[2])}" M5.Lcd.setCursor(300, 10) M5.Lcd.print(f"{date_str}") # Main content area margin = 20 y_pos = 80 # Temperature display M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print("Temperature:") # Add indicator based on value try: temp_value = float(data['ha_temperature']) indicator = "" if temp_value > 25: indicator = "!" # High elif temp_value < 18: indicator = "!" # Low else: indicator = "" # Good except ValueError: indicator = "?" M5.Lcd.setTextSize(3) M5.Lcd.setCursor(250, y_pos) M5.Lcd.print(f"{data['ha_temperature']}{data['ha_temperature_unit']} {indicator}") y_pos += 80 # Reset text size M5.Lcd.setTextSize(2) # Humidity display M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print("Humidity:") try: humidity_value = float(data['ha_humidity']) indicator = "" if humidity_value > 60: indicator = "!" # High elif humidity_value < 40: indicator = "!" # Low else: indicator = "" # Good except ValueError: indicator = "?" M5.Lcd.setTextSize(3) M5.Lcd.setCursor(250, y_pos) M5.Lcd.print(f"{data['ha_humidity']}{data['ha_humidity_unit']} {indicator}") y_pos += 80 # Reset text size M5.Lcd.setTextSize(2) # CO2 display M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print("CO2:") try: co2_value = float(data['ha_co2']) indicator = "" if co2_value > 1000: indicator = "!" # Warning else: indicator = "" # Good except ValueError: indicator = "?" M5.Lcd.setTextSize(3) M5.Lcd.setCursor(250, y_pos) M5.Lcd.print(f"{data['ha_co2']} {data['ha_co2_unit']} {indicator}") y_pos += 80 # Reset text size M5.Lcd.setTextSize(2) # IAQ display M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print("IAQ Level:") M5.Lcd.setTextSize(3) M5.Lcd.setCursor(250, y_pos) M5.Lcd.print(f"{data['ha_iaq']}") y_pos += 100 # Reset text size M5.Lcd.setTextSize(2) # Divider line M5.Lcd.drawLine(margin, y_pos, 540-margin, y_pos, BLACK) y_pos += 40 # Grow Lamp Control Button global button_y button_y = y_pos # Set the button Y position dynamically # Draw button button_color = BLACK if data['grow_lamp_state'] == "on" else WHITE text_color = WHITE if data['grow_lamp_state'] == "on" else BLACK M5.Lcd.fillRoundRect( button_x - button_width//2, button_y - button_height//2, button_width, button_height, 10, # Corner radius button_color ) # Draw button border M5.Lcd.drawRoundRect( button_x - button_width//2, button_y - button_height//2, button_width, button_height, 10, BLACK ) # Button text M5.Lcd.setTextSize(2) M5.Lcd.setTextColor(text_color, button_color) # Calculate centered text position text = "Grow Lamp: " + ("ON" if data['grow_lamp_state'] == "on" else "OFF") # Position for centered text text_width = len(text) * 12 # Approximate width based on font size text_x = button_x - text_width//2 text_y = button_y - 10 # Adjust for vertical centering M5.Lcd.setCursor(text_x, text_y) M5.Lcd.print(text) # Reset text color M5.Lcd.setTextColor(BLACK, WHITE) y_pos += 80 # Add space below button # Divider line after button M5.Lcd.drawLine(margin, y_pos, 540-margin, y_pos, BLACK) y_pos += 40 # Device information M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print("Device Info:") y_pos += 40 # Use smaller font for device info M5.Lcd.setTextSize(1) # Battery M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print(f"Battery: {data['batteryPercentage']}") y_pos += 30 # Voltage M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print(f"Voltage: {data['voltage']}") y_pos += 30 # WiFi status wifi_status = "Connected" if data['isWifiConnected'] else "Disconnected" M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print(f"WiFi: {wifi_status}") y_pos += 30 # Update interval M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print(f"Update Interval: {int(wakeup_interval/60)} min") y_pos += 30 # Last update time t = data['currentTime'] update_time = f"{addZero(t[3])}:{addZero(t[4])}:{addZero(t[5])}" M5.Lcd.setCursor(margin, y_pos) M5.Lcd.print(f"Last Updated: {update_time}") # For e-ink displays try: M5.update() except: pass # Main execution try: # Initialize M5.begin() # Show loading message M5.Lcd.fillScreen(WHITE) M5.Lcd.setTextColor(BLACK, WHITE) M5.Lcd.setTextSize(2) M5.Lcd.setCursor(200, 240) M5.Lcd.print("Loading...") # Try to update display try: M5.update() except: pass # Fetch data and render display aggregateData() render() # Keep awake longer to allow interaction awake_time = 30 # 30 seconds instead of 10 awake_start = time.time() last_touch_time = 0 # Wait for touch events or timeout while time.time() - awake_start < awake_time: # Check for touches using native GT911 method if hasattr(M5, 'TP'): # For newer firmware with direct touch access if hasattr(M5.TP, 'getStatus') and M5.TP.getStatus(): # Get touch point x = M5.TP.getX() y = M5.TP.getY() # Only process touch if it's a new touch (debounce) current_time = time.time() if current_time - last_touch_time > 0.5: if isButtonPressed(x, y): print(f"Button pressed at {x},{y}") toggleGrowLamp() # Reset timeout counter to give more time after interaction awake_start = time.time() last_touch_time = current_time # Alternative method for M5Paper with different touch API try: if hasattr(M5, 'TP') and hasattr(M5.TP, 'touched'): touches = M5.TP.touched() if touches > 0: # Process first touch point point = M5.TP.getPoint(0) x, y = point.x, point.y # Only process touch if it's a new touch (debounce) current_time = time.time() if current_time - last_touch_time > 0.5: if isButtonPressed(x, y): print(f"Button pressed at {x},{y}") toggleGrowLamp() # Reset timeout counter to give more time after interaction awake_start = time.time() last_touch_time = current_time except: pass # Update display if needed try: M5.update() except: pass time.sleep(0.1) # Try to sleep try: M5.Power.deepSleep(wakeup_interval * 1000) except: try: import machine machine.deepsleep(wakeup_interval * 1000) except: while True: time.sleep(3600) # Just sleep in a loop if deep sleep fails except Exception as e: # Display error M5.Lcd.fillScreen(WHITE) M5.Lcd.setTextColor(BLACK, WHITE) M5.Lcd.setTextSize(2) M5.Lcd.setCursor(20, 200) M5.Lcd.print(f"Error: {str(e)}") try: M5.update() except: pass time.sleep(60) -
Hello @daniel-edge456
in UIFlow2 v2.2.6 using touch blocks for M5Paper and then look into the Python tab I get the following code to get touch coordinates:
if (M5.Touch.getCount()) > 0: x = M5.Touch.getX() y = M5.Touch.getY()doing the same with power blocks I get:
Power.deepSleep(1000, True)to put M5Paper into deep sleep.
Thanks
Felix
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login