added my Recipes

This commit is contained in:
2024-07-11 14:16:35 +02:00
parent 38bc4f53ac
commit 09b621d929
7118 changed files with 525762 additions and 3 deletions

View File

@@ -0,0 +1,51 @@
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
SUMMARY = "Python script which launch several use-cases"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9"
SRC_URI = " \
file://demo_launcher.py \
file://start_up_demo_launcher.sh \
file://pictures \
file://application \
file://board \
"
PV = "2.1"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/
install -d ${D}${prefix}/local/demo/bin
install -d ${D}${prefix}/local/demo/pictures
install -d ${D}${prefix}/local/demo/media
install -d ${D}${prefix}/local/demo/application
install -d ${D}${prefix}/local/demo/board
install -m 0755 ${WORKDIR}/demo_launcher.py ${D}${prefix}/local/demo/
LIST=$(ls ${WORKDIR}/pictures/*)
if [ -n "$LIST" ]; then
install -m 0644 ${WORKDIR}/pictures/* ${D}${prefix}/local/demo/pictures/
fi
LIST=$(ls ${WORKDIR}/application/*)
if [ -n "$LIST" ]; then
cp -r ${WORKDIR}/application/* ${D}${prefix}/local/demo/application/
fi
LIST=$(ls ${WORKDIR}/board/*)
if [ -n "$LIST" ]; then
cp -r ${WORKDIR}/board/* ${D}${prefix}/local/demo/board/
fi
# start at startup
install -d ${D}${prefix}/local/weston-start-at-startup/
install -m 0755 ${WORKDIR}/start_up_demo_launcher.sh ${D}${prefix}/local/weston-start-at-startup/
}
FILES:${PN} += "${prefix}/local/demo/ ${prefix}/local/weston-start-at-startup/"
RDEPENDS:${PN} += "python3-pygobject gtk+3 python3-resource python3-threading"
#since zeus
RDEPENDS:${PN} += " python3-core "

View File

@@ -0,0 +1,3 @@
BOARD: STM32MP13
LOGO: pictures/ST20578_Label_OpenSTlinux_V.png
INFO: <span font='9' color='#FFFFFFFF'><b>STM32MP13x Board</b></span>|<span font='7' color='#FFFFFFFF'>Arm&#174; Cortex&#174;-A7</span>

View File

@@ -0,0 +1,4 @@
BOARD: STM32MP15
LOGO: pictures/ST20578_Label_OpenSTlinux_V.png
INFO: <span font='14' color='#FFFFFFFF'><b>STM32MP15x Board</b></span>|<span font='10' color='#FFFFFFFF'>Dual Arm&#174; Cortex&#174;-A7</span>|<span font='10' color='#FFFFFFFF'>+</span>|<span font='10' color='#FFFFFFFF'>Copro Arm&#174; Cortex&#174;-M4</span>

View File

@@ -0,0 +1,861 @@
#!/usr/bin/python3
# Copyright (c) 2019 STMicroelectronics. All rights reserved.
#
# This software component is licensed by ST under BSD 3-Clause license,
# the "License"; You may not use this file except in compliance with the
# License. You may obtain a copy of the License at:
# opensource.org/licenses/BSD-3-Clause
# to debug this script:
# python3 -m pdb ./demo_launcher.py
#
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
from gi.repository import Pango
import yaml
import subprocess
import random
import math
import os
import sys
import glob
import socket
import fcntl
import struct
import string
import random
from collections import deque
from time import sleep, time
import threading
import importlib
#
# For simulating UI on PC , please use
# the variable SIMULATE = 1
# If SIMULATE = 1 then
# the picture/icon must be present on pictures directory
#
SIMULATE = 0
if SIMULATE > 0:
#DEMO_PATH = os.environ['HOME']+"/Desktop/launcher"
DEMO_PATH = "./"
else:
DEMO_PATH = "/usr/local/demo"
# -------------------------------------------------------------------
# Managment of lock file to have only excution of this script as same time
lock = threading.Lock()
lock_handle = None
lock_file_path = '/tmp/demo_launcher.lock'
def file_is_locked(file_path):
global lock_handle
lock_handle= open(file_path, 'w')
try:
fcntl.lockf(lock_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
return False
except IOError:
return True
def file_lock_remove(file_path):
try:
os.remove(lock_file_path)
except Exception as exc:
print("Signal handler Exception: ", exc)
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def detroy_quit_application(widget):
file_lock_remove(lock_file_path)
Gtk.main_quit()
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# CONSTANT VALUES
#
SIMULATE_SCREEN_SIZE_WIDTH = 800
SIMULATE_SCREEN_SIZE_HEIGHT = 480
#SIMULATE_SCREEN_SIZE_WIDTH = 480
#SIMULATE_SCREEN_SIZE_HEIGHT = 272
# -------------------------------------------------------------------
# -------------------------------------------------------------------
ICON_SIZE_1080 = 260
ICON_SIZE_720 = 180
ICON_SIZE_480 = 128
ICON_SIZE_272 = 64
# return format:
# [ icon_size, font_size, logo_size, exit_size, column_spacing, row_spacing ]
SIZES_ID_ICON_SIZE = 0
SIZES_ID_FONT_SIZE = 1
SIZES_ID_LOGO_SIZE = 2
SIZES_ID_EXIT_SIZE = 3
SIZES_ID_COLUMN_SPACING = 4
SIZES_ID_ROW_SPACING = 5
def get_sizes_from_screen_size(width, height):
minsize = min(width, height)
icon_size = None
font_size = None
logo_size = None
exit_size = None
column_spacing = None
row_spacing = None
if minsize == 720:
icon_size = ICON_SIZE_720
font_size = 15
logo_size = 160
exit_size = 50
column_spacing = 20
row_spacing = 20
elif minsize == 480:
icon_size = ICON_SIZE_480
font_size = 15
logo_size = 160
exit_size = 50
column_spacing = 10
row_spacing = 10
elif minsize == 272:
icon_size = ICON_SIZE_272
font_size = 8
logo_size = 60
exit_size = 25
column_spacing = 5
row_spacing = 5
elif minsize == 600:
icon_size = ICON_SIZE_720
font_size = 15
logo_size = 160
exit_size = 50
column_spacing = 20
row_spacing = 20
elif minsize >= 1080:
icon_size = ICON_SIZE_1080
font_size = 32
logo_size = 260
exit_size = 50
column_spacing = 20
row_spacing = 20
return [icon_size, font_size, logo_size, exit_size, column_spacing, row_spacing]
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Back video view
class BackVideoWindow(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "Wifi", parent, 0)
self.previous_click_time=time()
self.maximize()
self.set_decorated(False)
self.set_name("backed_bg")
self.show_all()
# Info view
class InfoWindow(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "Wifi", parent, 0)
self.previous_click_time=time()
self.maximize()
self.set_decorated(False)
self.set_name("backed_bg")
try:
self.font_size = parent.font_size
except:
print("DEBUG take default font size")
self.font_size = 15
mainvbox = self.get_content_area()
page_info = Gtk.VBox()
page_info.set_border_width(10)
title = Gtk.Label()
title.set_markup("<span font='%d' color='#FFFFFFFF'><b>About the application</b></span>" % (self.font_size+5))
page_info.add(title)
label1 = Gtk.Label()
label1.set_markup("<span font='%d' color='#FFFFFFFF'>\n\nTo get control of video playback and camera preview,\nSimple tap: pause/resume\nDouble tap: exit from demos\n\nAI demo: draw character on touchscreen to launch action</span>" % self.font_size)
label1.set_justify(Gtk.Justification.LEFT)
page_info.add(label1)
mainvbox.pack_start(page_info, False, False, 3)
self.connect("button-release-event", self.on_page_press_event)
self.show_all()
def on_page_press_event(self, widget, event):
self.click_time = time()
print(self.click_time - self.previous_click_time)
# TODO : a fake click is observed, workaround hereafter
if (self.click_time - self.previous_click_time) < 0.01:
self.previous_click_time = self.click_time
elif (self.click_time - self.previous_click_time) < 0.3:
print ("double click")
self.destroy()
else:
print ("simple click")
self.previous_click_time = self.click_time
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def _load_image_eventBox(parent, filename, label_text1, label_text2, scale_w, scale_h, font_size):
# Create box for xpm and label
box = Gtk.VBox(homogeneous=False, spacing=0)
# Create an eventBox
eventBox = Gtk.EventBox()
# Now on to the image stuff
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=filename,
width=scale_w,
height=scale_h,
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
label = Gtk.Label()
label.set_markup("<span font='%d' color='#39A9DCFF'>%s\n</span>"
"<span font='%d' color='#002052FF'>%s</span>" %
(font_size, label_text1, font_size, label_text2))
label.set_justify(Gtk.Justification.CENTER)
label.set_line_wrap(True)
# Pack the pixmap and label into the box
box.pack_start(image, True, False, 0)
box.pack_start(label, True, False, 0)
# Add the image to the eventBox
eventBox.add(box)
return eventBox
def _load_image_Box(parent, mp1filename, infofilename, label_text, scale_w, scale_h):
box = Gtk.VBox(homogeneous=False, spacing=0)
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=mp1filename,
width=scale_w,
height=scale_h,
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
# Create a label for the button
label0 = Gtk.Label() #for padding
label1 = Gtk.Label()
label1.set_markup("%s\n" % label_text)
label1.set_justify(Gtk.Justification.CENTER)
label1.set_line_wrap(True)
eventBox = Gtk.EventBox()
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=infofilename,
width=scale_w,
height=(scale_h/4),
preserve_aspect_ratio=True)
info = Gtk.Image.new_from_pixbuf(pixbuf)
eventBox.add(info)
eventBox.connect("button_release_event", parent.info_event)
eventBox.connect("button_press_event", parent.highlight_eventBox)
label3 = Gtk.Label()
label3.set_markup("<span font='10' color='#FFFFFFFF'><b>Python GTK launcher</b></span>\n")
label3.set_justify(Gtk.Justification.CENTER)
label3.set_line_wrap(True)
# Pack the pixmap and label into the box
box.pack_start(label0, True, False, 0)
box.pack_start(image, True, False, 0)
box.pack_start(label1, True, False, 0)
box.pack_start(eventBox, True, False, 0)
box.pack_start(label3, True, False, 0)
return box
def _load_image_on_button(parent, filename, label_text, scale_w, scale_h):
# Create box for xpm and label
box = Gtk.HBox(homogeneous=False, spacing=0)
box.set_border_width(2)
# print("[DEBUG] image: %s " % filename)
# Now on to the image stuff
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=filename,
width=scale_w,
height=scale_h,
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
# Create a label for the button
label = Gtk.Label.new(label_text)
# Pack the pixmap and label into the box
box.pack_start(image, True, False, 3)
image.show()
label.show()
return box
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def read_board_compatibility_name():
if SIMULATE > 0:
return "all"
else:
try:
with open("/proc/device-tree/compatible") as fp:
string = fp.read()
return string.split(',')[-1].rstrip('\x00')
except:
return "all"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
BOARD_CONFIG_ID_BOARD = 0
BOARD_CONFIG_ID_LOGO = 1
BOARD_CONFIG_ID_INFO_TEXT = 2
def read_configuration_board_file(search_path):
board_list = []
yaml_configuration = None
board_compatibility_name = read_board_compatibility_name()
print("[DEBUG] compatiblity name ", read_board_compatibility_name())
configuration_found = None
for file in sorted(os.listdir(search_path)):
if board_compatibility_name.find(file) > -1:
configuration_found = file
#print("DEBUG: found board configuration file: ", file)
if configuration_found and os.path.isfile(os.path.join(search_path, configuration_found)):
print("[DEBUG] read configuration box for ", configuration_found)
with open(os.path.join(search_path, configuration_found)) as fp:
yaml_configuration = yaml.load(fp, Loader=yaml.FullLoader)
# board name
if yaml_configuration and yaml_configuration["BOARD"]:
board_list.append(yaml_configuration["BOARD"])
else:
board_list.append('STM32MP')
# logo to used
if yaml_configuration and yaml_configuration["LOGO"]:
board_list.append(yaml_configuration["LOGO"])
else:
board_list.append('pictures/ST20578_Label_OpenSTlinux_V.png')
# info text to display
if yaml_configuration and yaml_configuration["INFO"]:
info = '\n'.join(yaml_configuration["INFO"].split('|'))
board_list.append(info)
else:
board_list.append("<span font='14' color='#FFFFFFFF'><b>STM32MP BOARD</b></span>")
return board_list
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def import_module_by_name(module_name):
''' module example:0application.netdata.netdata
(corresponding to application/netdata/netdata.py file)
'''
try:
print("[DEBUG] module_name=>%s<" % module_name)
imported = importlib.import_module(module_name)
except Exception as e:
print("Module Load, error: ", e)
return None
return imported
class ApplicationButton():
def __init__(self, parent, yaml_file, icon_size, font_size):
self.event_box = None
self.yaml_configuration = None
self.icon_size = icon_size
self.font_size = font_size
self._parent = parent
self._compatible = True
with open(yaml_file) as fp:
self.yaml_configuration = yaml.load(fp, Loader=yaml.FullLoader)
#print(self.yaml_configuration)
#print("Name ", self.yaml_configuration["Application"]["Name"])
if self.yaml_configuration:
# check board if it's compatible
if (self._is_compatible(self.yaml_configuration["Application"]["Board"])):
self._compatible = True
self.event_box = _load_image_eventBox(self, "%s/%s" % (DEMO_PATH, self.yaml_configuration["Application"]["Icon"]),
self.yaml_configuration["Application"]["Name"],
self.yaml_configuration["Application"]["Description"],
-1, self.icon_size, self.font_size)
if (self.yaml_configuration["Application"]["Type"].rstrip() == "script"):
self.event_box.connect("button_release_event", self.script_handle)
self.event_box.connect("button_press_event", self._parent.highlight_eventBox)
elif (self.yaml_configuration["Application"]["Type"].rstrip() == "python"):
self.event_box.connect("button_release_event", self.python_start)
self.event_box.connect("button_press_event", self._parent.highlight_eventBox)
else:
self._compatible = False
print(" %s NOT compatible" % self.yaml_configuration["Application"]["Name"])
def is_exist(self, data):
try:
#print("[DEBUG][is_exist] ", data)
if (data):
for masterkey in data:
#print("[DEBUG][is_exist] key available: ", masterkey)
if masterkey == "Exist":
for key in data["Exist"]:
#print("[DEBUG][is_exist] key detected: %s" % key)
if key == "File" and len(data["Exist"]["File"].rstrip()):
if (os.path.exists(data["Exist"]["File"].rstrip())):
return True
else:
return False
elif (key == "Command" and len(data["Exist"]["Command"].rstrip())):
retcode = subprocess.call(data["Exist"]["Command"].rstrip(), shell=True);
if (int(retcode) == 0):
return True
else:
return False
return True
else:
return True
except:
print("is_exist exception return true")
return True
def exist_MSG_present(self, data):
try:
#print("[DEBUG][is_exist] ", data)
if (data):
for masterkey in data:
#print("[DEBUG][is_exist] key available: ", masterkey)
if masterkey == "Exist":
for key in data["Exist"]:
#print("[DEBUG][is_exist] key detected: %s" % key)
if key == "Msg_false" and len(data["Exist"]["Msg_false"].rstrip()):
return True
return False
except:
return False
def is_compatible(self):
return self._compatible
def _is_compatible(self, data):
board_compatibility_name = read_board_compatibility_name()
try:
if (data):
for key in data:
if key == "List" and len(data["List"].rstrip()):
#print("[DEBUG] List<", data["List"], "> %s" % board_compatibility_name, " ")
if data["List"].find('all') > -1:
return True
for b in data["List"].split():
#print("[DEBUG] test for List <", b, "> %s" % board_compatibility_name, " " , board_compatibility_name.find(b) )
if board_compatibility_name.find(b) > -1:
return True
return False
elif key == "NotList" and len(data["NotList"].rstrip()):
#print("[DEBUG] NotList<", data["NotList"], "> %s" % board_compatibility_name, " "))
for b in data["NotList"].split():
#print("[DEBUG] test for Not List <", b, "> %s" % board_compatibility_name, " " , board_compatibility_name.find(b) )
if board_compatibility_name.find(b) > -1:
return False
return True
else:
return True
except Exception as e:
print("is_compatible exception return true ", e)
return True
return True
def get_event_box(self):
return self.event_box
def python_start(self, widget, event):
print("Python module =>", self.yaml_configuration["Application"]["Python"]["Module"], "<<<")
if (self.is_exist(self.yaml_configuration["Application"]["Python"])):
if (self.yaml_configuration["Application"]["Python"]["Module"] and
len(self.yaml_configuration["Application"]["Python"]["Module"].rstrip()) > 0):
module_imported = import_module_by_name(self.yaml_configuration["Application"]["Python"]["Module"].rstrip())
if (module_imported):
print("[Python_event start]")
module_imported.create_subdialogwindow(self._parent)
print("[Python_event stop]\n")
widget.set_name("transparent_bg")
self._parent.button_exit.show()
elif (self.exist_MSG_present(self.yaml_configuration["Application"]["Python"])):
print("[WARNING] %s not detected\n" % self.yaml_configuration["Application"]["Python"]["Exist"]["Msg_false"])
self._parent.display_message("<span font='15' color='#FFFFFFFF'>%s\n</span>" % self.yaml_configuration["Application"]["Python"]["Exist"]["Msg_false"])
widget.set_name("transparent_bg")
self._parent.button_exit.show()
def script_start(self):
global lock
with lock:
print("Lock Acquired")
backscript_window = BackVideoWindow(self._parent)
backscript_window.show_all()
print("[DEBUG][ApplicationButton][script_handle]:")
print(" Name: ", self.yaml_configuration["Application"]["Name"])
print(" Start script: ", self.yaml_configuration["Application"]["Script"]["Start"])
cmd = [os.path.join(DEMO_PATH,self.yaml_configuration["Application"]["Script"]["Start"])]
subprocess.run(cmd, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
backscript_window.destroy()
print("Lock Released")
def script_handle(self, widget, event):
if (self.is_exist(self.yaml_configuration["Application"]["Script"])):
print("Acquiring lock")
self.script_start()
elif (self.exist_MSG_present(self.yaml_configuration["Application"]["Script"])):
print("[WARNING] %s not detected\n" % self.yaml_configuration["Application"]["Script"]["Exist"]["Msg_false"])
self._parent.display_message("<span font='15' color='#FFFFFFFF'>%s\n</span>" % self.yaml_configuration["Application"]["Script"]["Exist"]["Msg_false"])
print("[script_event stop]\n")
widget.set_name("transparent_bg")
self._parent.button_exit.show()
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def gtk_style():
css = b"""
.widget .grid .label {
background-color: rgba (100%, 100%, 100%, 1.0);
}
.textview {
color: gray;
}
#normal_bg {
background-color: rgba (100%, 100%, 100%, 1.0);
}
#transparent_bg {
background-color: rgba (0%, 0%, 0%, 0.0);
}
#highlight_bg {
background-color: rgba (0%, 0%, 0%, 0.1);
}
#logo_bg {
background-color: #03244b;
}
#backed_bg {
background-color: rgba (31%, 32%, 31%, 0.8);
}
"""
style_provider = Gtk.CssProvider()
style_provider.load_from_data(css)
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Demo Launcher")
self.set_decorated(False)
gtk_style()
if SIMULATE > 0:
self.screen_width = SIMULATE_SCREEN_SIZE_WIDTH
self.screen_height = SIMULATE_SCREEN_SIZE_HEIGHT
else:
#self.fullscreen()
self.maximize()
try:
display = Gdk.Display.get_default()
monitor = display.get_primary_monitor()
geometry = monitor.get_geometry()
scale_factor = monitor.get_scale_factor()
self.screen_width = scale_factor * geometry.width
self.screen_height = scale_factor * geometry.height
except:
self.screen_width = self.get_screen().get_width()
self.screen_height = self.get_screen().get_height()
self.board_name = "STM32MP board"
self.set_default_size(self.screen_width, self.screen_height)
print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
self.set_position(Gtk.WindowPosition.CENTER)
self.connect('destroy', detroy_quit_application)
self.previous_click_time=time()
self.application_path = os.path.join(DEMO_PATH,"./application/")
self.board_path = os.path.join(DEMO_PATH,"./board/")
self.board_configuration = read_configuration_board_file(self.board_path)
sizes = get_sizes_from_screen_size(self.screen_width, self.screen_height)
self.icon_size = sizes[SIZES_ID_ICON_SIZE]
self.font_size = sizes[SIZES_ID_FONT_SIZE]
self.logo_size = sizes[SIZES_ID_LOGO_SIZE]
self.exit_size = sizes[SIZES_ID_EXIT_SIZE]
self.column_spacing = sizes[SIZES_ID_COLUMN_SPACING]
self.row_spacing = sizes[SIZES_ID_ROW_SPACING]
# page for basic information
self.create_page_icon_autodetected()
def display_message(self, message):
dialog = Gtk.Dialog("Error", self, 0, (Gtk.STOCK_OK, Gtk.ResponseType.OK))
dialog.set_decorated(False)
width, height = self.get_size()
dialog.set_default_size(width, height)
dialog.set_name("backed_bg")
label0 = Gtk.Label() #for padding
label1 = Gtk.Label()
label1.set_markup(message)
label1.set_justify(Gtk.Justification.CENTER)
label1.set_line_wrap(True)
label2 = Gtk.Label() #for padding
# Create a centering alignment object
align = Gtk.Alignment()
align.set(0.5, 0, 0, 0)
dialog.vbox.pack_start(label0, True, False, 0)
dialog.vbox.pack_start(label1, True, True, 0)
dialog.vbox.pack_start(align, True, True, 0)
dialog.vbox.pack_start(label2, True, False, 0)
dialog.action_area.reparent(align)
dialog.show_all()
dialog.run()
print("INFO dialog closed")
dialog.destroy()
def info_event(self, widget, event):
print("[info_event start]");
info_window = InfoWindow(self)
info_window.show_all()
response = info_window.run()
info_window.destroy()
print("[info_event stop]\n");
widget.set_name("transparent_bg")
self.button_exit.show()
# Button event of main screen
def highlight_eventBox(self, widget, event):
''' highlight the eventBox widget '''
print("[highlight_eventBox start]")
widget.set_name("highlight_bg")
self.button_exit.hide()
print("[highlight_eventBox stop]\n")
def create_page_icon_autodetected(self):
self.yaml_application_list = None
self.application_list = []
self.application_eventbox_list = []
self.application_start_previous = 0
self.application_start_next = 0
self.application_end = 0
self.page_main = Gtk.HBox(homogeneous=False, spacing=0)
self.page_main.set_border_width(0)
# create a grid of icon
self.icon_grid = Gtk.Grid(column_homogeneous=True, row_homogeneous=True)
self.icon_grid.set_column_spacing(self.column_spacing)
self.icon_grid.set_row_spacing(self.row_spacing)
# STM32MP1 Logo and info area
info_box_text = self.board_configuration[BOARD_CONFIG_ID_INFO_TEXT]
info_box_logo = self.board_configuration[BOARD_CONFIG_ID_LOGO]
self.logo_info_area = _load_image_Box(self, "%s/%s" % (DEMO_PATH,info_box_logo), "%s/pictures/ST13340_Info_white.png" % DEMO_PATH, info_box_text, -1, self.logo_size)
self.logo_info_area.set_name("logo_bg")
self.icon_grid.attach(self.logo_info_area, 3, 0, 1, 2)
self.back_box = self.create_eventbox_back_next(1)
self.next_box = self.create_eventbox_back_next(0)
number_of_application = 0
for file in sorted(os.listdir(self.application_path)):
if os.path.isfile(os.path.join(self.application_path, file)) and file.endswith(".yaml"):
print("[DEBUG] create event box for ", file)
application_button = ApplicationButton(self, os.path.join(self.application_path, file), self.icon_size, self.font_size)
if application_button.is_compatible():
self.application_list.append(os.path.join(self.application_path, file))
self.application_eventbox_list.append(application_button.get_event_box())
number_of_application = number_of_application + 1
print("[DEBUG] there is %d application(s) detected " % number_of_application)
if number_of_application == 0:
self.set_default_size(self.screen_width, self.screen_height)
self.display_message("<span font='15' color='#FFFFFFFF'>There is no application detected\n</span>")
self.destroy()
self.application_end = len(self.application_list)
#print("[DEBUG] application list:\n", self.application_list)
self.create_page_icon_by_page(0)
self.page_main.add(self.icon_grid)
overlay = Gtk.Overlay()
overlay.add(self.page_main)
self.button_exit = Gtk.Button()
self.button_exit.connect("clicked", detroy_quit_application)
self.button_exit_image = _load_image_on_button(self, "%s/pictures/close_70x70_white.png" % DEMO_PATH, "Exit", -1, self.exit_size)
self.button_exit.set_halign(Gtk.Align.END)
self.button_exit.set_valign(Gtk.Align.START)
self.button_exit.add(self.button_exit_image)
self.button_exit.set_relief(Gtk.ReliefStyle.NONE)
overlay.add_overlay(self.button_exit)
self.add(overlay)
self.show_all()
def create_page_icon_by_page(self, app_start):
'''
--------------------------------------------------------------
| 0,0: app1 | 1,0: app2 | 2,0: app2 | 3,0: information |
--------------------------------------------------------------
| 0,1: app1 | 1,1: app2 | 2,1: app2 | 3,1: information |
--------------------------------------------------------------
'''
for ind in range(0,self.application_end):
if (self.application_eventbox_list[ind]):
self.icon_grid.remove(self.application_eventbox_list[ind])
self.icon_grid.remove(self.back_box)
self.icon_grid.remove(self.next_box)
#print("[ICON DEBUG] app_start ", app_start)
# calculate next and previous
if app_start > 0:
if (app_start % 5) == 0:
self.application_start_previous = app_start - 5
else:
self.application_start_previous = app_start - 4
if self.application_start_previous < 0:
self.application_start_previous = 0
self.application_start_next = app_start + 4
else:
self.application_start_previous = 0
self.application_start_next = 5
#print("[ICON DEBUG] previous ", self.application_start_previous)
#print("[ICON DEBUG] next ", self.application_start_next)
if app_start != 0:
''' add previous button '''
index = app_start
# 0, 0
self.icon_grid.attach(self.back_box, 0, 0, 1, 1)
# 1, 0
if self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 1, 0, 1, 1)
index = index + 1
else:
index = app_start
self.application_start_previous = app_start - 4
if self.application_start_previous < 0:
self.application_start_previous = 0
# 0, 0
if self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 0, 0, 1, 1)
index = index + 1
# 1, 0
if (index < self.application_end) and self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 1, 0, 1, 1)
else:
self.icon_grid.show_all()
return
index = index + 1
# 2, 0
if (index < self.application_end) and self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 2, 0, 1, 1)
else:
self.icon_grid.show_all()
return
index = index + 1
# 0, 1
if (index < self.application_end) and self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 0, 1, 1, 1)
else:
self.icon_grid.show_all()
return
index = index + 1
# 1, 1
if (index < self.application_end) and self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 1, 1, 1, 1)
else:
self.icon_grid.show_all()
return
index = index + 1
# 2, 1
if ((index+1) < self.application_end) and self.application_eventbox_list[index]:
''' add next button '''
self.icon_grid.attach(self.next_box, 2, 1, 1, 1)
else:
if (index < self.application_end) and self.application_eventbox_list[index]:
self.icon_grid.attach(self.application_eventbox_list[index], 2, 1, 1, 1)
self.icon_grid.show_all()
def create_eventbox_back_next(self,back):
if back > 0:
back_eventbox = _load_image_eventBox(self, "%s/pictures/ST10261_back_button_medium_grey.png" % DEMO_PATH,
"BACK", "menu", -1, self.icon_size, self.font_size)
back_eventbox.connect("button_release_event", self.on_back_menu_event)
back_eventbox.connect("button_press_event", self.highlight_eventBox)
return back_eventbox
else:
next_eventbox = _load_image_eventBox(self, "%s/pictures/ST10261_play_button_medium_grey.png" % DEMO_PATH,
"NEXT", "menu", -1, self.icon_size, self.font_size)
next_eventbox.connect("button_release_event", self.on_next_menu_event)
next_eventbox.connect("button_press_event", self.highlight_eventBox)
return next_eventbox
def on_back_menu_event(self, widget, event):
self.create_page_icon_by_page(self.application_start_previous)
widget.set_name("normal_bg")
widget.set_name("transparent_bg")
self.button_exit.show()
def on_next_menu_event(self, widget, event):
self.create_page_icon_by_page(self.application_start_next)
widget.set_name("normal_bg")
widget.set_name("transparent_bg")
self.button_exit.show()
# -------------------------------------------------------------------
# Signal handler
def demo_signal_handler(signum, frame):
file_lock_remove(lock_file_path)
sys.exit(0)
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
# add signal to catch CRTL+C
import signal
signal.signal(signal.SIGINT, demo_signal_handler)
if file_is_locked(lock_file_path):
print("[ERROR] another instance is running exiting now\n")
exit(0)
try:
win = MainUIWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
except Exception as exc:
print("Main Exception: ", exc)

View File

@@ -0,0 +1,177 @@
Summary:
=======
1. Purpose
2. Yaml description for each application
3. File tree
4. Example of application description
1. Purpose:
-----------
Propose a generic way to descibe an application and easily add it on the
demo_launcher.
To permit a better and dynamic management of application, each application are
described on a yaml file.
2. Yaml description for each application:
-----------------------------------------
Format:
Application:
Name: <name of application>
Description: <description of application>
Icon: <icon of application>
Type: <script|python>
Board:
<List|NotList>: <all|list of chip>
Script:
Exist:
<File|Command>: <file or command to verify>
Msg_false: <Message to display if <File|Command> are not true
Start: <script or application to launch application>
Python:
Exist:
<File|Command>: <file or command to verify>
Msg_false: <Message to display if <File|Command> are not true
Module: <Python module name to load>
Action:
button_release_event: <python_start|script_management>
button_press_event: highlight_eventBox
Explaination:
- Name: name of application displayed on demo_launcher
- Description: description of application displayed on demo_launcher
- Icon: icon of application displayed on demo_launcher
- Board: define which board the application are compatible
List: list of chip/soc the application are compatible
NotList: List of chip/soc the application are NOT compatible
- Type: Type of script to launch the application,
type available:
* "script": shell script or application (without parameters) to execute
* "python": python script to load for launching application
This two type have a specific declaration available: Script, Python
- Script: it'a s section for describe the script (shell or application) to
launch the application.
This section have several sub section:
Exist: verify some requirement before to launch start command
Start: command to start the application
Exist section:
File: <verify presence of specific file>
Command: <command to execute, if return are Ok then we can launch start command>
- Python: it'a s section for describe the python script to load for accessing
to application functionality. The python script must have the function
"create_subdialogwindow(<parent window>)"
This section have several sub section:
Exist: verify some requirement before to launch start command
Module: Python module name to load, it's corresponding to path and scirpt
name.
ex.:
path = application/netdata/netdata.py
module name = application.netdata.netdata
Tips: you need to add an empty file name "__init__.py" on each sub
directory to permit to launch the python module
Exist section:
File: <verify presence of specific file>
Command: <command to execute, if return are Ok then we can launch start command>
3. File Tree:
------------
application/
├── 000-netdata.yaml
├── 010-camera.yaml
├── 020-video.yaml
├── 030-3d_cube.yaml
├── 040-m4_ai.yaml
├── 060-bluetooth_audio_output.yaml
├── 3d_cube
│   ├── bin
│   │   └── launch_cube_3D.sh
│   └── pictures
│   └── ST153_cube_purple.png
├── bluetooth
│   ├── bluetooth_audio.py
│   ├── __init__.py
│   ├── pictures
│   │   └── ST11012_bluetooth_speaker_light_green.png
│   └── wrap_blctl.py
├── camera
│   ├── bin
│   │   └── launch_camera_preview.sh
│   ├── pictures
│   │   └── ST1077_webcam_dark_blue.png
│   └── shaders
│   └── edge_InvertLuma.fs
├── __init__.py
├── m4_ai
│   ├── bin
│   │   └── launch_AI.sh
│   └── pictures
│   └── ST7079_AI_neural_pink.png
├── netdata
│   ├── bin
│   │   └── build_qrcode.sh
│   ├── __init__.py
│   ├── netdata.py
│   └── pictures
│   └── netdata-icon-192x192.png
└── video
├── bin
│   └── launch_video.sh
└── pictures
└── Video_playback_logo.pn
4. Example of application:
-----------------------
Example 1:
Application:
Name: 3D Pict
Description: GPU with picture
Icon: application/3d_cube/pictures/ST153_cube_purple.png
Board:
NotList: stm32mp151
Type: script
Script:
Exist:
File: /dev/galcore
Msg_false: No GPU capabilities to run 3D GPU demo
Start: application/3d_cube/bin/launch_cube_3D.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox
Example 2:
Application:
Name: Camera
Description: shader
Icon: application/camera/pictures/ST1077_webcam_dark_blue.png
Board:
List: all
Type: script
Script:
Exist:
File: /dev/video0
Msg_false: Webcam is not connected,
/dev/video0 doesn't exist
Start: application/camera/bin/launch_camera_shader.sh
Action:
button_release_event: script_management
button_press_event: highlight_eventBox
Example 3:
Application:
Name: Bluetooth
Description: speaker
Icon: application/bluetooth/pictures/ST11012_bluetooth_speaker_light_green.png
Type: python
Board:
List: stm32mp157 stm32mp153
Python:
Exist:
Command: hciconfig hci0 up
Msg_false: Please connect a bluetooth controller on the board
Module: application.bluetooth.bluetooth_audio
Action:
button_release_event: python_start
button_press_event: highlight_eventBox

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,48 @@
#!/bin/sh
source /etc/profile.d/weston_profile.sh
source /etc/profile.d/pulse_profile.sh
# wait pulseaudio starting
while [ 1 ]; do
if [ $(pgrep pulseaudio | wc -l) -ge 1 ]; then
break;
else
sleep 1;
fi
done
# this magic line permit to create the link to pulseaudio
script -qc 'su -l weston -c "source /etc/profile.d/pulse_profile.sh;pactl info; pactl list sinks"'
while [ 1 ]; do
pactl info
if [ $? -eq 0 ]; then
break;
else
sleep 1;
fi
done
if [ -f /usr/bin/pulseaudio_hdmi_switch.sh ]; then
/usr/bin/pulseaudio_hdmi_switch.sh
else
pactl info; pactl list sinks
cards=`pactl list cards | egrep -i 'alsa.card_name' | sed 's/ //g'| sed 's/alsa.card_name=\"//g'| sed 's/\"//g'`
index=0
for i in $cards;
do
found=`echo $i | grep -n STM32MP | wc -l`
if [ $found -eq 1 ];
then
pactl set-card-profile $index output:analog-stereo
fi
index=$((index+1))
done
fi
# force pulseaudio sink and source to be on SUSPENDED state (cf: pactl list sinks)
pactl suspend-source 0
for sink in $(pactl list short sinks | awk '{ print $1 }'); do
pactl suspend-sink $sink
done
/usr/local/demo/demo_launcher.py

View File

@@ -0,0 +1,24 @@
SUMMARY = "qrenc which uses libqrencode to generate QR-code"
LICENSE = "LGPL-2.1-only"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/LGPL-2.1-only;md5=1a6d268fd218675ffea8be556788b780"
DEPENDS += "qrencode"
DEPENDS += "libpng"
inherit pkgconfig
SRC_URI = " file://qrenc.c \
file://Makefile \
"
S = "${WORKDIR}"
do_install() {
install -d ${D}${prefix}/bin/
install -m 0755 ${B}/qrencode ${D}${prefix}/bin/
}
FILES:${PN} += "${prefix}/bin/"
RDEPENDS:${PN} += "qrencode libpng"

View File

@@ -0,0 +1,9 @@
all: qrencode
CFLAGS += -Wall $(shell pkg-config --cflags libqrencode libpng)
LDFLAGS += $(shell pkg-config --libs libqrencode libpng)
qrencode: qrenc.c
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
clean: ; rm -rf *.o qrencode

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
SUMMARY = "Python script which monitor temperature from sensor on Nucleo extension board iks01a2a"
LICENSE = "Proprietary"
LIC_FILES_CHKSUM = "file://${OPENSTLINUX_BASE}/files/licenses/ST-Proprietary;md5=7cb1e55a9556c7dd1a3cae09db9cc85f"
SRC_URI = " \
file://sensors_temperature.py \
\
file://pictures \
file://README.txt\
"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install() {
install -d ${D}${prefix}/local/demo/pictures
install -m 0755 ${WORKDIR}/sensors_temperature.py ${D}${prefix}/local/demo/
install -m 0644 ${WORKDIR}/pictures/* ${D}${prefix}/local/demo/pictures
install -m 0644 ${WORKDIR}/README.txt ${D}${prefix}/local/demo/README_sensor_iks01a2.txt
}
FILES:${PN} += "${prefix}/local/demo/"
RDEPENDS:${PN} += "python3-core python3-pygobject python3-pycairo gtk+3 "

View File

@@ -0,0 +1,71 @@
How to deploy demonstration:
----------------------------
Materials:
* Nucleo extension board with mems, here IKS01A2
* connection between extension board and stm32mp15 board.
Pre-requisite:
--------------
1. Kernel:
You need to configure the kernel to support the Nucleo extension
board with the devitree configuration and the kernel configuration.
1.1 DeviceTree:
* Enable the sensor on I2C
For Discovery board (stm32mp157c-dk2), the sensors are linked on ic25.
Add the following line on your devicetree associateds to the board
&i2c5 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c5_pins_a>;
pinctrl-1 = <&i2c5_pins_sleep_a>;
i2c-scl-rising-time-ns = <124>;
i2c-scl-falling-time-ns = <3>;
/delete-property/dmas;
/delete-property/dma-names;
status = "okay";
hts221@5f {
compatible = "st,hts221";
reg = <0x5f>;
};
lsm6dsl@6b {
compatible = "st,lsm6dsl";
reg = <0x6b>;
};
};
NOTE: the i2c depend of the pin-muxing of the board and could be different of
i2c5.
1.2 Kernel configuration:
Add the following config on your kernel configuraturation
(best way are via a new fragment)
CONFIG_IIO_BUFFER=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_TRIGGERED_BUFFER=y
CONFIG_HTS221=y
CONFIG_IIO_ST_PRESS=y
CONFIG_IIO_ST_LSM6DSX=y
CONFIG_IIO_ST_LSM6DSX_I2C=y
2. Software
You need to have some framework available on the board for executing the
python script:
List of packages already present on st-example-image-weston:
weston
gtk+3
python3 and several python3 addons
Execution of script on board:
-----------------------------
Files:
/usr/local/demo/
/usr/local/demo/sensors_temperature.py
Put the files on board and launch the python script:
BOARD > /usr/local/demo/sensors_temperature.py
To quit the application, just click on ST logo.

View File

@@ -0,0 +1,7 @@
CONFIG_IIO_BUFFER=y
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_TRIGGERED_BUFFER=y
CONFIG_HTS221=y
CONFIG_IIO_ST_PRESS=y
CONFIG_IIO_ST_LSM6DSX=y
CONFIG_IIO_ST_LSM6DSX_I2C=y

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -0,0 +1,269 @@
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo
import random
import math
import os
from time import sleep, time
# time between each sensor mesearuement (1s)
TIME_UPATE = 2000
class Sensors():
def __init__(self):
''' '''
self.sensor_dictionnary = {}
def found_iio_device_with_name(self, data, name):
prefix = "/sys/bus/iio/devices/"
of_name = 'OF_NAME=' + name
try:
for filefolder in os.listdir(prefix):
with open(prefix + '/' + filefolder + '/uevent') as f:
for line in f:
if line.split('\n')[0] == of_name:
''' return directory which contains "data" '''
if os.path.exists(prefix + '/' + filefolder + '/' + data):
return (prefix + '/' + filefolder + '/')
except OSError:
pass
except Exception as exc:
pass
return None
def found_all_sensor_path(self):
self.sensor_dictionnary['temperature'] = self.found_iio_device_with_name("in_temp_raw", "hts221")
self.sensor_dictionnary['humidity'] = self.found_iio_device_with_name("in_humidityrelative_raw", "hts221")
self.sensor_dictionnary['accelerometer'] = self.found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
self.sensor_dictionnary['gyroscope'] = self.found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")
print("[DEBUG] temperature -> ", self.sensor_dictionnary['temperature'], "<")
print("[DEBUG] humidity -> ", self.sensor_dictionnary['humidity'], "<")
print("[DEBUG] accelerometer -> ", self.sensor_dictionnary['accelerometer'], "<")
print("[DEBUG] gyroscope -> ", self.sensor_dictionnary['gyroscope'], "<")
def temperature_read(self):
prefix_path = self.sensor_dictionnary['temperature']
try:
with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
raw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
raw = 0.0
try:
with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
scale = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
scale = 0.0
try:
with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
offset = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
offset = 0.0
return (offset + raw) * scale
def humidity_read(self):
prefix_path = self.sensor_dictionnary['humidity']
try:
with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
raw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
raw = 0.0
try:
with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
scale = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
scale = 0.0
try:
with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
offset = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
offset = 0.0
return (offset + raw) * scale
def accelerometer_read(self):
prefix_path = self.sensor_dictionnary['accelerometer']
try:
with open(prefix_path + "in_accel_" + 'scale', 'r') as f:
rscale = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'scale', exc)
rscale = 0.0
try:
with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
xraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
xraw = 0.0
accel_x = int(xraw * rscale * 256.0 / 9.81)
try:
with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
yraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
yraw = 0.0
accel_y = int(yraw * rscale * 256.0 / 9.81)
try:
with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
zraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
zraw = 0.0
accel_z = int(zraw * rscale * 256.0 / 9.81)
return [ accel_x, accel_y, accel_z]
def gyroscope_read(self):
prefix_path = self.sensor_dictionnary['gyroscope']
try:
with open(prefix_path + "in_anglvel_" + 'scale', 'r') as f:
rscale = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'scale', exc)
rscale = 0.0
try:
with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
xraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
xraw = 0.0
gyro_x = int(xraw * rscale * 256.0 / 9.81)
try:
with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
yraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
yraw = 0.0
gyro_y = int(yraw * rscale * 256.0 / 9.81)
try:
with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
zraw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
zraw = 0.0
gyro_z = int(zraw * rscale * 256.0 / 9.81)
return [ gyro_x, gyro_y, gyro_z]
# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Sensor usage")
#self.set_decorated(False)
self.maximize()
self.screen_width = self.get_screen().get_width()
self.screen_height = self.get_screen().get_height()
self.set_default_size(self.screen_width, self.screen_height)
print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
self.set_position(Gtk.WindowPosition.CENTER)
self.connect('destroy', Gtk.main_quit)
# search sensor interface
self.sensors = Sensors()
self.sensors.found_all_sensor_path()
sensor_box = Gtk.VBox(homogeneous=False, spacing=0)
# temperature
temp_label = Gtk.Label()
temp_label.set_markup("<span font_desc='LiberationSans 25'>Temperature</span>")
self.temp_value_label = Gtk.Label()
self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- °C</span>")
temp_box = Gtk.HBox(homogeneous=False, spacing=0)
temp_box.add(temp_label)
temp_box.add(self.temp_value_label)
sensor_box.add(temp_box)
# humidity
humidity_label = Gtk.Label()
humidity_label.set_markup("<span font_desc='LiberationSans 25'>Humidity</span>")
self.humidity_value_label = Gtk.Label()
self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- %c</span>" % '%')
humidity_box = Gtk.HBox(homogeneous=False, spacing=0)
humidity_box.add(humidity_label)
humidity_box.add(self.humidity_value_label)
sensor_box.add(humidity_box)
# Accel
accel_label = Gtk.Label()
accel_label.set_markup("<span font_desc='LiberationSans 25'>Accelerometer</span>")
self.accel_value_label = Gtk.Label()
self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
accel_box = Gtk.HBox(homogeneous=False, spacing=0)
accel_box.add(accel_label)
accel_box.add(self.accel_value_label)
sensor_box.add(accel_box)
# Gyroscope
gyro_label = Gtk.Label()
gyro_label.set_markup("<span font_desc='LiberationSans 25'>Gyroscope</span>")
self.gyro_value_label = Gtk.Label()
self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
gyro_box = Gtk.HBox(homogeneous=False, spacing=0)
gyro_box.add(gyro_label)
gyro_box.add(self.gyro_value_label)
sensor_box.add(gyro_box)
self.add(sensor_box)
# Add a timer callback to update
# this takes 2 args: (how often to update in millisec, the method to run)
GLib.timeout_add(TIME_UPATE, self.update_ui)
def destroy(self, widget, data=None):
Gtk.main_quit()
def update_ui(self):
# temperature
temp = self.sensors.temperature_read()
self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % temp)
# humidity
hum = self.sensors.humidity_read()
self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (hum, '%'))
# accel
accel = self.sensors.accelerometer_read()
self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (accel[0], accel[1], accel[2]))
# gyro
gyro = self.sensors.gyroscope_read()
self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (gyro[0], gyro[1], gyro[2]))
# As this is a timeout function, return True so that it
# continues to get called
return True
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
# add signal to catch CRTL+C
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
win = MainUIWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

View File

@@ -0,0 +1,91 @@
#!/bin/sh
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
# for hts221: Temperature + Humidity
if grep -q hts221 $d/name ;
then
echo "============================="
echo "=== HTS221 ==="
echo "=== (temperature) ==="
echo "============================="
raw=`cat $d/in_temp_raw`
offset=`cat $d/in_temp_offset`
scale=`cat $d/in_temp_scale`
printf "Value read: raw %0f\n" $raw
printf "Value read: offset %0f\n" $offset
printf "Value read: scale %0f\n" $scale
temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`
echo "Temperature $temperature"
printf "Temperature %.02f\n" $temperature
echo "============================="
echo "=== HTS221 ==="
echo "=== (humidity) ==="
echo "============================="
raw=`cat $d/in_humidityrelative_raw`
offset=`cat $d/in_humidityrelative_offset`
scale=`cat $d/in_humidityrelative_scale`
printf "Value read: raw %0f\n" $raw
printf "Value read: offset %0f\n" $offset
printf "Value read: scale %0f\n" $scale
humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`
echo "Humidity $humidity"
printf "Humidity %.02f\n" $humidity
fi
# for lsm6dsl: accelerometer
if grep -q lsm6dsl_accel $d/name ;
then
echo "============================="
echo "=== LSM6DSL ==="
echo "=== (accelerometer) ==="
echo "============================="
rscale=`cat $d/in_accel_scale`
xraw=`cat $d/in_accel_x_raw`
yraw=`cat $d/in_accel_y_raw`
zraw=`cat $d/in_accel_z_raw`
printf "Value read: X (raw/scale) %d / %.06f \n" $xraw $rscale
printf "Value read: Y (raw/scale) %d / %.06f \n" $yraw $rscale
printf "Value read: Z (raw/scale) %d / %.06f \n" $zraw $rscale
factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$rscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$rscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$rscale*$factor" | bc`
printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
fi
# for lsm6dsl: gyroscope
if grep -q lsm6dsl_gyro $d/name ;
then
echo "============================="
echo "=== LSM6DSL ==="
echo "=== (gyroscope) ==="
echo "============================="
rscale=`cat $d/in_anglvel_scale`
xraw=`cat $d/in_anglvel_x_raw`
yraw=`cat $d/in_anglvel_y_raw`
zraw=`cat $d/in_anglvel_z_raw`
printf "Value read: X (raw/scale) %d / %.06f \n" $xraw $rscale
printf "Value read: Y (raw/scale) %d / %.06f \n" $yraw $rscale
printf "Value read: Z (raw/scale) %d / %.06f \n" $zraw $rscale
factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$rscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$rscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$rscale*$factor" | bc`
printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
fi
done

View File

@@ -0,0 +1,767 @@
#!/usr/bin/python3
# to debug this script:
# python3 -m pdb ./sensors_temperature.py
#
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo
import random
import math
import os
import socket
from collections import deque
from time import sleep, time
#
# For simulating the presence of sensor, please use
# the variable SIMULATE_SENSORS = 1
# If SIMULATE_SENSORS = 1 then
# the picture/icon must be present on pictures directory
#
SIMULATE_SENSORS = 0
ICON_PICTURES_PATH = "/usr/local/demo/pictures"
WITH_PRESSURE = 0
WITH_GYRO = 1
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# CONSTANT VALUES
#
SIMULATE_SCREEN_SIZE_WIDTH = 480
SIMULATE_SCREEN_SIZE_HEIGHT = 800
DEFAULT_SCREEN_WIDTH = 400
DEFAULT_SCREEN_HEIGHT = 600
# time between each sensor mesearuement (1s)
TIME_UPATE = 2000
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# SPLASH SCREEN class
# the splash screen display a logo and the different step of boot
#
class SplashScreen():
def __init__(self, picture_filename, timeout):
#DONT connect 'destroy' event here!
self.window = Gtk.Window()
self.window.set_title('Sensor IKS01A2')
self.window.set_position(Gtk.WindowPosition.CENTER)
self.window.set_decorated(False)
if SIMULATE_SENSORS > 0:
screen_width = SIMULATE_SCREEN_SIZE_WIDTH
screen_height = SIMULATE_SCREEN_SIZE_HEIGHT
else:
self.window.fullscreen()
#self.maximize()
screen_width = self.window.get_screen().get_width()
screen_height = self.window.get_screen().get_height()
self.window.set_default_size(screen_width, screen_height)
self.window.set_border_width(1)
# Add Vbox with image and label
main_vbox = Gtk.VBox(False, 1)
self.window.add(main_vbox)
# load picture
print("[DEBUG] Splash screen with picture: %s" % picture_filename)
if os.path.exists(picture_filename):
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=picture_filename,
width=400, # TODO: change size
height=600, # TODO: change size
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
main_vbox.pack_start(image, True, True, 0)
#self.lbl = Gtk.Label("Init: splash screen")
#self.lbl.set_alignment(0, 0.5)
#main_vbox.pack_start(self.lbl, True, True, 0)
self.window.set_auto_startup_notification(False)
self.window.show_all()
self.window.set_auto_startup_notification(True)
# Ensure the splash is completely drawn before moving on
GLib.timeout_add(1000, self.loop)
self.loops = 0
self.loops_timeout = timeout
self.loops_break = 0
def update_text(self, text):
self.lbl.set_text(text)
def loop_stop(self):
self.loops_break = 1
def loop(self):
global var
var = time ()
print ("[DEBUG] ", var)
self.loops += 1
if self.loops_break or self.loops == self.loops_timeout:
Gtk.main_quit()
self.window.destroy()
return False
return True
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def _load_image_on_button(parent, filename, label_text, scale_w, scale_h):
# Create box for xpm and label
box1 = Gtk.HBox(homogeneous=False, spacing=0)
box1.set_border_width(2)
# Now on to the image stuff
#image = Gtk.Image()
#image.set_from_file(filename)
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename=filename,
width=scale_w,
height=scale_h,
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
# Create a label for the button
label = Gtk.Label(label_text)
# Pack the pixmap and label into the box
box1.pack_start(image, True, False, 3)
#box1.pack_start(label, False, False, 3)
image.show()
label.show()
return box1
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def _load_image(parent, filename_without_prefix):
img = Gtk.Image()
img.set_from_file("%s/%s" % (ICON_PICTURES_PATH, filename_without_prefix))
return img
# scale_width and scale_height are sht siez disired after scale,
# It can be -1 for no scale on one value
def _load_image_constrained(parent, filename_without_prefix, scale_width, scale_height):
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename="%s/%s" % (ICON_PICTURES_PATH, filename_without_prefix),
width=scale_width,
height=scale_height,
preserve_aspect_ratio=True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
return image
# -------------------------------------------------------------------
# -------------------------------------------------------------------
class Sensors():
key_temperature = 'temp'
key_humidity = 'humidity'
key_pressure = 'pressure'
key_accelerometer = 'accel'
key_gyroscope = 'gyro'
key_magnetometer = 'magneto'
driver_name_temperature = 'driver_temp'
driver_name_humidity = 'driver_humidity'
driver_name_pressure = 'driver_pressure'
driver_name_accelerometer = 'driver_accel'
driver_name_gyroscope = 'driver_gyro'
driver_name_magnetometer = 'driver_magneto'
prefix_temp = "in_temp_"
prefix_humidity = "in_humidityrelative_"
prefix_pressure = "in_pressure_"
prefix_accel = "in_accel_"
prefix_gyro = "in_anglvel_"
prefix_magneto = "in_magn_" # TODO: verify
def __init__(self):
''' '''
self.sensor_dictionnary = {}
def init_pressure_sampling_frequency(self):
if not self.sensor_dictionnary[self.key_pressure] is None and len(self.sensor_dictionnary[self.key_pressure]) > 5:
with open(self.sensor_dictionnary[self.key_pressure] + 'sampling_frequency', 'w') as f:
f.write('10')
def found_iio_device(self, data):
prefix = "/sys/bus/iio/devices/"
try:
for filefolder in os.listdir(prefix):
if os.path.exists(prefix + '/' + filefolder + '/' + data):
''' return directory which contains "data" '''
return (prefix + '/' + filefolder + '/')
except OSError:
pass
return None
def found_iio_device_with_name(self, data, name):
prefix = "/sys/bus/iio/devices/"
of_name = 'OF_NAME=' + name
try:
for filefolder in os.listdir(prefix):
with open(prefix + '/' + filefolder + '/uevent') as f:
for line in f:
if line.split('\n')[0] == of_name:
''' return directory which contains "data" '''
if os.path.exists(prefix + '/' + filefolder + '/' + data):
return (prefix + '/' + filefolder + '/')
except OSError:
pass
except Exception as exc:
pass
return None
def driver_name_iio_device(self, key):
if SIMULATE_SENSORS > 0:
val_name = "-Simulated-"
else:
if self.sensor_dictionnary[key] == None:
val_name = "-Not present / Simulated-"
else:
try:
with open(self.sensor_dictionnary[key] + "name", 'r') as f:
val_name = f.read()
except Exception as exc:
val_name = "-Not present-"
return val_name
def found_all_sensor_path(self):
self.sensor_dictionnary[self.key_temperature] = self.found_iio_device_with_name("in_temp_raw", "hts221")
self.sensor_dictionnary[self.key_humidity] = self.found_iio_device("in_humidityrelative_raw")
self.sensor_dictionnary[self.key_pressure] = self.found_iio_device("in_pressure_raw")
self.sensor_dictionnary[self.key_accelerometer] = self.found_iio_device("in_accel_x_raw")
if WITH_GYRO:
self.sensor_dictionnary[self.key_gyroscope] = self.found_iio_device("in_anglvel_x_raw")
else:
self.sensor_dictionnary[self.key_gyroscope] = ""
self.sensor_dictionnary[self.key_magnetometer] = "" #TODO
self.sensor_dictionnary[self.driver_name_temperature] = self.driver_name_iio_device(self.key_temperature)
self.sensor_dictionnary[self.driver_name_humidity] = self.driver_name_iio_device(self.key_humidity)
self.sensor_dictionnary[self.driver_name_pressure] = self.driver_name_iio_device(self.key_pressure)
self.sensor_dictionnary[self.driver_name_accelerometer] = self.driver_name_iio_device(self.key_accelerometer)
self.sensor_dictionnary[self.driver_name_gyroscope] = self.driver_name_iio_device(self.key_gyroscope)
self.sensor_dictionnary[self.driver_name_magnetometer] = self.driver_name_iio_device(self.key_magnetometer)
self.init_pressure_sampling_frequency()
print("[DEBUG] " , self.key_temperature, " -> ", self.sensor_dictionnary[self.key_temperature], "<")
print("[DEBUG] " , self.key_humidity, " -> ", self.sensor_dictionnary[self.key_humidity], "<")
print("[DEBUG] " , self.key_pressure, " -> ", self.sensor_dictionnary[self.key_pressure], "<")
print("[DEBUG] " , self.key_accelerometer, " -> ", self.sensor_dictionnary[self.key_accelerometer], "<")
print("[DEBUG] " , self.key_gyroscope, " -> ", self.sensor_dictionnary[self.key_gyroscope], "<")
print("[DEBUG] " , self.key_magnetometer, " -> ", self.sensor_dictionnary[self.key_magnetometer], "<")
def read_sensor_basic(self, key, prefix):
if SIMULATE_SENSORS > 0:
if self.key_temperature == key:
return random.uniform(0.0, 50.0)
elif self.key_humidity == key:
return random.uniform(0.0, 100.0)
else:
return random.uniform(800.0, 1200.0)
else:
if self.sensor_dictionnary[key] is None or len(self.sensor_dictionnary[key]) < 5:
return 0.0
try:
with open(self.sensor_dictionnary[key] + prefix + 'raw', 'r') as f:
raw = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'raw', exc)
raw = 0.0
try:
with open(self.sensor_dictionnary[key] + prefix + 'scale', 'r') as f:
scale = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'scale', exc)
scale = 0.0
if self.key_pressure != key:
try:
with open(self.sensor_dictionnary[key] + prefix + 'offset', 'r') as f:
offset = float(f.read())
except Exception as exc:
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'offset', exc)
offset = 0.0
else:
offset = 0.0
scale = scale * 10
temp = (offset + raw) * scale
#print("[DEBUG] [%s] %f" % (key, temp))
return temp
def read_sensor_move(self, key, prefix):
if SIMULATE_SENSORS > 0:
in_x = random.randint(-180, 180)
in_y = random.randint(-180, 180)
in_z = random.randint(-180, 180)
return [in_x, in_y, in_z]
else:
if self.sensor_dictionnary[key] is None or len(self.sensor_dictionnary[key]) < 5:
return [0, 0, 0]
try:
with open(self.sensor_dictionnary[key] + prefix + 'x_raw', 'r') as f:
scale = float(f.read())
with open(self.sensor_dictionnary[key] + prefix + 'x_scale', 'r') as f:
raw = float(f.read())
in_x = int(raw * scale * 256.0 / 9.81)
with open(self.sensor_dictionnary[key] + prefix + 'y_raw', 'r') as f:
scale = float(f.read())
with open(self.sensor_dictionnary[key] + prefix + 'y_scale', 'r') as f:
raw = float(f.read())
in_y = int(raw * scale * 256.0 / 9.81)
with open(self.sensor_dictionnary[key] + prefix + 'z_raw', 'r') as f:
scale = float(f.read())
with open(self.sensor_dictionnary[key] + prefix + 'z_scale', 'r') as f:
raw = float(f.read())
in_z = int(raw * scale * 256.0 / 9.81)
except Exception as exc:
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + '[x_ , y_ , z_ ]', exc)
return [0, 0, 0]
return [in_x, in_y, in_z]
def read_temperature(self):
return self.read_sensor_basic(self.key_temperature, self.prefix_temp)
def read_humidity(self):
return self.read_sensor_basic(self.key_humidity, self.prefix_humidity)
def read_pressure(self):
return self.read_sensor_basic(self.key_pressure, self.prefix_pressure)
def read_accelerometer(self):
return self.read_sensor_move(self.key_accelerometer, self.prefix_accel)
def read_gyroscope(self):
return self.read_sensor_move(self.key_gyroscope, self.prefix_gyro)
def read_magnetometer(self):
return self.read_sensor_move(self.key_magnetometer, self.prefix_magneto)
def get_driver_name_temperature(self):
return self.sensor_dictionnary[self.driver_name_temperature]
def get_driver_name_humidity(self):
return self.sensor_dictionnary[self.driver_name_humidity]
def get_driver_name_pressure(self):
return self.sensor_dictionnary[self.driver_name_pressure]
def get_driver_name_accelerometer(self):
return self.sensor_dictionnary[self.driver_name_accelerometer]
def get_driver_name_gyroscope(self):
return self.sensor_dictionnary[self.driver_name_gyroscope]
def get_driver_name_magnetometer(self):
return self.sensor_dictionnary[self.driver_name_magnetometer]
def calculate_imu(self, accel):
x = accel[0]
y = accel[1]
z = accel[2]
if x == 0 and y == 0 and z == 0:
return [0, 0, 0]
pitch = round(math.atan(x / math.sqrt(y * y + z * z)) * (180.0 / math.pi))
roll = round(math.atan(y / math.sqrt(x * x + z * z)) * (180.0 / math.pi))
yaw = round(math.atan(z / math.sqrt(x * x + z * z)) * (180.0 / math.pi))
return [pitch, roll, yaw]
def get_imu_orientation(self, pitch, roll):
if abs(pitch) > 35:
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
if pitch > 0:
return "left-up"
else:
return "right-up"
else:
if abs(roll) > 35:
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
if roll > 0:
return "bottom-up"
else:
return "normal"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Sensor usage")
self.set_decorated(False)
if SIMULATE_SENSORS > 0:
self.screen_width = SIMULATE_SCREEN_SIZE_WIDTH
self.screen_height = SIMULATE_SCREEN_SIZE_HEIGHT
else:
self.fullscreen()
#self.maximize()
self.screen_width = self.get_screen().get_width()
self.screen_height = self.get_screen().get_height()
self.set_default_size(self.screen_width, self.screen_height)
print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
self.set_position(Gtk.WindowPosition.CENTER)
self.connect('destroy', Gtk.main_quit)
# search sensor interface
self.sensors = Sensors()
self.sensors.found_all_sensor_path()
# variable for sensor
self._axis_ranges = {} # {axis_num: [min_seen, max_seen]}
self._axis_values = {} # {axis_num: deque([val0, ..., valN])}
# create nodebook
self.notebook = Gtk.Notebook()
self.add(self.notebook)
# page for basic information
# current temperature / Humidity / Pressure
self.create_notebook_page_basic_sensor()
# page for accel / gyro / magentic
self.create_notebook_page_basic_accel()
# page for IMU
self.create_notebook_page_imu()
# page sensor information
self.create_notebook_page_sensor_information()
# page for quitting application
self.create_notebook_page_exit()
# Add a timer callback to update
# this takes 2 args: (how often to update in millisec, the method to run)
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
self.timer_enable = True
self.show_all()
def _set_basic_temperature(self, val):
self.temperature_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % val)
#self.temperature_basic_label.set_text("%.02f °C" % val)
def _set_basic_humidity(self, val):
self.humidity_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (val, '%'))
#self.humidity_basic_label.set_text("%.02f %c" % (val, '%'))
def _set_basic_pressure(self, val):
self.pressure_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f hP</span>" % val)
#self.pressure_basic_label.set_text("%.02f hP" % val)
def _set_basic_accelerometer(self, x, y, z):
self.liststore[self.accel_store][1] = '%d' % x
self.liststore[self.accel_store][2] = '%d' % y
self.liststore[self.accel_store][3] = '%d' % z
def _set_basic_gyroscope(self, x, y, z):
self.liststore[self.gyro_store][1] = '%d' % x
self.liststore[self.gyro_store][2] = '%d' % y
self.liststore[self.gyro_store][3] = '%d' % z
def _set_basic_magnetometer(self, x, y, z):
self.liststore[self.magneto_store][1] = '%d' % x
self.liststore[self.magneto_store][2] = '%d' % y
self.liststore[self.magneto_store][3] = '%d' % z
def _set_imu_roll(self, val):
self.imu_liststore[self.roll_store][1] = '%d' % val
def _set_imu_pitch(self, val):
self.imu_liststore[self.pitch_store][1] = '%d' % val
def _set_imu_yaw(self, val):
self.imu_liststore[self.yaw_store][1] = '%d' % val
def _update_orientation(self, val):
self.orientation_label.set_markup("<span font_desc='LiberationSans 25'>Orientation: %s</span>" % val)
def create_notebook_page_basic_sensor(self):
'''
create notebook page for displaying basic current
sensor information: temperature, humidity, pressure
'''
page_basic = Gtk.HBox(homogeneous=False, spacing=0)
page_basic.set_border_width(10)
# temperature
temp_box = Gtk.VBox(homogeneous=False, spacing=0)
temp_image = _load_image_constrained(self, "RS1069_climate_change_light_blue.png", -1, 100)
self.temperature_basic_label = Gtk.Label('--.-- °C')
temp_image.show()
self.temperature_basic_label.show()
temp_box.pack_start(temp_image, True, False, 1)
temp_box.add(self.temperature_basic_label)
# humidity
humidity_box = Gtk.VBox(homogeneous=False, spacing=0)
humidity_image = _load_image_constrained(self, "RS1902_humidity_light_blue.png", -1, 100)
self.humidity_basic_label = Gtk.Label('--.-- °C')
humidity_image.show()
self.humidity_basic_label.show()
humidity_box.pack_start(humidity_image, True, False, 1)
humidity_box.add(self.humidity_basic_label)
# Pressure
if WITH_PRESSURE:
pressure_box = Gtk.VBox(homogeneous=False, spacing=0)
pressure_image = _load_image_constrained(self, "RS6355_FORCE_PRESSURE_light_blue.png", -1, 100)
self.pressure_basic_label = Gtk.Label('--.-- °C')
pressure_image.show()
self.pressure_basic_label.show()
pressure_box.pack_start(pressure_image, True, False, 1)
pressure_box.add(self.pressure_basic_label)
page_basic.add(temp_box)
page_basic.add(humidity_box)
if WITH_PRESSURE:
page_basic.add(pressure_box)
notebook_title = Gtk.Label()
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Sensors</span>")
self.notebook.append_page(page_basic, notebook_title)
def create_notebook_page_basic_accel(self):
'''
create notebook page for displaying movement
sensor information: accellerometer, gyroscope, magentometer
'''
page_basic_movement = Gtk.Box()
page_basic_movement.set_border_width(10)
self.liststore = Gtk.ListStore(str, str, str, str)
self.accel_store = self.liststore.append([ "Accelerometer", "0.0", "0.0", "0.0" ])
if WITH_GYRO:
self.gyro_store = self.liststore.append([ "Gyroscope", "0.0", "0.0", "0.0" ])
#if WITH_MAGNETO:
# self.magneto_store = self.liststore.append([ "Magnetometer", "0.0", "0.0", "0.0" ])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Sensor", renderer_text, text=0)
treeview.append_column(column_text)
renderer_x = Gtk.CellRendererText()
column_x = Gtk.TreeViewColumn("X", renderer_x, text=1)
treeview.append_column(column_x)
renderer_y = Gtk.CellRendererText()
column_y = Gtk.TreeViewColumn("Y", renderer_y, text=2)
treeview.append_column(column_y)
renderer_z = Gtk.CellRendererText()
column_z = Gtk.TreeViewColumn("Z", renderer_z, text=3)
treeview.append_column(column_z)
page_basic_movement.add(treeview)
notebook_title = Gtk.Label()
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Move</span>")
self.notebook.append_page(page_basic_movement, notebook_title)
def create_notebook_page_imu(self):
'''
display the IMU: Inertial Measurement Unit
Roll(X-axis), Pitch(Y-axis) and Yaw(Z-axis).
'''
page_imu_all = Gtk.VBox(homogeneous=False, spacing=0)
imu_frame = Gtk.Frame(label="IMU")
orientation_frame = Gtk.Frame(label="Orientation")
page_imu = Gtk.VBox(homogeneous=False, spacing=0)
#page_imu_all.add(page_imu)
page_imu_all.add(imu_frame)
page_imu_all.add(orientation_frame)
page_imu.set_border_width(10)
# explanation
imu_label = Gtk.Label()
imu_label.set_markup("<span font_desc='LiberationSans 25'>Inertial Measurement Unit</span>")
page_imu.add(imu_label)
imu_h_box = Gtk.HBox(homogeneous=False, spacing=0)
# picture which describe IMU
picture_filename = "%s/RS10670_Aereo-lpr.jpg" % ICON_PICTURES_PATH
image_imu = _load_image(self, "RS10670_Aereo-lpr.jpg")
imu_h_box.pack_start(image_imu, True, True, 10)
# add tree view with roll, picth, yaw
self.imu_liststore = Gtk.ListStore(str, str)
self.roll_store = self.imu_liststore.append([ "Roll (X-axis)", "0.0"])
self.pitch_store = self.imu_liststore.append([ "Pitch (Y-axis)", "0.0"])
self.yaw_store = self.imu_liststore.append([ "Yaw (Z-axis)", "0.0"])
imu_treeview = Gtk.TreeView(model=self.imu_liststore)
imu_h_box.add(imu_treeview)
page_imu.add(imu_h_box)
imu_frame.add(page_imu)
self.orientation_label = Gtk.Label()
self.orientation_label.set_markup("<span font_desc='LiberationSans 25'>Orientation: --none--</span>")
orientation_frame.add(self.orientation_label)
renderer_text = Gtk.CellRendererText()
#renderer_text.set_property("size", 18)
column_imu_text = Gtk.TreeViewColumn('Type', renderer_text, text=0)
imu_treeview.append_column(column_imu_text)
renderer_val = Gtk.CellRendererText()
column_val = Gtk.TreeViewColumn("Value", renderer_val, text=1)
imu_treeview.append_column(column_val)
notebook_title = Gtk.Label()
notebook_title.set_markup("<span font_desc='LiberationSans 25'>IMU</span>")
self.notebook.append_page(page_imu_all, notebook_title)
def _create_frame_with_image_and_label(self, title, img_file_name, label_text):
frame = Gtk.Frame(label=title)
box = Gtk.VBox(homogeneous=False, spacing=0)
img = _load_image(self, img_file_name)
img = _load_image_constrained(self, img_file_name, -1, 100)
label = Gtk.Label()
label.set_markup("<span font_desc='LiberationSans 18'>%s</span>" % label_text)
box.add(img)
box.add(label)
frame.add(box)
return frame
def create_notebook_page_sensor_information(self):
''' Display all the sensor used for this demo '''
page_sensor_info = Gtk.Grid()
frame_temp = self._create_frame_with_image_and_label(
"%25s" % "Temperature",
"RS1069_climate_change_light_blue.png",
self.sensors.get_driver_name_temperature()
)
frame_humidity = self._create_frame_with_image_and_label(
"%25s" % "Humidity",
"RS1902_humidity_light_blue.png",
self.sensors.get_driver_name_humidity()
)
if WITH_PRESSURE:
frame_pressure = self._create_frame_with_image_and_label(
"%25s" % "Pressure",
"RS6355_FORCE_PRESSURE_light_blue.png",
self.sensors.get_driver_name_pressure()
)
frame_accel = self._create_frame_with_image_and_label(
"%25s" % "Accelerometer",
"RS1761_MEMS_accelerometer_light_blue.png",
self.sensors.get_driver_name_accelerometer()
)
if WITH_GYRO:
frame_gyro = self._create_frame_with_image_and_label(
"%25s" % "Gyroscope",
"RS1760_MEMS_gyroscope_light_blue.png",
self.sensors.get_driver_name_gyroscope()
)
#if WITH_MAGNETO:
# frame_magneto = self._create_frame_with_image_and_label(
# "%25s" % "Magnetometer",
# "RS1762_MEMS_compass_light_blue.png",
# self.sensors.get_driver_name_magnetometer()
# )
page_sensor_info.set_column_spacing(2)
page_sensor_info.set_row_spacing(2)
page_sensor_info.attach(frame_temp, 1, 1, 3, 1)
page_sensor_info.attach_next_to(frame_humidity, frame_temp,
Gtk.PositionType.RIGHT, 1, 1)
if WITH_PRESSURE:
page_sensor_info.attach_next_to(frame_pressure, frame_humidity,
Gtk.PositionType.RIGHT, 1, 1)
page_sensor_info.attach_next_to(frame_accel, frame_temp,
Gtk.PositionType.BOTTOM, 1, 1)
if WITH_GYRO:
page_sensor_info.attach_next_to(frame_gyro, frame_accel,
Gtk.PositionType.RIGHT, 1, 1)
#if WITH_MAGNETO:
# page_sensor_info.attach_next_to(frame_magneto, frame_gyro,
# Gtk.PositionType.RIGHT, 1, 1)
#self.notebook.append_page(page_sensor_info,
# Gtk.Image.new_from_icon_name(
# "dialog-information",
# Gtk.IconSize.MENU
# ))
notebook_title = Gtk.Label()
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Infos</span>")
self.notebook.append_page(page_sensor_info, notebook_title)
def create_notebook_page_exit(self):
''' notebook page for quitting application '''
page = Gtk.VBox(homogeneous=False, spacing=0)
page.set_border_width(10)
''' button '''
lastbutton = Gtk.Button()
lastbutton.connect("clicked", self.destroy)
image_to_add = _load_image_on_button(self, "%s/RS70_ST_Logo_Qi.png" % ICON_PICTURES_PATH, "Quit", -1, 200)
lastbutton.add(image_to_add)
lastbutton.show()
page.pack_start(lastbutton, True, True, 0)
exit_label = Gtk.Label()
exit_label.set_markup("<span font_desc='LiberationSans 25'>To exit, click on logo.</span>")
page.pack_start(exit_label, False, False, 0)
notebook_title = Gtk.Label()
notebook_title.set_markup("<span font_desc='LiberationSans 25'>EXIT</span>")
self.notebook.append_page(page, notebook_title)
def destroy(self, widget, data=None):
Gtk.main_quit()
def rearm_timer(self):
if self.timer_enable:
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
def update_ui(self, user_data):
if False == self.timer_enable:
return False;
# temperature
temp = self.sensors.read_temperature()
self._set_basic_temperature(temp)
# humidity
hum = self.sensors.read_humidity()
self._set_basic_humidity(hum)
# pressure
if WITH_PRESSURE:
press = self.sensors.read_pressure()
self._set_basic_pressure(press)
# accel
accel = self.sensors.read_accelerometer()
self._set_basic_accelerometer(accel[0], accel[1], accel[2])
# gyro
if WITH_GYRO:
gyro = self.sensors.read_gyroscope()
self._set_basic_gyroscope(gyro[0], gyro[1], gyro[2])
# magneto
#if WITH_MAGNETO:
# magneto = self.sensors.read_magnetometer()
# self._set_basic_magnetometer(magneto[0], magneto[1], magneto[2])
# imu
pitch, roll, yaw = self.sensors.calculate_imu(accel)
self._set_imu_pitch(pitch)
self._set_imu_roll(roll)
self._set_imu_yaw(yaw)
self._update_orientation(self.sensors.get_imu_orientation(pitch, roll))
#print("[DEBUG] visibility: ", self.get_property("visible"))
# As this is a timeout function, return True so that it
# continues to get called
return True
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
# add signal to catch CRTL+C
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
try:
#splScr = SplashScreen("%s/RS70_ST_Logo_Qi.png" % ICON_PICTURES_PATH, 5)
#Gtk.main()
win = MainUIWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
except Exception as exc:
print("Main Exception: ", exc )
Gtk.main()

View File

@@ -0,0 +1,505 @@
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
import cairo
import random
import math
from collections import deque
import os
#for testing on PC without sensors, put REAL to 0
MAKE_REAL_MESUREMENT = 1
NUM_SAMPLES = 112
HMARGIN = 20
VMARGIN = 10
CHARTHEIGHT = 40
GRAPH_V_PADDING = 4
GRAPH_H_PADDING = 4
#TIME_UPATE = 5000
TIME_UPATE = 1000
# example of orientation
# https://github.com/hadess/iio-sensor-proxy/blob/master/src/test-orientation-gtk.c
ORIENTATION_UNDEFINED = 0
ORIENTATION_NORMAL = 1
ORIENTATION_BOTTOM_UP = 2
ORIENTATION_LEFT_UP = 3
ORIENTATION_RIGHT_UP = 4
def _load_image_on_button(parent, filename, label_text):
# Create box for xpm and label
box1 = Gtk.HBox(False, 0)
box1.set_border_width(2)
# Now on to the image stuff
image = Gtk.Image()
image.set_from_file(filename)
# Create a label for the button
label = Gtk.Label(label_text)
# Pack the pixmap and label into the box
box1.pack_start(image, True, False, 3)
#box1.pack_start(label, False, False, 3)
image.show()
label.show()
return box1
class SensorWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Temperature/Humidity")
if MAKE_REAL_MESUREMENT > 0:
self.fullscreen()
#self.maximize()
screen_width = self.get_screen().get_width()
screen_height = 600
else:
screen_width = 400
screen_height = 600
self.temperature_prefix_path = self.found_iio_device("in_temp_raw")
self.humidity_prefix_path = self.found_iio_device("in_humidityrelative_raw")
self.accelerometer_prefix_path = self.found_iio_device("in_accel_x_raw")
#screen_height = self.get_screen().get_height()
self.set_default_size(screen_width, screen_height)
# current, Max, Min
self.temperature_max = 0.0
self.temperature_min = 35.0
self.humidity_max = 0.0
self.humidity_min = 35.0
'''
0: "undefined"
1: "normal"
2: "bottom-up",
3: "left-up",
4: "right-up",
'''
self.previous_orientation = ORIENTATION_UNDEFINED
''' TreeView '''
self.liststore = Gtk.ListStore(str, str, str, str)
self.temperature_store = self.liststore.append([ "Temperature", "0.0", "0.0", "0.0" ])
self.humidity_store = self.liststore.append([ "Humidity", "0.0", "0.0", "0.0" ])
self.accel_store = self.liststore.append([ "Accelerometer", "0.0", "0.0", "0.0" ])
self.treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Sensor", renderer_text, text=0)
self.treeview.append_column(column_text)
renderer_current = Gtk.CellRendererText()
column_cur = Gtk.TreeViewColumn("Current", renderer_current, text=1)
self.treeview.append_column(column_cur)
renderer_max = Gtk.CellRendererText()
column_max = Gtk.TreeViewColumn("Max", renderer_max, text=2)
self.treeview.append_column(column_max)
renderer_min = Gtk.CellRendererText()
column_min = Gtk.TreeViewColumn("Min", renderer_min, text=3)
self.treeview.append_column(column_min)
# Add a timer callback to update
# this takes 2 args: (how often to update in millisec, the method to run)
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
''' DrawView '''
self.drawarea = Gtk.DrawingArea()
self.drawing_area_width = screen_width
self.drawing_area_height = screen_height/2
self.drawarea.set_size_request(self.drawing_area_width, self.drawing_area_height)
self.drawarea.connect("draw", self._draw_event)
self._axis_ranges = {} # {axis_num: [min_seen, max_seen]}
self._axis_values = {} # {axis_num: deque([val0, ..., valN])}
''' spinner '''
# add scale
grid_scale_hor = Gtk.Grid()
grid_scale_hor.set_column_spacing(10)
grid_scale_hor.set_column_homogeneous(True)
self.x_adj = Gtk.Adjustment(0, -256, 256, 2, 2, 0)
self.x_scale = Gtk.Scale(orientation=Gtk.Orientation.VERTICAL)
self.x_scale.set_orientation(Gtk.Orientation.VERTICAL)
self.x_scale.set_adjustment(self.x_adj)
self.x_scale.set_digits(0)
self.x_scale.set_draw_value(True)
self.x_scale.set_vexpand(True)
grid_scale_hor.attach(self.x_scale, 0, 0, 1, 1)
self.y_adj = Gtk.Adjustment(0, -256, 256, 2, 2, 0)
self.y_scale = Gtk.Scale()
self.y_scale.set_orientation(Gtk.Orientation.VERTICAL)
self.y_scale.set_adjustment(self.y_adj)
self.y_scale.set_digits(0)
self.y_scale.set_draw_value(True)
self.y_scale.set_vexpand(True)
grid_scale_hor.attach_next_to(self.y_scale, self.x_scale, Gtk.PositionType.RIGHT, 1, 1)
self.z_adj = Gtk.Adjustment(0.0, -256.0, 256.0, 2.0, 2.0, 0.0)
self.z_scale = Gtk.Scale()
self.z_scale.set_orientation(Gtk.Orientation.VERTICAL)
self.z_scale.set_adjustment(self.z_adj)
self.z_scale.set_digits(0)
self.z_scale.set_draw_value(True)
self.z_scale.set_vexpand(True)
grid_scale_hor.attach_next_to(self.z_scale, self.y_scale, Gtk.PositionType.RIGHT, 1, 1)
self.orientation = Gtk.Label("Orientation")
#grid_scale_hor.attach_next_to(self.orientation, self.z_scale, Gtk.PositionType.RIGHT, 1, 1)
grid_scale_hor.attach(self.orientation, 0, 1, 2, 1)
''' button '''
lastbutton = Gtk.Button()
lastbutton.connect("clicked", self.destroy)
if MAKE_REAL_MESUREMENT > 0:
image_to_add = _load_image_on_button(self, "/home/root/stlogo.png", "Quit")
else:
image_to_add = _load_image_on_button(self, "./stlogo.png", "Quit")
lastbutton.add(image_to_add)
lastbutton.show()
"""
UI:
---------------------------------------------------
| | |
| DrawingArea with two graph | Treeview |
| | |
---------------------------------------------------
| | |
| Spinner for accelerometer | Button with |
| | ST image |
---------------------------------------------------
"""
box_outer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
self.add(box_outer)
# to activate draw area
boxdraw_vert = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
boxdraw_vert.pack_start(self.drawarea, False, True, 0)
boxdraw_vert.pack_start(grid_scale_hor, True, True, 0)
box_outer.pack_start(boxdraw_vert, False, True, 0)
box_vert = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.tree_frame = Gtk.Frame(label="Temperature & Humidity")
box_vert.pack_start(self.tree_frame, True, True, 0)
self.tree_frame.add(self.treeview)
box_vert.pack_start(lastbutton, True, True, 0)
box_outer.pack_start(box_vert, True, True, 0)
def destroy(self, widget, data=None):
Gtk.main_quit()
def found_iio_device(self, data):
prefix = "/sys/bus/iio/devices/"
try:
for filefolder in os.listdir(prefix):
if os.path.exists(prefix + '/' + filefolder + '/' + data):
''' return directory which contains "data" '''
return (prefix + '/' + filefolder + '/')
except OSError:
pass
return None
def _draw_cb(self, drawingarea, ctx):
width = self.drawing_area_width
height = self.drawing_area_height
axis_ids = set(self._axis_ranges.keys())
axis_ids.intersection_update(set(self._axis_values.keys()))
for i in sorted(axis_ids):
if i == 1:
# temperature value
#draw rectangle
ctx.set_source_rgb(0.8, 0.8, 0.8)
ctx.rectangle(0, 0, width, height/2)
ctx.fill()
#draw axes
ctx.set_source_rgb(0, 1, 1)
ctx.move_to(30 + 0.5, height/4)
ctx.line_to(width - 0.5, height/4)
ctx.stroke()
# value (text)
ctx.select_font_face("sans-serif")
ctx.set_font_size(20.0)
ctx.set_source_rgb(0, 0, 0)
ctx.move_to(0, 20)
ctx.show_text("T (°C)")
ctx.set_font_size(10.0)
ctx.move_to(0, height/4 + 4)
ctx.show_text("20 °C")
# temperateure between 0 and 40
values = self._axis_values[i]
ctx.set_source_rgb(0, 0, 0)
for x, v in enumerate(values):
val = 30 + x*GRAPH_H_PADDING
ctx.move_to(val, height/2)
ctx.line_to(val, (40.0 - v) * height/80)
ctx.stroke()
if i == 2:
# Humidity values
offset = 10
#draw rectangle
ctx.set_source_rgb(0.8, 0.8, 0.8)
ctx.rectangle(0, height/2 + offset, width, height/2)
ctx.fill()
#draw axes
ctx.set_source_rgb(0, 1, 1)
ctx.move_to(25 + 0.5, height/2 + offset + height/4)
ctx.line_to(width - 0.5, height/2 + offset + height/4)
ctx.stroke()
# value (text)
ctx.select_font_face("sans-serif")
ctx.set_font_size(20.0)
ctx.set_source_rgb(0, 0, 0)
ctx.move_to(0, height/2 + offset + 20)
ctx.show_text("H (%)")
ctx.set_font_size(10.0)
ctx.set_source_rgb(0, 0, 0)
ctx.move_to(0, height/2 + offset + height/4 + 4)
ctx.show_text("50 %")
values = self._axis_values[i]
ctx.set_source_rgb(0, 0, 0)
for x, v in enumerate(values):
val = 25 + x*GRAPH_H_PADDING
ctx.move_to(val, height/2 + offset + height/2)
ctx.line_to(val, height/2 + offset + (100.0 - v) * height/200)
ctx.stroke()
return False
def _orientation_calc(self, x, y, z):
rotation = round( math.atan(x / math.sqrt(y * y + z * z)) * 180.0 * math.pi)
if abs(rotation) > 35:
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
if self.previous_orientation == ORIENTATION_LEFT_UP or self.previous_orientation == ORIENTATION_NORMAL:
if abs(rotation) < 5:
self.update_movement(self.previous_orientation)
else:
if rotation > 0:
self.update_movement(ORIENTATION_LEFT_UP)
else:
self.update_movement(ORIENTATION_RIGHT_UP)
else:
rotation = round( math.atan(y / math.sqrt(x * x + z * z)) * 180.0 * math.pi)
if abs(rotation) > 35:
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
if self.previous_orientation == ORIENTATION_BOTTOM_UP or self.previous_orientation == ORIENTATION_NORMAL:
if abs(rotation) < 5:
self.update_movement(self.previous_orientation)
else:
if rotation > 0:
self.update_movement(ORIENTATION_BOTTOM_UP)
else:
self.update_movement(ORIENTATION_NORMAL)
def orientation_calc(self, x, y, z):
rotation = round( math.atan(x / math.sqrt(y * y + z * z)) * 180.0 * math.pi)
if abs(rotation) > 35:
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
if rotation > 0:
self.update_movement(ORIENTATION_LEFT_UP)
else:
self.update_movement(ORIENTATION_RIGHT_UP)
else:
rotation = round( math.atan(y / math.sqrt(x * x + z * z)) * 180.0 * math.pi)
if abs(rotation) > 35:
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
if rotation > 0:
self.update_movement(ORIENTATION_BOTTOM_UP)
else:
self.update_movement(ORIENTATION_NORMAL)
def udate_temperature(self, cur_val):
self.liststore[self.temperature_store][1] = '%.2f' % cur_val
if cur_val > self.temperature_max:
self.temperature_max = cur_val
if cur_val < self.temperature_min:
self.temperature_min = cur_val
self.liststore[self.temperature_store][2] = '%.2f' % self.temperature_max
self.liststore[self.temperature_store][3] = '%.2f' % self.temperature_min
''' for drawing '''
values = self._axis_values.get(1, None)
if values is None:
values = deque(maxlen=NUM_SAMPLES)
self._axis_values[1] = values
if len(list(values)) > (NUM_SAMPLES - 1):
values. popleft()
values.append(cur_val)
self._axis_ranges[1] = (0.0, 60.0)
#print("TEMPERATURE: cur_val = %0.2f Max: %0.2f" % (cur_val, self.temperature_max))
#print(self.liststore[self.temperature_store][0:])
def udate_humidity(self, cur_val):
self.liststore[self.humidity_store][1] = '%.2f' % cur_val
if cur_val > self.humidity_max:
self.humidity_max = cur_val
if cur_val < self.humidity_min:
self.humidity_min = cur_val
self.liststore[self.humidity_store][2] = '%.2f' % self.humidity_max
self.liststore[self.humidity_store][3] = '%.2f' % self.humidity_min
''' for drawing '''
values = self._axis_values.get(2, None)
if values is None:
values = deque(maxlen=NUM_SAMPLES)
self._axis_values[2] = values
values.append(cur_val)
self._axis_ranges[2] = (0.0, 60.0)
def update_accel(self, x, y, z):
self.liststore[self.accel_store][1] = '%d' % x
self.liststore[self.accel_store][2] = '%d' % y
self.liststore[self.accel_store][3] = '%d' % z
self.x_adj.set_value(x)
self.y_adj.set_value(y)
self.z_adj.set_value(z)
def update_movement(self, m):
self.previous_orientation = m
if m == ORIENTATION_UNDEFINED:
self.orientation.set_text("undefined")
elif m == ORIENTATION_NORMAL:
self.orientation.set_text("normal")
elif m == ORIENTATION_BOTTOM_UP:
self.orientation.set_text("bottom-up")
elif m == ORIENTATION_LEFT_UP:
self.orientation.set_text("left-up")
elif m == ORIENTATION_RIGHT_UP:
self.orientation.set_text("right-up")
else:
self.orientation.set_text("undefined")
def read_temperature(self):
offset = 0.0
raw = 0.0
scale = 0.0
temp = 0.0
if MAKE_REAL_MESUREMENT > 0:
if self.temperature_prefix_path:
with open(self.temperature_prefix_path + 'in_temp_offset', 'r') as f:
offset = float(f.read())
with open(self.temperature_prefix_path + 'in_temp_raw', 'r') as f:
raw = float(f.read())
with open(self.temperature_prefix_path + 'in_temp_scale', 'r') as f:
scale = float(f.read())
temp = (offset + raw) * scale
self.udate_temperature(temp)
else:
# randomly generated
self.udate_temperature(random.uniform(18.0, 35.0))
else:
# randomly generated
self.udate_temperature(random.uniform(18.0, 35.0))
def read_humidity(self):
offset = 0.0
raw = 0.0
scale = 0.0
temp = 0.0
if MAKE_REAL_MESUREMENT > 0:
if self.humidity_prefix_path:
with open(self.humidity_prefix_path + 'in_humidityrelative_offset', 'r') as f:
offset = float(f.read())
with open(self.humidity_prefix_path + 'in_humidityrelative_raw', 'r') as f:
raw = float(f.read())
with open(self.humidity_prefix_path + 'in_humidityrelative_scale', 'r') as f:
scale = float(f.read())
temp = (offset + raw) * scale
self.udate_humidity(temp)
else:
# randomly generated
self.udate_humidity(random.uniform(18.0, 35.0))
else:
# randomly generated
self.udate_humidity(random.uniform(18.0, 35.0))
def read_accel(self):
raw = 0.0
scale = 0.0
in_x = 0.0
in_y = 0.0
in_z = 0.0
if MAKE_REAL_MESUREMENT > 0:
if self.accelerometer_prefix_path:
with open(self.accelerometer_prefix_path + 'in_accel_x_raw', 'r') as f:
scale = float(f.read())
with open(self.accelerometer_prefix_path + 'in_accel_x_scale', 'r') as f:
raw = float(f.read())
in_x = int(raw * scale * 256.0 / 9.81)
with open(self.accelerometer_prefix_path + 'in_accel_y_raw', 'r') as f:
scale = float(f.read())
with open(self.accelerometer_prefix_path + 'in_accel_y_scale', 'r') as f:
raw = float(f.read())
in_y = int(raw * scale * 256.0 / 9.81)
with open(self.accelerometer_prefix_path + 'in_accel_z_raw', 'r') as f:
scale = float(f.read())
with open(self.accelerometer_prefix_path + 'in_accel_z_scale', 'r') as f:
raw = float(f.read())
in_z = int(raw * scale * 256.0 / 9.81)
self.update_accel(in_x, in_y, in_z)
else:
in_x = random.randint(-256, 256)
in_y = random.randint(-256, 256)
in_z = random.randint(-256, 256)
self.update_accel(in_x, in_y, in_z)
else:
in_x = random.randint(-256, 256)
in_y = random.randint(-256, 256)
in_z = random.randint(-256, 256)
self.update_accel(in_x, in_y, in_z)
self.orientation_calc(in_x, in_y, in_z)
def _draw_event(self, drawingarea, user_data):
win = self.drawarea.get_window()
ctx = win.cairo_create()
self._draw_cb(win, ctx)
def update_ui(self, user_data):
self.read_temperature()
self.read_humidity()
self.read_accel()
win = self.drawarea.get_window()
ctx = win.cairo_create()
self._draw_cb(win, ctx)
# As this is a timeout function, return True so that it
# continues to get called
return True
win = SensorWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()