Konubinix' opinionated web of thoughts

More Clever Night Light in Kivy

Fleeting

Following more clever night light, but using my a python runtime on android, so that I can use it when travelling. I also needed it a day when my sd card burned and I did not have a fiber connection to build a new raspberry pi image easily.

the code

Using the click sound from click.ogg

import os
from datetime import datetime, timedelta

import math
import time
import requests
from subprocess import call
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
import requests
from kivy.properties import BooleanProperty, NumericProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from plyer import wifi
from android.runnable import run_on_ui_thread

import subprocess
from kivy.uix.spinner import Spinner
from plyer import orientation
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.audio import SoundLoader

from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from kivy.uix.screenmanager import Screen, ScreenManager, ScreenManagerException
from kivy.core.audio import SoundLoader

from jnius import autoclass

from helpers.osc import oschandler, to_service
from helpers.wakelock import WakeLock
from helpers.notify import notify, show_toast, get_memory_usage, list_open_files
from android.runnable import run_on_ui_thread
from logging import getLogger
from kivy.lang import Builder
from kivy.uix.togglebutton import ToggleButton

Context = autoclass('android.content.Context')
AlarmManager = autoclass('android.app.AlarmManager')
PendingIntent = autoclass('android.app.PendingIntent')
Intent = autoclass('android.content.Intent')
SystemClock = autoclass('android.os.SystemClock')
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Build_VERSION = autoclass('android.os.Build$VERSION')
api_level = Build_VERSION.SDK_INT
activity = PythonActivity.mActivity
WifiManager = autoclass('android.net.wifi.WifiManager')
wifi_service = activity.getSystemService(Context.WIFI_SERVICE)

logger = getLogger(__name__)

pink = (1, 0.75, 0.8)
orange = (1, 0.5, 0)
cyan = (0, 1, 1)
white = (1, 1, 1)
red = (1, 0, 0)
black = (0, 0, 0)
green = (0, 1, 0)

school_schedule = {
    "almost_hour": 6,
    "almost_minute": 30,
    "getup_hour": 7,
    "getup_minute": 0,
    "day_hour": 7,
    "day_minute": 40,
    "evening_hour": 20,
    "evening_minute": 0,
    "night_hour": 20,
    "night_minute": 30,
}

holiday_schedule = {
    "almost_hour": 7,
    "almost_minute": 30,
    "getup_hour": 8,
    "getup_minute": 0,
    "day_hour": 8,
    "day_minute": 40,
    "evening_hour": 20,
    "evening_minute": 0,
    "night_hour": 20,
    "night_minute": 30,
}

force_today = None


def ease_debugging(schedule, today=None, duration=30, start_time="night"):
    now = datetime.now()
    global force_today
    force_today = today

    start_assoc = {"night": 0, "almost": 1, "getup": 2, "day": 3, "evening": 4,
                   "tomorrow": 5,}

    schedule["almost_hour"] = (now + timedelta(minutes=duration*(1 - start_assoc[start_time]))).hour
    schedule["almost_minute"] = (now + timedelta(minutes=duration*(1 - start_assoc[start_time]))).minute

    schedule["getup_hour"] = (now + timedelta(minutes=duration*(2 - start_assoc[start_time]))).hour
    schedule["getup_minute"] = (now + timedelta(minutes=duration*(2 - start_assoc[start_time]))).minute

    schedule["day_hour"] = (now + timedelta(minutes=duration*(3 - start_assoc[start_time]))).hour
    schedule["day_minute"] = (now + timedelta(minutes=duration*(3 - start_assoc[start_time]))).minute

    schedule["evening_hour"] = (now + timedelta(minutes=duration*(4 - start_assoc[start_time]))).hour
    schedule["evening_minute"] = (now + timedelta(minutes=duration*(4 - start_assoc[start_time]))).minute

    schedule["night_hour"] = (now + timedelta(minutes=duration*(5 - start_assoc[start_time]))).hour
    schedule["night_minute"] = (now + timedelta(minutes=duration*(5 - start_assoc[start_time]))).minute

#ease_debugging(holiday_schedule, duration=60)
#ease_debugging(school_schedule, duration=60)

@run_on_ui_thread
def fs2():
    from jnius import autoclass, cast
    window = activity.getWindow()
    decorView = window.getDecorView()
    View = autoclass('android.view.View')
    flags = (
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_FULLSCREEN
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    )

    # Apply flags
    decorView.setSystemUiVisibility(flags)

    # Also set window flag to keep fullscreen
    LayoutParams = autoclass('android.view.WindowManager$LayoutParams')
    window.addFlags(LayoutParams.FLAG_FULLSCREEN)


def su(cmd):
    logger.debug("su: {}".format(cmd))
    call(["su", "-c", cmd])

def set_wifi_enabled(enable=True):
    if api_level >= 26:
        # on recent android, we cannot deal with the wifi anymore, I will
        # therefore rely on su and for sake of simplicity enable airplane mode
        # all together
        su("settings put global airplane_mode_on {}".format("0" if enable else "1"))
        su("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state {}".format("false" if enable else "true"))
    else:
        # this works with android 4 and 5. I only need to play with the wifi
        # because all other services are generally already off on such legacy
        # devices
        wifi_service.setWifiEnabled(enable)
        wifi_service.reconnect()

def wake_n_notify(message, sleep=True, priority="default"):
    import threading
    logger.debug("thread: {}".format(threading.current_thread().name))
    set_wifi_enabled(True)
    now = datetime.now()
    message = "{:02}:{:02}:{:02}: {}".format(now.hour, now.minute, now.second, message)
    show_toast(message)
    for _ in range(3):
        if notify(message, channel="nightlight", priority=priority):
            # get_memory_usage(channel="nightlight")
            show_toast("notification sent: {}".format(message), long=True)
            # also sync the date until I get back internet (and ntp) working
            try:
                if os.path.exists("/system/bin/toybox"):
                    resp = requests.get("http://home/dateserver/toybox")
                    if resp.status_code // 100 != 2:
                        raise NotImplementedError()
                    su("toybox date {}".format(resp.text))
                elif os.path.exists("/system/bin/toolbox"):
                    # heuristic. On the device that accepts another format, which is not there
                    if os.path.exists("/system/xbin/which"):
                        resp = requests.get("http://home/dateserver/toolbox1")
                        if resp.status_code // 100 != 2:
                            raise NotImplementedError()
                        su("toolbox date {}".format(resp.text))
                    else:
                        resp = requests.get("http://home/dateserver/toolbox2")
                        if resp.status_code // 100 != 2:
                            raise NotImplementedError()
                        su("toolbox date -s {}".format(resp.text))
                else:
                    raise NotImplementedError()
            except Exception as e:
                show_toast("Failed to update the date...: {}".format(e))
            break
        else:
            seconds = 5
            show_toast("retrying in {} seconds".format(seconds))
            time.sleep(seconds)
    if sleep:
        set_wifi_enabled(False)

