Files
2024-07-11 14:16:35 +02:00

400 lines
16 KiB
Python

#!/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 os
import socket
import fcntl
import struct
import string
import random
import math
import subprocess
from time import sleep, time
import threading
SIMULATE = 0
ETHERNET_PREFIX="end"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
SUBMODULE_PATH = "application/netdata"
DEMO_PATH = "/usr/local/demo"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
WIFI_LINUX_INTERFACE_NAME = "wlan0"
WIFI_HOTSPOT_IP="192.168.72.1"
WIFI_DEFAULT_SSID="STDemoNetwork"
WIFI_DEFAULT_PASSWD="stm32mp1"
if SIMULATE > 0:
WIFI_LINUX_INTERFACE_NAME = "wlp8s0"
# -------------------------------------------------------------------
# -------------------------------------------------------------------
ICON_SIZE_1080 = 260
ICON_SIZE_720 = 160
ICON_SIZE_480 = 160
ICON_SIZE_272 = 48
# return format:
# [ icon_size, font_size ]
SIZES_ID_ICON_SIZE = 0
SIZES_ID_FONT_SIZE = 1
def get_sizes_from_screen_size(width, height):
minsize = min(width, height)
icon_size = None
font_size = None
if minsize == 720:
icon_size = ICON_SIZE_720
font_size = 25
elif minsize == 480:
icon_size = ICON_SIZE_480
font_size = 20
elif minsize == 272:
icon_size = ICON_SIZE_272
font_size = 10
elif minsize == 600:
icon_size = ICON_SIZE_720
font_size = 15
elif minsize >= 1080:
icon_size = ICON_SIZE_1080
font_size = 32
return [icon_size, font_size]
def get_icon_size_from_screen_size(width, height):
minsize = min(width, height)
if minsize == 720:
return ICON_SIZE_720
elif minsize == 480:
return ICON_SIZE_480
elif minsize == 272:
return ICON_SIZE_272
elif minsize == 600:
return ICON_SIZE_1080
elif minsize >= 1080:
return ICON_SIZE_1080
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Get the wlan interface name
def get_wlan_interface_name():
cmd = ["%s/application/netdata/bin/get_wlan_name.sh" % DEMO_PATH]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
res = proc.stdout.read().decode('utf-8')
return res
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Get list of ip address
def get_ip_address_list():
cmd = ["%s/application/netdata/bin/get_ethernet_ip.sh" % DEMO_PATH]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
res = proc.stdout.read().decode('utf-8')
return res
# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Get the ip address of board
def get_ip_address(ifname):
ip = "NA"
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip = socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', bytes(ifname[:15], 'utf-8'))
)[20:24])
except socket.error:
pass
return ip
# -------------------------------------------------------------------
# -------------------------------------------------------------------
def _load_image_wlan_eventBox(parent, filename, label_text1, label_text2, scale_w, scale_h):
# 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='10' color='#FFFFFFFF'>%s\n</span>"
"<span font='10' color='#FFFFFFFF'>%s</span>" % (label_text1, label_text2))
#label.set_justify(Gtk.Justification.LEFT)
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 id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return "".join(random.choice(chars) for _ in range(size))
# -------------------------------------------------------------------
# -------------------------------------------------------------------
class NetdataWebserver(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "Wifi", parent, 0)
if SIMULATE > 0:
self.screen_width = 800
self.screen_height = 480
self.set_default_size(self.screen_width, self.screen_height)
else:
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.icon_size = get_icon_size_from_screen_size(self.screen_width, self.screen_height)
sizes = get_sizes_from_screen_size(self.screen_width, self.screen_height)
self.font_size = sizes[SIZES_ID_FONT_SIZE]
self.set_decorated(False)
rgba = Gdk.RGBA(0.31, 0.32, 0.31, 0.8)
self.override_background_color(0,rgba)
mainvbox = self.get_content_area()
self.page_ip = Gtk.VBox(homogeneous=False, spacing=0)
self.page_ip.set_border_width(10)
self.set_border_width(10)
self.title = Gtk.Label()
self.title.set_markup("<span font='%d' color='#FFFFFFFF'><b>Access information to netdata</b></span>" % (self.font_size+5))
self.page_ip.add(self.title)
self.label_eth = Gtk.Label()
self.label_eth.set_markup("<span font='%d' color='#FFFFFFFF'>netdata over Ethernet:</span>" % self.font_size)
self.label_eth.set_xalign (0.0)
self.label_ip_ethernet = Gtk.Label()
#self.label_ip_ethernet.set_xalign (0.0)
self.label_wifi = Gtk.Label()
self.label_wifi.set_markup("<span font='%d' color='#FFFFFFFF'>netdata over Wifi:</span>" % self.font_size)
self.label_wifi.set_xalign (0.0)
self.label_ip_wlan0 = Gtk.Label()
#self.label_ip_wlan0.set_xalign (0.0)
self.label_hotspot = Gtk.Label()
self.label_hotspot.set_xalign (0.0)
self.previous_click_time=0
self.wifi_ssid=WIFI_DEFAULT_SSID
self.wifi_passwd=WIFI_DEFAULT_PASSWD
self.info_grid = Gtk.Grid()
self.info_grid.set_column_spacing(2)
self.info_grid.set_row_spacing(2)
self.info_grid.attach(self.label_eth, 0, 1, 1, 1)
self.info_grid.attach(self.label_ip_ethernet, 1, 1, 1, 1)
if self.is_wifi_available():
print ("wlan0 is available")
self.hotspot_switch = Gtk.Switch()
# set wlan switch state on first execution
ip_wlan0 = get_ip_address(get_wlan_interface_name())
if ip_wlan0 == WIFI_HOTSPOT_IP:
self.hotspot_switch.set_active(True)
else:
self.hotspot_switch.set_active(False)
self.hotspot_switch.connect("notify::active", self.on_switch_activated)
self.info_grid.attach(self.label_wifi, 0, 2, 1, 1)
self.info_grid.attach(self.hotspot_switch, 0, 3, 1, 1)
self.info_grid.attach(self.label_hotspot, 1, 3, 1, 1)
else:
print ("wlan0 interface not available")
self.info_grid.attach(self.label_hotspot, 0, 3, 1, 1)
self.page_ip.add(self.info_grid)
self.refresh_network_page()
self.connect("button-release-event", self.on_page_press_event)
mainvbox.pack_start(self.page_ip, False, True, 3)
self.show_all()
def is_wifi_available(self):
interface_name = get_wlan_interface_name()
if len(interface_name) > 0:
return True
return False
def get_wifi_config(self):
filepath = "/etc/default/hostapd"
if os.path.isfile(filepath):
file = open(filepath, "r")
i=0
for line in file:
if "HOSTAPD_SSID" in line:
self.wifi_ssid = (line.split('=')[1]).rstrip('\r\n')
i+=1
if "HOSTAPD_PASSWD" in line:
self.wifi_passwd=(line.split('=')[1]).rstrip('\r\n')
i+=1
file.close()
if (i==2):
print("[Wifi: use hostapd configuration: ssid=%s, passwd=%s]\n" %(self.wifi_ssid, self.wifi_passwd))
else:
self.wifi_ssid=WIFI_DEFAULT_SSID
self.wifi_passwd=WIFI_DEFAULT_PASSWD
print("[Wifi: use default configuration: ssid=%s, passwd=%s]\n" %(self.wifi_ssid, self.wifi_passwd))
else:
print("[Wifi: use default configuration: ssid=%s, passwd=%s]\n" %(self.wifi_ssid, self.wifi_passwd))
def set_random_wifi_config(self):
self.wifi_ssid="ST-" + id_generator()
#self.wifi_passwd=id_generator(6, string.ascii_lowercase)
self.set_wifi_config(self.wifi_ssid, self.wifi_passwd)
def set_wifi_config(self, ssid, password):
filepath = "/tmp/hostapd"
file = open(filepath, "w")
print ("[Wifi: set hostapd config: ssid=%s, passwd=%s]" %(ssid, password))
file.write('HOSTAPD_SSID=%s\nHOSTAPD_PASSWD=%s\n' %(ssid, password))
file.close()
os.system('su -c \"cp /tmp/hostapd /etc/default/hostapd\"')
def refresh_network_page(self):
print("[Refresh network page]\n")
ip_list=get_ip_address_list().split()
if len(ip_list) > 0:
ip_ethernet = ip_list[0]
ethernet_status = "<span font='%d' color='#FFFFFFFF'> %s</span>" % (self.font_size, ip_ethernet)
else:
ip_ethernet = get_ip_address('{}0'.format(ETHERNET_PREFIX))
if ip_ethernet == "NA":
ip_ethernet = get_ip_address('{}1'.format(ETHERNET_PREFIX))
if ip_ethernet != "NA":
ethernet_status = "<span font='%d' color='#FFFFFFFF'> http://%s:19999</span>" % (self.font_size, ip_ethernet)
else:
ethernet_status = "<span font='%d' color='#FF0000FF'> No Ethernet connection</span>" % self.font_size
self.label_ip_ethernet.set_markup(ethernet_status)
if self.is_wifi_available():
print ("wlan0 is available")
ip_wlan0 = get_ip_address(get_wlan_interface_name())
print("Ip address of Wlan0 are: ", ip_wlan0)
if ip_wlan0 == "NA":
sleep(1)
ip_wlan0 = get_ip_address(get_wlan_interface_name())
print("Ip address of Wlan0 are: ", ip_wlan0)
if ip_wlan0 == "NA":
hotspot_status = "<span font='%d' color='#FF0000FF'> Wifi not started</span>" % self.font_size
self.info_grid.remove_row(6)
elif ip_wlan0 == WIFI_HOTSPOT_IP:
self.get_wifi_config()
hotspot_status = "<span font='%d' color='#00AA00FF'> Wifi hotspot started</span>" % self.font_size
wifi_qrcode_cmd = "WIFI:S:%s;T:WPA;P:%s;;" %(self.wifi_ssid, self.wifi_passwd)
print("%s/bin/build_qrcode.sh" % os.path.join(DEMO_PATH,SUBMODULE_PATH), "-o /tmp/qr-code_wifi_access.png", wifi_qrcode_cmd)
cmd = ["%s/bin/build_qrcode.sh" % os.path.join(DEMO_PATH,SUBMODULE_PATH), "-o /tmp/qr-code_wifi_access.png", wifi_qrcode_cmd]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = proc.stdout.read().decode('utf-8')
url_qrcode_cmd = "http://%s:19999" % ip_wlan0
cmd2 = ["%s/bin/build_qrcode.sh" % os.path.join(DEMO_PATH,SUBMODULE_PATH), "-o /tmp/qr-code_netdata_url.png", url_qrcode_cmd]
proc = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = proc.stdout.read().decode('utf-8')
self.wifi_credential = _load_image_wlan_eventBox(self, "/tmp/qr-code_wifi_access.png", "ssid: %s" % self.wifi_ssid, "passwd: %s" % self.wifi_passwd, -1, self.icon_size)
self.netdata_url = _load_image_wlan_eventBox(self, "/tmp/qr-code_netdata_url.png", "url: http://%s:19999" % ip_wlan0, "", -1, self.icon_size)
self.info_grid.attach(self.wifi_credential, 0, 6, 1, 1)
self.info_grid.attach(self.netdata_url, 1, 6, 1, 1)
self.show_all()
else:
hotspot_status = "<span font='%d' color='#FF0000FF'>Wifi started but not configured as hotspot</span>" % self.font_size
self.info_grid.remove_row(6)
self.label_ip_wlan0.set_markup("<span font='%d' color='#FFFFFFFF'>NetData over Wifi: http://%s:19999</span>" % (self.font_size, ip_wlan0))
self.info_grid.attach(self.label_ip_wlan0, 0, 6, 1, 1)
self.show_all()
else:
print ("wlan0 interface not available")
hotspot_status = "<span font='%d' color='#FF0000FF'> Wifi not available on board</span>" % self.font_size
self.label_hotspot.set_markup(hotspot_status)
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 : exit")
self.destroy()
else:
#print ("simple click")
self.previous_click_time = self.click_time
def on_switch_activated(self, switch, gparam):
if switch.get_active():
self.set_random_wifi_config()
self.wifi_hotspot_start()
else:
self.wifi_hotspot_stop()
self.refresh_network_page()
def wifi_hotspot_start(self):
print('[DEBUG]: %s/application/netdata/bin/wifi_start.sh' % DEMO_PATH)
os.system('%s/application/netdata/bin/wifi_start.sh' % DEMO_PATH)
def wifi_hotspot_stop(self):
print('[DEBUG]:%s/application/netdata/bin/wifi_start.sh\"' % DEMO_PATH)
os.system('%s/application/netdata/bin/wifi_stop.sh' % DEMO_PATH)
def create_subdialogwindow(parent):
_window = NetdataWebserver(parent)
_window.show_all()
response = _window.run()
_window.destroy()
# -------------------------------------------------
# -------------------------------------------------
# test submodule
class TestUIWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Test Launcher")
create_subdialogwindow(self)
self.show_all()
if __name__ == "__main__":
win = TestUIWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()