class SettingsScreen(Screen):
    steps = NumericProperty(4)
    step_time = NumericProperty(20)
    rest_time = NumericProperty(10)
    total_time = StringProperty("Total: 0s")

    def _update_rect(self, instance, value):
        self.rect.pos = instance.pos
        self.rect.size = instance.size

    def get_current_schedule(self):
        if self.holidays.state == "down":
            return holiday_schedule
        else:
            return school_schedule

    def trigger_ease_debugging(self, *_):
        """Trigger ease_debugging on the currently selected schedule"""
        if self.debug_button.state == "normal":
            logger.info("Debug mode is off, not triggering ease_debugging")
            return
        ease_debugging(school_schedule, duration=int(self.debug_number.text))
        ease_debugging(holiday_schedule, duration=int(self.debug_number.text))
        logger.info("Triggered ease_debugging on current schedule")
        # Update the UI to reflect the new schedule values
        self.setup_times()

    def create_time_picker(self, layout, label_text, hour_key, minute_key):
        """Create a time picker layout with hour and minute spinners"""
        time_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(time_layout)

        time_layout.add_widget(Label(text=label_text, color=(0, 0, 0, 1)))

        # Hour spinner
        hour_spinner = Spinner(
            text="0",  # Temporary value, will be set by setup_times
            values=[str(i) for i in range(0, 24)],
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(hour_spinner, hour_key)
        time_layout.ad
    def bind_spinner(self, spinner, key):
        def update_schedule(instance, value):
            current_schedule = self.get_current_schedule()
            current_schedule[key] = int(value)
            # logger.info("Updated {} to {} in global schedule".format(key, value))

        spinner.bind(text=update_schedule)

    def __init__(self, **kwargs):
        wake_n_notify("Updating the date", sleep=True)
        super(SettingsScreen, self).__init__(**kwargs)
        with self.canvas.before:
            self.color = Color(1, 1, 1, 1)
            self.rect = Rectangle(size=self.size, pos=self.pos)

        self.bind(size=self._update_rect, pos=self._update_rect)

        layout = BoxLayout(orientation='vertical')
        self.add_widget(layout)

        self.debug_button_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(self.debug_button_layout)

        self.debug_button = ToggleButton(
            text='Debug Mode',
            size_hint=(1, 1),
            background_color=(1, 0.5, 0, 1),
            pos_hint={'center_x': .5, 'center_y': .5},
            color=(1, 1, 1, 1),
        )
        self.debug_button.bind(on_press=self.trigger_ease_debugging)
        self.debug_button_layout.add_widget(self.debug_button)
        self.debug_number = Spinner(
            text="1",
            values=[str(i) for i in range(0, 61)],  # numbers 0 to 60
            size_hint=(1, 1),
            pos_hint={'center_x': .5, 'center_y': .5},
        )
        self.debug_number.bind(text=self.trigger_ease_debugging)
        self.debug_button_layout.add_widget(self.debug_number)

        self.holidays = ToggleButton(text='Holidays', size_hint=(1, 0.15))

        layout.add_widget(self.holidays)
        self.holidays.bind(on_press=self.setup_times)

        almost_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(almost_layout)
        almost_layout.add_widget(
            Label(text="Almost", color=(0, 0, 0, 1))
        )
        self.almost_hour = Spinner(
            text="7",
            values=[str(i) for i in range(0, 24)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.almost_hour, "almost_hour")
        almost_layout.add_widget(self.almost_hour)
        self.almost_minute = Spinner(
            text='30',
            values=[str(i) for i in range(0, 60)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.almost_minute, "almost_minute")
        almost_layout.add_widget(self.almost_minute)

        getup_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(getup_layout)
        getup_layout.add_widget(
            Label(text="getup", color=(0, 0, 0, 1))
        )
        self.getup_hour = Spinner(
            text="8",
            values=[str(i) for i in range(0, 24)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.getup_hour, "getup_hour")
        getup_layout.add_widget(self.getup_hour)
        self.getup_minute = Spinner(
            text='0',
            values=[str(i) for i in range(0, 60)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.getup_minute, "getup_minute")
        getup_layout.add_widget(self.getup_minute)

        day_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(day_layout)
        day_layout.add_widget(
            Label(text="day", color=(0, 0, 0, 1))
        )
        self.day_hour = Spinner(
            text="8",
            values=[str(i) for i in range(0, 24)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.day_hour, "day_hour")
        day_layout.add_widget(self.day_hour)
        self.day_minute = Spinner(
            text='40',
            values=[str(i) for i in range(0, 60)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.day_minute, "day_minute")
        day_layout.add_widget(self.day_minute)

        evening_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(evening_layout)
        evening_layout.add_widget(
            Label(text="evening", color=(0, 0, 0, 1))
        )
        self.evening_hour = Spinner(
            text="20",
            values=[str(i) for i in range(0, 24)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.evening_hour, "evening_hour")
        evening_layout.add_widget(self.evening_hour)
        self.evening_minute = Spinner(
            text='0',
            values=[str(i) for i in range(0, 60)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.evening_minute, "evening_minute")
        evening_layout.add_widget(self.evening_minute)

        night_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(night_layout)
        night_layout.add_widget(
            Label(text="night", color=(0, 0, 0, 1))
        )
        self.night_hour = Spinner(
            text="8",
            values=[str(i) for i in range(0, 24)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.night_hour, "night_hour")
        night_layout.add_widget(self.night_hour)
        self.night_minute = Spinner(
            text='0',
            values=[str(i) for i in range(0, 60)],  # numbers 0 to 100
            size_hint=(None, None),
            size=(200, 44),
            pos_hint={'center_x': .5, 'center_y': .5}
        )
        self.bind_spinner(self.night_minute, "night_minute")
        night_layout.add_widget(self.night_minute)

        self.setup_times()

        self.go_button = Button(text="Go !!!",
                                background_color=(0, 0, 1, 1),
                                color=(1, 1, 1, 1),
                                size_hint=(1, 0.15), disabled=True)
        self.go_button.bind(on_press=self.start)
        layout.add_widget(self.go_button)

        @oschandler("service:ready")
        def _(_):
            self.go_button.disabled = False

    def setup_times(self, instance=None):
        if self.holidays.state == "down":
            logger.info("Using holidays schedule {}".format(self.holidays.state))
            schedule = holiday_schedule
        else:
            logger.info("Using school schedule")
            schedule = school_schedule

        self.almost_hour.text = str(schedule["almost_hour"])
        self.almost_minute.text = str(schedule["almost_minute"])
        self.getup_hour.text = str(schedule["getup_hour"])
        self.getup_minute.text = str(schedule["getup_minute"])
        self.day_hour.text = str(schedule["day_hour"])
        self.day_minute.text = str(schedule["day_minute"])
        self.evening_hour.text = str(schedule["evening_hour"])
        self.evening_minute.text = str(schedule["evening_minute"])
        self.night_hour.text = str(schedule["night_hour"])
        self.night_minute.text = str(schedule["night_minute"])


    def start(self, *_):
        app = App.get_running_app()
        normal = app.sm.get_screen('nightlight:normal')
        normal.debug = self.debug_button.state == "down"
        normal.debug_number = int(self.debug_number.text)
        normal.holidays = self.holidays.state == "down"

        app.goto("nightlight:normal")
        normal.start()

class NormalScreen(Screen):

    def _update_rect(self, instance, value):
        self.rect.pos = instance.pos
        self.rect.size = instance.size

    def _get_time(self, value):
        now = datetime.now()
        today = force_today or now.weekday()
        if self.holidays or today in [2, 5, 6]:  # 2=Wednesday, 5=Saturday, 6=Sunday
            schedule = holiday_schedule
            logger.debug("the schedule of today is holiday")
        else:
            schedule = school_schedule
            logger.debug("the schedule of today is school")
        if now.replace(hour=schedule["night_hour"],
                       minute=schedule["night_minute"], second=0,) < now:
            logger.debug("it is late, I should consider the schedule of tomorrow")
            if self.holidays or today in [2-1, 5-1, 6-1]:  # tomorrow is a day off
                schedule = holiday_schedule
            else:
                schedule = school_schedule
        if value == "almost_hour" and self.debug:
            ease_debugging(schedule, duration=self.debug_number)
            logger.debug("Today: {}, schedule[{}]: {}".format(today, value, schedule[value]))
        return schedule[value]

    @property
    def almost_hour(self):
        return self._get_time("almost_hour")
    @property
    def almost_minute(self):
        return self._get_time("almost_minute")
    @property
    def getup_hour(self):
        return self._get_time("getup_hour")
    @property
    def getup_minute(self):
        return self._get_time("getup_minute")
    @property
    def day_hour(self):
        return self._get_time("day_hour")
    @property
    def day_minute(self):
        return self._get_time("day_minute")
    @property
    def evening_hour(self):
        return self._get_time("evening_hour")
    @property
    def evening_minute(self):
        return self._get_time("evening_minute")
    @property
    def night_hour(self):
        return self._get_time("night_hour")

    @property
    def night_minute(self):
        return self._get_time("night_minute")

    def __init__(self, **kwargs):
        super(NormalScreen, self).__init__(**kwargs)
        self.click = SoundLoader.load(os.path.join(os.path.dirname(__file__), "click.ogg"))
        self.remaining_time = None

        with self.canvas.before:
            self.color = Color(0, 0, 0, 1)
            self.rect = Rectangle(size=self.size, pos=self.pos)

        self.bind(size=self._update_rect, pos=self._update_rect)

        layout = BoxLayout(orientation='vertical')
        self.add_widget(layout)

        current_layout = BoxLayout(size_hint=(1, 0.15))
        layout.add_widget(current_layout)
        self.current_hour = Label(
            text="7",
            font_size="115sp",
        )
        current_layout.add_widget(self.current_hour)
        self.sep = Label(
            text=":",
            font_size="150sp",
        )
        current_layout.add_widget(self.sep)
        self.current_minute = Label(
            text='30',
            font_size="115sp",
        )
        current_layout.add_widget(self.current_minute)

        self.keepon = WakeLock("nightlight:keepon", wakeup=False, partial=True)
        self.wakeup = WakeLock("nightlight:wakeup", wakeup=True, partial=False)
        self.keepon.acquire()
        self.update_display()

        @oschandler("clockwake:done:nightlight:almost", answer=True)
        def _(_):
            app = App.get_running_app()
            if app.sm.current == self.name:
                Clock.schedule_once(self.almost)
            else:
                wake_n_notify("nightlight:almost, but not in the right screen", sleep=not self.debug)

        @oschandler("clockwake:done:nightlight:getup", answer=True)
        def _(_):
            app = App.get_running_app()
            if app.sm.current == self.name:
                Clock.schedule_once(self.getup)
            else:
                wake_n_notify("nightlight:getup, but not in the right screen", sleep=not self.debug)

        @oschandler("clockwake:done:nightlight:day", answer=True)
        def _(_):
            app = App.get_running_app()
            if app.sm.current == self.name:
                Clock.schedule_once(self.day)
            else:
                wake_n_notify("nightlight:day, but not in the right screen", sleep=not self.debug)

        @oschandler("clockwake:done:nightlight:evening", answer=True)
        def _(_):
            app = App.get_running_app()
            if app.sm.current == self.name:
                Clock.schedule_once(self.evening)
            else:
                wake_n_notify("nightlight:evening, but not in the right screen", sleep=not self.debug)

        @oschandler("clockwake:done:nightlight:night", answer=True)
        def _(_):
            app = App.get_running_app()
            if app.sm.current == self.name:
                Clock.schedule_once(self.night)
            else:
                wake_n_notify("nightlight:night, but not in the right screen", sleep=not self.debug)

        self.bind(on_pre_enter=self.pre_enter_handler)
        self.bind(on_pre_leave=self.pre_leave_handler)

    def pre_leave_handler(self, _):
        self.keepon.release()
        self.wakeup.release()
        from jnius import autoclass
        from android import mActivity

        View = autoclass('android.view.View')

        option = View.SYSTEM_UI_FLAG_VISIBLE
        from android.runnable import run_on_ui_thread

        @run_on_ui_thread
        def fs():
            logger.debug("Exit fullscreen mode")
            mActivity.getWindow().getDecorView().setSystemUiVisibility(option)

        if not self.debug:
            fs()

    def pre_enter_handler(self, _):
        # from plyer import orientation
        # orientation.set_landscape()

        from jnius import autoclass
        from android import mActivity

        View = autoclass('android.view.View')

        option = View.SYSTEM_UI_FLAG_FULLSCREEN

        @run_on_ui_thread
        def fs():
            logger.debug("Entering fullscreen mode")
            mActivity.getWindow().getDecorView().setSystemUiVisibility(option)

        if not self.debug:

            if api_level >= 26:
                fs2()
            else:
                fs()

    def update_display(self, *_):
        now = datetime.now()
        self.current_hour.text = str(now.hour).zfill(2)
        self.current_minute.text = str(now.minute).zfill(2)
        Clock.schedule_once(self.update_display, 61 - now.second)

    def durationuntil(self, hour, minute):
        now = datetime.now()
        new_date = now.replace(hour=hour, minute=minute,second=0)
        duration = (new_date - now).total_seconds()
        if duration < 0:
            new_date = new_date + timedelta(days=1)
            duration = (new_date - now).total_seconds()
        return duration

    def start(self):
        now = datetime.now()
        almost = now.replace(hour=self.almost_hour, minute=self.almost_minute)
        getup = now.replace(hour=self.getup_hour, minute=self.getup_minute)
        day = now.replace(hour=self.day_hour, minute=self.day_minute)
        evening = now.replace(hour=self.evening_hour, minute=self.evening_minute)
        night = now.replace(hour=self.night_hour, minute=self.night_minute)

        if now < almost:
            self.night()
        elif now < getup:
            self.almost()
        elif now < day:
            self.getup()
        elif now < evening:
            self.day()
        elif now < night:
            self.evening()
        else:
            self.night()

    def almost(self, *_):
        self.color.rgb = orange
        self.current_hour.color = (0,0,0, 1)
        self.current_minute.color = (0,0,0, 1)
        self.sep.color = (0,0,0, 1)
        self.wakeup.acquire()
        wake_n_notify("almost time, next at {:02}:{:02}".format(self.getup_hour,
                                                                self.getup_minute), priority=("low" if self.debug else "default"),sleep=not self.debug)
        to_service("clockwake", {"duration": self.durationuntil(self.getup_hour, self.getup_minute), "callback": "nightlight:getup"})

    def getup(self, *_):
        self.color.rgb = green
        self.current_hour.color = (0,0,0, 1)
        self.sep.color = (0,0,0, 1)
        self.current_minute.color = (0,0,0, 1)
        self.wakeup.acquire()
        wake_n_notify("getup, next at {:02}:{:02}".format(self.day_hour, self.day_minute), priority=("low" if self.debug else "default"),sleep=not self.debug)
        self.click.seek(0)
        self.click.play()
        to_service("clockwake", {"duration": self.durationuntil(self.day_hour, self.day_minute), "callback": "nightlight:day"})

    def day(self, *_):
        wake_n_notify("day, next at {:02}:{:02}".format(self.evening_hour, self.evening_minute), priority=("low" if self.debug else "default"),sleep=not self.debug)
        self.wakeup.release()
        self.current_hour.color = (0,0,0, 1)
        self.sep.color = (0,0,0, 1)
        self.current_minute.color = (0,0,0, 1)
        self.color.rgb = white
        to_service("clockwake", {"duration": self.durationuntil(self.evening_hour, self.evening_minute), "callback": "nightlight:evening"})

    def evening(self, *_):
        self.color.rgb = red
        self.current_hour.color = (1,1,1, 1)
        self.sep.color = (1,1,1, 1)
        self.current_minute.color = (1,1,1, 1)
        self.wakeup.acquire()
        wake_n_notify("evening, next at {:02}:{:02}".format(self.night_hour, self.night_minute), priority=("low" if self.debug else "default"),sleep=not self.debug)
        self.click.seek(0)
        self.click.play()
        to_service("clockwake", {"duration": self.durationuntil(self.night_hour, self.night_minute), "callback": "nightlight:night"})

    def night(self, *_):
        wake_n_notify("night, next at {:02}:{:02}".format(self.almost_hour, self.almost_minute), priority=("low" if self.debug else "default"),sleep=not self.debug)
        self.wakeup.release()
        self.color.rgb = black
        to_service("clockwake", {"duration": self.durationuntil(self.almost_hour, self.almost_minute), "callback": "nightlight:almost"})


class NightLightApp(App):

    def goto(self, screen):
        self.sm.current = screen

    def back(self):
        self.sm.current = 'nightlight:normal'

    @staticmethod
    def populate(sm):
        try:
            sm.get_screen('nightlight:normal')
            return
        except ScreenManagerException:
            pass # not populated yet

        sm.add_widget(SettingsScreen(name='nightlight:settings'))
        sm.add_widget(NormalScreen(name='nightlight:normal'))

    def build(self):
        self.sm = ScreenManager()
        self.populate(self.sm)
        return self.sm


def run():
    NightLightApp().run()

trying it

It worked well for a time.

But I noticed that the android application stopped working from time to time, generally after a day or two. I ran a test, monitoring the used RAM and the number of open files, in debug mode (hence with a change every minutes). I found out that the behavior depended a lot on the device I used:

  • on the wiko cink peax 2, android 4.1.2 and using the legacy runtime, the JNI part generally segfault after either a few hours1,
  • on the i9300, running android 8, its number of files keeps increasing until it reaches the 1024 limit and fails, after about 2 hours2, most likely due to the call to su to disable the wifi
  • on the zte blade s6, running android 5, I did not managed to make it crash, I stopped the application after more than 48 hours of continuously working (hence more than 3000 changes).

None of them showed memory issues.

I already used the three of them to run the pomodo timer on kivy for months without any issue, so running a kivy app for a long time is not impossible. But in that case, I’m out of luck. I bet that the main issue is with turning off and on the wifi.

I don’t like using a solution that is so dependant on the android device, so I tried another implementation based on micropython.

See more clever night light in micropython.

investigating the file descriptor issue on the i9300

clk android -d i9300 adb shell pidof eu.konubinix.konixpoc
20409

pid=$(echo ${pid}|trim)
clk android -d i9300 adb shell su -c "'ls -la /proc/${pid//\n/}/fd'"|cut -f 2 -d '>' |sed -r 's/socket:.+$/socket/'|sort |uniq -c
...
    1  /dev/binder
    1  /dev/hwbinder
    1  /dev/mali
  114  /dev/null
    1  /dev/ump
    3  /dev/urandom
    1  /system/framework/android.hidl.base-V1.0-java.jar
    1  /system/framework/android.hidl.manager-V1.0-java.jar
    1  /system/framework/apache-xml.jar
    1  /system/framework/bouncycastle.jar
    1  /system/framework/conscrypt.jar
    1  /system/framework/core-libart.jar
    1  /system/framework/core-oj.jar
    1  /system/framework/ext.jar
    1  /system/framework/framework-res.apk
    1  /system/framework/framework.jar
    1  /system/framework/ims-common.jar
    1  /system/framework/legacy-test.jar
    1  /system/framework/okhttp.jar
    1  /system/framework/org.apache.http.legacy.boot.jar
    1  /system/framework/telephony-common.jar
    1  /system/framework/voip-common.jar
    3  anon_inode:[eventfd]
    3  anon_inode:[eventpoll]
  168  anon_inode:mali-4232
    6  anon_inode:sync_fence
    2  pipe:[23022]
  114  socket
    1 dr-x------ 2 u0_a101 u0_a101  0 2025-08-07 07:15 .
    1 dr-xr-xr-x 8 u0_a101 u0_a101  0 2025-08-07 07:15 ..
    1 total 0

trying to remove the calls to show_toast

 2  /data/app/eu.konubinix.konixpoc-Fy72Z4lKElrJ27GZCjfhAw==/base.apk
 1  /data/data/eu.konubinix.konixpoc/files/app/.kivy/logs/kivy_25-08-07_4.txt
 4  /data/data/eu.konubinix.konixpoc/files/app/_python_bundle/site-packages/kivy/data/fonts/Roboto-Regular.ttf
 1  /data/data/eu.konubinix.konixpoc/files/app/main.pyc
 3  /dev/ashmem
 1  /dev/binder
 1  /dev/hwbinder
 1  /dev/mali
12  /dev/null
 1  /dev/ump
 3  /dev/urandom
 1  /system/framework/android.hidl.base-V1.0-java.jar
 1  /system/framework/android.hidl.manager-V1.0-java.jar
 1  /system/framework/apache-xml.jar
 1  /system/framework/bouncycastle.jar
 1  /system/framework/conscrypt.jar
 1  /system/framework/core-libart.jar
 1  /system/framework/core-oj.jar
 1  /system/framework/ext.jar
 1  /system/framework/framework-res.apk
 1  /system/framework/framework.jar
 1  /system/framework/ims-common.jar
 1  /system/framework/legacy-test.jar
 1  /system/framework/okhttp.jar
 1  /system/framework/org.apache.http.legacy.boot.jar
 1  /system/framework/telephony-common.jar
 1  /system/framework/voip-common.jar
 2  anon_inode:[eventfd]
 2  anon_inode:[eventpoll]
12  anon_inode:mali-16605
 8  anon_inode:sync_fence
 2  pipe:[133878]
10  socket
 1 dr-x------ 2 u0_a101 u0_a101  0 2025-08-07 08:43 .
 1 dr-xr-xr-x 8 u0_a101 u0_a101  0 2025-08-07 08:43 ..
 1 total 0

Fixing show_toast and trying again

 2  /data/app/eu.konubinix.konixpoc-Fy72Z4lKElrJ27GZCjfhAw==/base.apk
 1  /data/data/eu.konubinix.konixpoc/files/app/.kivy/logs/kivy_25-08-07_12.txt
 4  /data/data/eu.konubinix.konixpoc/files/app/_python_bundle/site-packages/kivy/data/fonts/Roboto-Regular.ttf
 1  /data/data/eu.konubinix.konixpoc/files/app/main.pyc
 3  /dev/ashmem
 1  /dev/binder
 1  /dev/hwbinder
 1  /dev/mali
13  /dev/null
 1  /dev/ump
 3  /dev/urandom
 1  /system/framework/android.hidl.base-V1.0-java.jar
 1  /system/framework/android.hidl.manager-V1.0-java.jar
 1  /system/framework/apache-xml.jar
 1  /system/framework/bouncycastle.jar
 1  /system/framework/conscrypt.jar
 1  /system/framework/core-libart.jar
 1  /system/framework/core-oj.jar
 1  /system/framework/ext.jar
 1  /system/framework/framework-res.apk
 1  /system/framework/framework.jar
 1  /system/framework/ims-common.jar
 1  /system/framework/legacy-test.jar
 1  /system/framework/okhttp.jar
 1  /system/framework/org.apache.http.legacy.boot.jar
 1  /system/framework/telephony-common.jar
 1  /system/framework/voip-common.jar
 2  anon_inode:[eventfd]
 2  anon_inode:[eventpoll]
12  anon_inode:mali-20409
 7  anon_inode:sync_fence
 2  pipe:[188587]
10  socket
 1 dr-x------ 2 u0_a101 u0_a101  0 2025-08-07 09:10 .
 1 dr-xr-xr-x 8 u0_a101 u0_a101  0 2025-08-07 09:10 ..
 1 total 0

Now, the i9300 works without noticeable issue. The cinkpeax2 though, still crashes.

investigating the crash on the cinkpeax2

This device is able to run the pomodo timer on kivy for several weeks without issue, so there is likely something that triggers the segfault here.

This is more hairy, because reproducing the error needs to run the application for several hours.

It seems that the error happen in wake_n_notify.

Notes linking here


  1. 148:I/DEBUG   ( 8877): handle_request(15)
    149:I/DEBUG   ( 8877): check process 3014 name:ubinix.konixpoc
    150:I/DEBUG   ( 8877): BOOM: pid=3014 uid=10079 gid=10079 tid=3045
    160:I/DEBUG   ( 8877): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    161:I/DEBUG   ( 8877): Build fingerprint: 'WIKO/wiko/wiko:4.1.2/JZO54K/:user/release-keys'
    162:I/DEBUG   ( 8877): pid: 3014, tid: 3045, name: SDLThread  >>> eu.konubinix.konixpoc <<<
    163:I/DEBUG   ( 8877): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008
    196:I/DEBUG   ( 8877):     r0 00000000  r1 00000000  r2 5157a180  r3 40d88c84
    197:I/DEBUG   ( 8877):     r4 00000000  r5 00000000  r6 5157a180  r7 00000001
    198:I/DEBUG   ( 8877):     r8 00000000  r9 00000001  sl 56772d9c  fp 00000000
    199:I/DEBUG   ( 8877):     ip 00000000  sp 55e0f1a8  lr 40d2ac15  pc 40d22550  cpsr 60000030
    200:I/DEBUG   ( 8877):
    201:I/DEBUG   ( 8877): backtrace:
    202:I/DEBUG   ( 8877):     #00  pc 00042550  /system/lib/libdvm.so (dvmDbgGetTagWidth(int)+135)
    203:I/DEBUG   ( 8877):     #01  pc 0004ac11  /system/lib/libdvm.so
    204:I/DEBUG   ( 8877):     #02  pc 00036e6b  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    205:I/DEBUG   ( 8877):
    206:I/DEBUG   ( 8877): stack:
    207:I/DEBUG   ( 8877):          55e0f168  00000000
    208:I/DEBUG   ( 8877):          55e0f16c  00000000
    209:I/DEBUG   ( 8877):          55e0f170  55e0f194  [stack:3045]
    210:I/DEBUG   ( 8877):          55e0f174  5158bb98
    211:I/DEBUG   ( 8877):          55e0f178  40d71ffb  /system/lib/libdvm.so
    212:I/DEBUG   ( 8877):          55e0f17c  0000000d
    213:I/DEBUG   ( 8877):          55e0f180  55e0f1ac  [stack:3045]
    214:I/DEBUG   ( 8877):          55e0f184  00000000
    215:I/DEBUG   ( 8877):          55e0f188  5157a180
    216:I/DEBUG   ( 8877):          55e0f18c  40d28bc5  /system/lib/libdvm.so
    217:I/DEBUG   ( 8877):          55e0f190  55e0f1ac  [stack:3045]
    218:I/DEBUG   ( 8877):          55e0f194  5157a180
    219:I/DEBUG   ( 8877):          55e0f198  00000000
    220:I/DEBUG   ( 8877):          55e0f19c  00000000
    221:I/DEBUG   ( 8877):          55e0f1a0  df0027ad
    222:I/DEBUG   ( 8877):          55e0f1a4  00000000
    223:I/DEBUG   ( 8877):     #00  55e0f1a8  5157a180
    224:I/DEBUG   ( 8877):          ........  ........
    225:I/DEBUG   ( 8877):     #01  55e0f1a8  5157a180
    226:I/DEBUG   ( 8877):          55e0f1ac  515a02a8
    227:I/DEBUG   ( 8877):          55e0f1b0  00000000
    228:I/DEBUG   ( 8877):          55e0f1b4  5978da20
    229:I/DEBUG   ( 8877):          55e0f1b8  5157a180
    230:I/DEBUG   ( 8877):          55e0f1bc  56753e6d  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    231:I/DEBUG   ( 8877):     #02  55e0f1c0  566cc28d
    232:I/DEBUG   ( 8877):          55e0f1c4  00000001
    233:I/DEBUG   ( 8877):          55e0f1c8  5978da34
    234:I/DEBUG   ( 8877):          55e0f1cc  551f16ef  /data/data/eu.konubinix.konixpoc/lib/libpython2.7.so (PyString_FromStringAndSize+166)
    235:I/DEBUG   ( 8877):          55e0f1d0  1d3007fd
    236:I/DEBUG   ( 8877):          55e0f1d4  5978da20
    237:I/DEBUG   ( 8877):          55e0f1d8  566cc278
    238:I/DEBUG   ( 8877):          55e0f1dc  5157a180
    239:I/DEBUG   ( 8877):          55e0f1e0  00000001
    240:I/DEBUG   ( 8877):          55e0f1e4  00000000
    241:I/DEBUG   ( 8877):          55e0f1e8  00000001
    242:I/DEBUG   ( 8877):          55e0f1ec  56772d9c  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    243:I/DEBUG   ( 8877):          55e0f1f0  00000000
    244:I/DEBUG   ( 8877):          55e0f1f4  56750565  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    245:I/DEBUG   ( 8877):          55e0f1f8  40d8f0a0
    246:I/DEBUG   ( 8877):          55e0f1fc  40d28761  /system/lib/libdvm.so
    247:I/DEBUG   ( 8877):
    248:I/DEBUG   ( 8877): memory near r2:
    249:I/DEBUG   ( 8877):     5157a160 6e696275 6b2e7869 78696e6f 2f636f70  ubinix.konixpoc/
    250:I/DEBUG   ( 8877):     5157a170 656c6966 70612f73 51570070 00000023  files/app.WQ#...
    251:I/DEBUG   ( 8877):     5157a180 40d862f0 00000000 0000000d 515a02a8  .b.@..........ZQ
    252:I/DEBUG   ( 8877):     5157a190 00000000 515a2dd8 5155b2e0 0000001b  .....-ZQ..UQ....
    253:I/DEBUG   ( 8877):     5157a1a0 48545950 4e5f4e4f 3d454d41 68747970  PYTHON_NAME=pyth
    254:I/DEBUG   ( 8877):
    255:I/DEBUG   ( 8877): memory near r3:
    256:I/DEBUG   ( 8877):     40d88c64 40d880cc 40d88158 40d881cc 40d88208  ...@X..@...@...@
    257:I/DEBUG   ( 8877):     40d88c74 40d32479 40d34ff5 40d4c1c9 40d48425  y$.@.O.@...@%..@
    258:I/DEBUG   ( 8877):     40d88c84 00000000 00000000 00000000 4006d318  ...............@
    259:I/DEBUG   ( 8877):     40d88c94 400565d4 40055cd0 40053540 4005355c  .e.@.\.@@5.@\5.@
    260:I/DEBUG   ( 8877):     40d88ca4 40056a30 400c27f4 400c2440 400cf1b8  0j.@.'.@@$.@...@
    261:I/DEBUG   ( 8877):
    262:I/DEBUG   ( 8877): memory near r6:
    263:I/DEBUG   ( 8877):     5157a160 6e696275 6b2e7869 78696e6f 2f636f70  ubinix.konixpoc/
    264:I/DEBUG   ( 8877):     5157a170 656c6966 70612f73 51570070 00000023  files/app.WQ#...
    265:I/DEBUG   ( 8877):     5157a180 40d862f0 00000000 0000000d 515a02a8  .b.@..........ZQ
    266:I/DEBUG   ( 8877):     5157a190 00000000 515a2dd8 5155b2e0 0000001b  .....-ZQ..UQ....
    267:I/DEBUG   ( 8877):     5157a1a0 48545950 4e5f4e4f 3d454d41 68747970  PYTHON_NAME=pyth
    268:I/DEBUG   ( 8877):
    269:I/DEBUG   ( 8877): memory near sl:
    270:I/DEBUG   ( 8877):     56772d7c 55311ec0 5530ff14 55309620 56776130  ..1U..0U .0U0awV
    271:I/DEBUG   ( 8877):     56772d8c 5530ffa4 5530bf90 5530ff18 5530fe6c  ..0U..0U..0Ul.0U
    272:I/DEBUG   ( 8877):     56772d9c 00000000 00000000 00000000 40072bb8  .............+.@
    273:I/DEBUG   ( 8877):     56772dac 40072d6c 551e5cc9 55238271 55238569  l-.@.\.Uq.#Ui.#U
    274:I/DEBUG   ( 8877):     56772dbc 551fc2ed 551d8111 5522c639 55238931  ...U...U9."U1.#U
    275:I/DEBUG   ( 8877):
    276:I/DEBUG   ( 8877): memory near sp:
    277:I/DEBUG   ( 8877):     55e0f188 5157a180 40d28bc5 55e0f1ac 5157a180  ..WQ...@...U..WQ
    278:I/DEBUG   ( 8877):     55e0f198 00000000 00000000 df0027ad 00000000  .........'......
    279:I/DEBUG   ( 8877):     55e0f1a8 5157a180 515a02a8 00000000 5978da20  ..WQ..ZQ.... .xY
    280:I/DEBUG   ( 8877):     55e0f1b8 5157a180 56753e6d 566cc28d 00000001  ..WQm>uV..lV....
    281:I/DEBUG   ( 8877):     55e0f1c8 5978da34 551f16ef 1d3007fd 5978da20  4.xY...U..0. .xY
    282:I/DEBUG   ( 8877):
    283:I/DEBUG   ( 8877): code around pc:
    284:I/DEBUG   ( 8877):     40d22530 20064905 44794a05 f7db447a f04fe908  .I. .JyDzD....O.
    285:I/DEBUG   ( 8877):     40d22540 bd0830ff bd082001 00049c88 0004adfa  .0... ..........
    286:I/DEBUG   ( 8877):     40d22550 47706880 6805b538 785c69ab f7ff4620  .hpG8..h.i\x F..
    287:I/DEBUG   ( 8877):     40d22560 b920fd31 e8bd6be8 f7ff4038 4620bd83  1. ..k..8@.... F
    288:I/DEBUG   ( 8877):     40d22570 0000bd38 4ff7e92d 6883461e 19924614  8...-..O.F.h.F..
    289:I/DEBUG   ( 8877):
    290:I/DEBUG   ( 8877): code around lr:
    291:I/DEBUG   ( 8877):     40d2abf4 4603bd1c 460cb537 4619a801 f7fd4615  ...F7..F...F.F..
    292:I/DEBUG   ( 8877):     40d2ac04 4621ffc3 f7fe9801 4604fff7 fc9ef7f7  ..!F.......F....
    293:I/DEBUG   ( 8877):     40d2ac14 fde6f7fd f00a4620 4604f920 2000b10d  .... F.. ..F...
    294:I/DEBUG   ( 8877):     40d2ac24 a8017028 ffd4f7fd bd3e4620 b5134603  (p...... F>..F..
    295:I/DEBUG   ( 8877):     40d2ac34 a801460c f7fd4619 4621ffa7 f7fe9801  .F...F....!F....
    
    468566:I/DEBUG   ( 1940): handle_request(15)
    468567:I/DEBUG   ( 1940): check process 687 name:ubinix.konixpoc
    468568:I/DEBUG   ( 1940): BOOM: pid=687 uid=10079 gid=10079 tid=733
    468593:I/DEBUG   ( 1940): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    468594:I/DEBUG   ( 1940): Build fingerprint: 'WIKO/wiko/wiko:4.1.2/JZO54K/:user/release-keys'
    468595:I/DEBUG   ( 1940): pid: 687, tid: 733, name: SDLThread  >>> eu.konubinix.konixpoc <<<
    468596:I/DEBUG   ( 1940): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008
    468622:I/DEBUG   ( 1940):     r0 00000000  r1 00000000  r2 515dda28  r3 40d88c84
    468623:I/DEBUG   ( 1940):     r4 00000000  r5 00000000  r6 515dda28  r7 00000001
    468624:I/DEBUG   ( 1940):     r8 00000000  r9 00000001  sl 56769d9c  fp 00000000
    468625:I/DEBUG   ( 1940):     ip 00000000  sp 55e0e300  lr 40d2ac15  pc 40d22550  cpsr 60000030
    468626:I/DEBUG   ( 1940):
    468627:I/DEBUG   ( 1940): backtrace:
    468628:I/DEBUG   ( 1940):     #00  pc 00042550  /system/lib/libdvm.so (dvmDbgGetTagWidth(int)+135)
    468629:I/DEBUG   ( 1940):     #01  pc 0004ac11  /system/lib/libdvm.so
    468630:I/DEBUG   ( 1940):     #02  pc 00036e6b  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    468631:I/DEBUG   ( 1940):
    468632:I/DEBUG   ( 1940): stack:
    468633:I/DEBUG   ( 1940):          55e0e2c0  00000000
    468634:I/DEBUG   ( 1940):          55e0e2c4  00000000
    468635:I/DEBUG   ( 1940):          55e0e2c8  55e0e2ec  [stack:733]
    468636:I/DEBUG   ( 1940):          55e0e2cc  51553b08
    468637:I/DEBUG   ( 1940):          55e0e2d0  40d71ffb  /system/lib/libdvm.so
    468638:I/DEBUG   ( 1940):          55e0e2d4  0000000d
    468639:I/DEBUG   ( 1940):          55e0e2d8  55e0e304  [stack:733]
    468640:I/DEBUG   ( 1940):          55e0e2dc  00000000
    468641:I/DEBUG   ( 1940):          55e0e2e0  515dda28
    468642:I/DEBUG   ( 1940):          55e0e2e4  40d28bc5  /system/lib/libdvm.so
    468643:I/DEBUG   ( 1940):          55e0e2e8  55e0e304  [stack:733]
    468644:I/DEBUG   ( 1940):          55e0e2ec  515dda28
    468645:I/DEBUG   ( 1940):          55e0e2f0  00000000
    468646:I/DEBUG   ( 1940):          55e0e2f4  00000000
    468647:I/DEBUG   ( 1940):          55e0e2f8  df0027ad
    468648:I/DEBUG   ( 1940):          55e0e2fc  00000000
    468649:I/DEBUG   ( 1940):     #00  55e0e300  515dda28
    468650:I/DEBUG   ( 1940):          ........  ........
    468651:I/DEBUG   ( 1940):     #01  55e0e300  515dda28
    468652:I/DEBUG   ( 1940):          55e0e304  515a02a8
    468653:I/DEBUG   ( 1940):          55e0e308  00000000
    468658:I/DEBUG   ( 1940):          55e0e30c  59761430
    468659:I/DEBUG   ( 1940):          55e0e310  515dda28
    468660:I/DEBUG   ( 1940):          55e0e314  5674ae6d  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    468661:I/DEBUG   ( 1940):     #02  55e0e318  566c60fd
    468662:I/DEBUG   ( 1940):          55e0e31c  00000001
    468663:I/DEBUG   ( 1940):          55e0e320  59761444
    468664:I/DEBUG   ( 1940):          55e0e324  551f16ef  /data/data/eu.konubinix.konixpoc/lib/libpython2.7.so (PyString_FromStringAndSize+166)
    468665:I/DEBUG   ( 1940):          55e0e328  1d4007fd
    468666:I/DEBUG   ( 1940):          55e0e32c  59761430
    468667:I/DEBUG   ( 1940):          55e0e330  566c60e8
    468668:I/DEBUG   ( 1940):          55e0e334  515dda28
    468669:I/DEBUG   ( 1940):          55e0e338  00000001
    468670:I/DEBUG   ( 1940):          55e0e33c  00000000
    468671:I/DEBUG   ( 1940):          55e0e340  00000001
    468672:I/DEBUG   ( 1940):          55e0e344  56769d9c  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    468673:I/DEBUG   ( 1940):          55e0e348  00000000
    468674:I/DEBUG   ( 1940):          55e0e34c  56747565  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    468675:I/DEBUG   ( 1940):          55e0e350  40d8f0a0
    468676:I/DEBUG   ( 1940):          55e0e354  40d28761  /system/lib/libdvm.so
    468677:I/DEBUG   ( 1940):
    468678:I/DEBUG   ( 1940): memory near r2:
    468679:I/DEBUG   ( 1940):     515dda08 402ec934 00000000 41400000 41400000  4..@......@A..@A
    468680:I/DEBUG   ( 1940):     515dda18 40a00000 41400000 41400000 00000023  ...@..@A..@A#...
    468681:I/DEBUG   ( 1940):     515dda28 40d862f0 00000000 0000000d 515a02a8  .b.@..........ZQ
    468682:I/DEBUG   ( 1940):     515dda38 00000000 4fe429c8 515a1130 00000043  .....).O0.ZQC...
    468683:I/DEBUG   ( 1940):     515dda48 00000001 00000020 20303d78 38333d79  .... ...x=0 y=38
    468684:I/DEBUG   ( 1940):
    468685:I/DEBUG   ( 1940): memory near r3:
    468686:I/DEBUG   ( 1940):     40d88c64 40d880cc 40d88158 40d881cc 40d88208  ...@X..@...@...@
    468687:I/DEBUG   ( 1940):     40d88c74 40d32479 40d34ff5 40d4c1c9 40d48425  y$.@.O.@...@%..@
    468688:I/DEBUG   ( 1940):     40d88c84 00000000 00000000 00000000 4006d318  ...............@
    468689:I/DEBUG   ( 1940):     40d88c94 400565d4 40055cd0 40053540 4005355c  .e.@.\.@@5.@\5.@
    468690:I/DEBUG   ( 1940):     40d88ca4 40056a30 400c27f4 400c2440 400cf1b8  0j.@.'.@@$.@...@
    468691:I/DEBUG   ( 1940):
    468692:I/DEBUG   ( 1940): memory near r6:
    468693:I/DEBUG   ( 1940):     515dda08 402ec934 00000000 41400000 41400000  4..@......@A..@A
    468694:I/DEBUG   ( 1940):     515dda18 40a00000 41400000 41400000 00000023  ...@..@A..@A#...
    468695:I/DEBUG   ( 1940):     515dda28 40d862f0 00000000 0000000d 515a02a8  .b.@..........ZQ
    468696:I/DEBUG   ( 1940):     515dda38 00000000 4fe429c8 515a1130 00000043  .....).O0.ZQC...
    468697:I/DEBUG   ( 1940):     515dda48 00000001 00000020 20303d78 38333d79  .... ...x=0 y=38
    468698:I/DEBUG   ( 1940):
    468699:I/DEBUG   ( 1940): memory near sl:
    468700:I/DEBUG   ( 1940):     56769d7c 55311ec0 5530ff14 55309620 5676d130  ..1U..0U .0U0.vV
    468701:I/DEBUG   ( 1940):     56769d8c 5530ffa4 5530bf90 5530ff18 5530fe6c  ..0U..0U..0Ul.0U
    468702:I/DEBUG   ( 1940):     56769d9c 00000000 00000000 00000000 40072bb8  .............+.@
    468703:I/DEBUG   ( 1940):     56769dac 40072d6c 551e5cc9 55238271 55238569  l-.@.\.Uq.#Ui.#U
    468704:I/DEBUG   ( 1940):     56769dbc 551fc2ed 551d8111 5522c639 55238931  ...U...U9."U1.#U
    468705:I/DEBUG   ( 1940):
    468706:I/DEBUG   ( 1940): memory near sp:
    468707:I/DEBUG   ( 1940):     55e0e2e0 515dda28 40d28bc5 55e0e304 515dda28  (.]Q...@...U(.]Q
    468708:I/DEBUG   ( 1940):     55e0e2f0 00000000 00000000 df0027ad 00000000  .........'......
    468712:I/DEBUG   ( 1940):     55e0e300 515dda28 515a02a8 00000000 59761430  (.]Q..ZQ....0.vY
    468713:I/DEBUG   ( 1940):     55e0e310 515dda28 5674ae6d 566c60fd 00000001  (.]Qm.tV.`lV....
    468714:I/DEBUG   ( 1940):     55e0e320 59761444 551f16ef 1d4007fd 59761430  D.vY...U..@.0.vY
    468715:I/DEBUG   ( 1940):
    468716:I/DEBUG   ( 1940): code around pc:
    468717:I/DEBUG   ( 1940):     40d22530 20064905 44794a05 f7db447a f04fe908  .I. .JyDzD....O.
    468718:I/DEBUG   ( 1940):     40d22540 bd0830ff bd082001 00049c88 0004adfa  .0... ..........
    468719:I/DEBUG   ( 1940):     40d22550 47706880 6805b538 785c69ab f7ff4620  .hpG8..h.i\x F..
    468720:I/DEBUG   ( 1940):     40d22560 b920fd31 e8bd6be8 f7ff4038 4620bd83  1. ..k..8@.... F
    468721:I/DEBUG   ( 1940):     40d22570 0000bd38 4ff7e92d 6883461e 19924614  8...-..O.F.h.F..
    468722:I/DEBUG   ( 1940):
    468723:I/DEBUG   ( 1940): code around lr:
    468724:I/DEBUG   ( 1940):     40d2abf4 4603bd1c 460cb537 4619a801 f7fd4615  ...F7..F...F.F..
    468725:I/DEBUG   ( 1940):     40d2ac04 4621ffc3 f7fe9801 4604fff7 fc9ef7f7  ..!F.......F....
    468726:I/DEBUG   ( 1940):     40d2ac14 fde6f7fd f00a4620 4604f920 2000b10d  .... F.. ..F...
    468727:I/DEBUG   ( 1940):     40d2ac24 a8017028 ffd4f7fd bd3e4620 b5134603  (p...... F>..F..
    468728:I/DEBUG   ( 1940):     40d2ac34 a801460c f7fd4619 4621ffa7 f7fe9801  .F...F....!F....
    
    598331:I/DEBUG   (13426): handle_request(15)
    598332:I/DEBUG   (13426): check process 10283 name:ubinix.konixpoc
    598333:I/DEBUG   (13426): BOOM: pid=10283 uid=10079 gid=10079 tid=10301
    598342:I/DEBUG   (13426): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    598343:I/DEBUG   (13426): Build fingerprint: 'WIKO/wiko/wiko:4.1.2/JZO54K/:user/release-keys'
    598344:I/DEBUG   (13426): pid: 10283, tid: 10301, name: SDLThread  >>> eu.konubinix.konixpoc <<<
    598345:I/DEBUG   (13426): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008
    598378:I/DEBUG   (13426):     r0 00000000  r1 00000000  r2 51577698  r3 40d88c84
    598379:I/DEBUG   (13426):     r4 00000000  r5 00000000  r6 51577698  r7 00000001
    598380:I/DEBUG   (13426):     r8 00000000  r9 00000001  sl 5675ed9c  fp 00000000
    598381:I/DEBUG   (13426):     ip 00000000  sp 5563d1a8  lr 40d2ac15  pc 40d22550  cpsr 60000030
    598382:I/DEBUG   (13426):
    598383:I/DEBUG   (13426): backtrace:
    598384:I/DEBUG   (13426):     #00  pc 00042550  /system/lib/libdvm.so (dvmDbgGetTagWidth(int)+135)
    598385:I/DEBUG   (13426):     #01  pc 0004ac11  /system/lib/libdvm.so
    598386:I/DEBUG   (13426):     #02  pc 00036e6b  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    598387:I/DEBUG   (13426):
    598388:I/DEBUG   (13426): stack:
    598389:I/DEBUG   (13426):          5563d168  00000000
    598390:I/DEBUG   (13426):          5563d16c  00000000
    598391:I/DEBUG   (13426):          5563d170  5563d194  [stack:10301]
    598392:I/DEBUG   (13426):          5563d174  51577658
    598393:I/DEBUG   (13426):          5563d178  40d71ffb  /system/lib/libdvm.so
    598394:I/DEBUG   (13426):          5563d17c  0000000d
    598395:I/DEBUG   (13426):          5563d180  5563d1ac  [stack:10301]
    598396:I/DEBUG   (13426):          5563d184  00000000
    598397:I/DEBUG   (13426):          5563d188  51577698
    598398:I/DEBUG   (13426):          5563d18c  40d28bc5  /system/lib/libdvm.so
    598399:I/DEBUG   (13426):          5563d190  5563d1ac  [stack:10301]
    598400:I/DEBUG   (13426):          5563d194  51577698
    598401:I/DEBUG   (13426):          5563d198  00000000
    598402:I/DEBUG   (13426):          5563d19c  00000000
    598403:I/DEBUG   (13426):          5563d1a0  df0027ad
    598404:I/DEBUG   (13426):          5563d1a4  00000000
    598405:I/DEBUG   (13426):     #00  5563d1a8  51577698
    598406:I/DEBUG   (13426):          ........  ........
    598407:I/DEBUG   (13426):     #01  5563d1a8  51577698
    598408:I/DEBUG   (13426):          5563d1ac  50cb30e0
    598409:I/DEBUG   (13426):          5563d1b0  00000000
    598410:I/DEBUG   (13426):          5563d1b4  598abe80
    598411:I/DEBUG   (13426):          5563d1b8  51577698
    598412:I/DEBUG   (13426):          5563d1bc  5673fe6d  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    598413:I/DEBUG   (13426):     #02  5563d1c0  566ba0fd
    598414:I/DEBUG   (13426):          5563d1c4  00000001
    598415:I/DEBUG   (13426):          5563d1c8  598abe94
    598416:I/DEBUG   (13426):          5563d1cc  5230d6ef  /data/data/eu.konubinix.konixpoc/lib/libpython2.7.so (PyString_FromStringAndSize+166)
    598417:I/DEBUG   (13426):          5563d1d0  1d3007fd
    598418:I/DEBUG   (13426):          5563d1d4  598abe80
    598419:I/DEBUG   (13426):          5563d1d8  566ba0e8
    598420:I/DEBUG   (13426):          5563d1dc  51577698
    598421:I/DEBUG   (13426):          5563d1e0  00000001
    598422:I/DEBUG   (13426):          5563d1e4  00000000
    598423:I/DEBUG   (13426):          5563d1e8  00000001
    598424:I/DEBUG   (13426):          5563d1ec  5675ed9c  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    598425:I/DEBUG   (13426):          5563d1f0  00000000
    598426:I/DEBUG   (13426):          5563d1f4  5673c565  /data/data/eu.konubinix.konixpoc/files/app/lib/python2.7/site-packages/jnius/jnius.so
    598427:I/DEBUG   (13426):          5563d1f8  40d8f0a0
    598428:I/DEBUG   (13426):          5563d1fc  40d28761  /system/lib/libdvm.so
    598429:I/DEBUG   (13426):
    598430:I/DEBUG   (13426): memory near r2:
    598431:I/DEBUG   (13426):     51577678 0000283d 00000000 00000000 00000000  =(..............
    598432:I/DEBUG   (13426):     51577688 00000001 00000000 5563ef00 00000023  ..........cU#...
    598433:I/DEBUG   (13426):     51577698 40d862f0 00000000 0000000d 50cb30e0  .b.@.........0.P
    598434:I/DEBUG   (13426):     515776a8 00000000 515a06f8 4fe47790 0000001b  ......ZQ.w.O....
    598435:I/DEBUG   (13426):     515776b8 48545950 4e5f4e4f 3d454d41 68747970  PYTHON_NAME=pyth
    598436:I/DEBUG   (13426):
    598437:I/DEBUG   (13426): memory near r3:
    598438:I/DEBUG   (13426):     40d88c64 40d880cc 40d88158 40d881cc 40d88208  ...@X..@...@...@
    598439:I/DEBUG   (13426):     40d88c74 40d32479 40d34ff5 40d4c1c9 40d48425  y$.@.O.@...@%..@
    598440:I/DEBUG   (13426):     40d88c84 00000000 00000000 00000000 4006d318  ...............@
    598441:I/DEBUG   (13426):     40d88c94 400565d4 40055cd0 40053540 4005355c  .e.@.\.@@5.@\5.@
    598442:I/DEBUG   (13426):     40d88ca4 40056a30 400c27f4 400c2440 400cf1b8  0j.@.'.@@$.@...@
    598443:I/DEBUG   (13426):
    598444:I/DEBUG   (13426): memory near r6:
    598445:I/DEBUG   (13426):     51577678 0000283d 00000000 00000000 00000000  =(..............
    598446:I/DEBUG   (13426):     51577688 00000001 00000000 5563ef00 00000023  ..........cU#...
    598447:I/DEBUG   (13426):     51577698 40d862f0 00000000 0000000d 50cb30e0  .b.@.........0.P
    598448:I/DEBUG   (13426):     515776a8 00000000 515a06f8 4fe47790 0000001b  ......ZQ.w.O....
    598449:I/DEBUG   (13426):     515776b8 48545950 4e5f4e4f 3d454d41 68747970  PYTHON_NAME=pyth
    598450:I/DEBUG   (13426):
    598451:I/DEBUG   (13426): memory near sl:
    598452:I/DEBUG   (13426):     5675ed7c 5242dec0 5242bf14 52425620 56762130  ..BR..BR VBR0!vV
    598453:I/DEBUG   (13426):     5675ed8c 5242bfa4 52427f90 5242bf18 5242be6c  ..BR..BR..BRl.BR
    598454:I/DEBUG   (13426):     5675ed9c 00000000 00000000 00000000 40072bb8  .............+.@
    598455:I/DEBUG   (13426):     5675edac 40072d6c 52301cc9 52354271 52354569  l-.@..0RqB5RiE5R
    598456:I/DEBUG   (13426):     5675edbc 523182ed 522f4111 52348639 52354931  ..1R.A/R9.4R1I5R
    598457:I/DEBUG   (13426):
    598458:I/DEBUG   (13426): memory near sp:
    598459:I/DEBUG   (13426):     5563d188 51577698 40d28bc5 5563d1ac 51577698  .vWQ...@..cU.vWQ
    598460:I/DEBUG   (13426):     5563d198 00000000 00000000 df0027ad 00000000  .........'......
    598461:I/DEBUG   (13426):     5563d1a8 51577698 50cb30e0 00000000 598abe80  .vWQ.0.P.......Y
    598462:I/DEBUG   (13426):     5563d1b8 51577698 5673fe6d 566ba0fd 00000001  .vWQm.sV..kV....
    598463:I/DEBUG   (13426):     5563d1c8 598abe94 5230d6ef 1d3007fd 598abe80  ...Y..0R..0....Y
    598464:I/DEBUG   (13426):
    598465:I/DEBUG   (13426): code around pc:
    598466:I/DEBUG   (13426):     40d22530 20064905 44794a05 f7db447a f04fe908  .I. .JyDzD....O.
    598467:I/DEBUG   (13426):     40d22540 bd0830ff bd082001 00049c88 0004adfa  .0... ..........
    598468:I/DEBUG   (13426):     40d22550 47706880 6805b538 785c69ab f7ff4620  .hpG8..h.i\x F..
    598469:I/DEBUG   (13426):     40d22560 b920fd31 e8bd6be8 f7ff4038 4620bd83  1. ..k..8@.... F
    598470:I/DEBUG   (13426):     40d22570 0000bd38 4ff7e92d 6883461e 19924614  8...-..O.F.h.F..
    598471:I/DEBUG   (13426):
    598472:I/DEBUG   (13426): code around lr:
    598473:I/DEBUG   (13426):     40d2abf4 4603bd1c 460cb537 4619a801 f7fd4615  ...F7..F...F.F..
    598474:I/DEBUG   (13426):     40d2ac04 4621ffc3 f7fe9801 4604fff7 fc9ef7f7  ..!F.......F....
    598475:I/DEBUG   (13426):     40d2ac14 fde6f7fd f00a4620 4604f920 2000b10d  .... F.. ..F...
    598476:I/DEBUG   (13426):     40d2ac24 a8017028 ffd4f7fd bd3e4620 b5134603  (p...... F>..F..
    598477:I/DEBUG   (13426):     40d2ac34 a801460c f7fd4619 4621ffa7 f7fe9801  .F...F....!F....
    
     ↩︎
  2. 22917:08-04 16:50:01.500 18291 18315 I python  : [DEBUG  ] 2025-08-04 16:50:01,499 - app.nightlight - su: settings put global airplane_mode_on 0
    22918:08-04 16:50:01.515 18291 18315 I python  : [INFO   ] 2025-08-04 16:50:01,514 - kivy - Base: Leaving application in progress...
    22929:08-04 16:50:01.591 18291 18315 I python  :  Traceback (most recent call last):
    22930:08-04 16:50:01.593 18291 18315 I python  :    File "/app/.buildozer/android/app/main.py", line 14, in <module>
    22933:08-04 16:50:01.602 18291 18315 I python  :    File "/storage/emulated/0/poc/poc.py", line 15, in main
    22934:08-04 16:50:01.606 18291 18315 I python  :      main.run()
    22935:08-04 16:50:01.608 18291 18315 I python  :    File "/storage/emulated/0/poc/app/main.py", line 453, in run
    22936:08-04 16:50:01.612 18291 18315 I python  :      MainApp().run()
    22937:08-04 16:50:01.614 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/app.py", line 956, in run
    22938:08-04 16:50:01.617 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/base.py", line 574, in runTouchApp
    22939:08-04 16:50:01.620 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/base.py", line 339, in mainloop
    22940:08-04 16:50:01.623 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/base.py", line 379, in idle
    22941:08-04 16:50:01.627 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/clock.py", line 733, in tick
    22942:08-04 16:50:01.631 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/python-installs/konixpoc/armeabi-v7a/kivy/clock.py", line 776, in post_idle
    22943:08-04 16:50:01.633 18291 18315 I python  :    File "kivy/_clock.pyx", line 620, in kivy._clock.CyClockBase._process_events
    22948:08-04 16:50:01.636 18291 18315 I python  :    File "kivy/_clock.pyx", line 653, in kivy._clock.CyClockBase._process_events
    22949:08-04 16:50:01.638 18291 18315 I python  :    File "kivy/_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events
    22951:08-04 16:50:01.641 18291 18315 I python  :    File "kivy/_clock.pyx", line 218, in kivy._clock.ClockEvent.tick
    22952:08-04 16:50:01.644 18291 18315 I python  :    File "/storage/emulated/0/poc/app/nightlight.py", line 720, in evening
    22954:08-04 16:50:01.648 18291 18315 I python  :      wake_n_notify("evening, next at {:02}:{:02}".format(self.night_hour, self.night_minute))
    22955:08-04 16:50:01.650 18291 18315 I python  :    File "/storage/emulated/0/poc/app/nightlight.py", line 171, in wake_n_notify
    22956:08-04 16:50:01.653 18291 18315 I python  :      set_wifi_enabled(True)
    22957:08-04 16:50:01.654 18291 18315 I python  :    File "/storage/emulated/0/poc/app/nightlight.py", line 154, in set_wifi_enabled
    22958:08-04 16:50:01.656 18291 18315 I python  :      su("settings put global airplane_mode_on {}".format("0" if enable else "1"))
    22959:08-04 16:50:01.657 18291 18315 I python  :    File "/storage/emulated/0/poc/app/nightlight.py", line 147, in su
    22960:08-04 16:50:01.660 18291 18315 I python  :      call(["su", "-c", cmd])
    22961:08-04 16:50:01.662 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/subprocess.py", line 389, in call
    22962:08-04 16:50:01.664 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/subprocess.py", line 1026, in __init__
    22963:08-04 16:50:01.666 18291 18315 I python  :    File "/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/subprocess.py", line 1849, in _execute_child
    22964:08-04 16:50:01.669 18291 18315 I python  :  OSError: [Errno 24] Too many open files
    22965:08-04 16:50:01.669 18291 18315 I python  : Python for android ended.
    
     ↩︎