DarkMode

Post Reply
ElmodiLatta
Posts: 21
Joined: Mon Sep 15, 2025 10:11 am
Location: Italy

DarkMode

Post by ElmodiLatta »

Hi, I'm trying to understand how the DarkMode.py example changes state every 10 seconds based on
self._timer = threading.Timer(10, self.toggle_dark_mode, [client]).
Does deleting the timer and changing the value from zero to one in the "client.send(hudiy_api.MESSAGE_SET_DARK_MODE, 0" line still make the change?
I'd like to activate it based on a message from the CAN-BUS about the light status.
Thanks
noobychris
Posts: 25
Joined: Fri Aug 15, 2025 5:06 pm
Location: Germany
Contact:

Re: DarkMode

Post by noobychris »

Hello ElmodiLatta,

please check that one:

https://github.com/wiboma/hudiy/blob/ma ... proto#L686

// Id: MESSAGE_SET_DARK_MODE
// Receiver: Hudiy
// Description: Controls dark and light themes.
message SetDarkMode {
required bool enabled = 1;
}

if you break down that to a single line command it would be:

# Day (enabled = False)

Code: Select all

self.client.send(api.MESSAGE_SET_DARK_MODE, 0, api.SetDarkMode(enabled=False).SerializeToString())
# Night (enabled = True)

Code: Select all

self.client.send(api.MESSAGE_SET_DARK_MODE, 0, api.SetDarkMode(enabled=True).SerializeToString())

I am using also can bus for speed, rpm, light etc and added this functions to the eventhandler class:

Code: Select all

def _resolve_day_mode_for_toggle(self) -> bool:

	if getattr(self, "_is_day_mode", None) is not None:
		return self._is_day_mode

	# If you want an initial system/app default, change this to False for Night.
	return True

Code: Select all

def send_day_night(self, mode: str) -> None:
    try:
        # --- Determine / toggle mode ----------------------------------------
        if mode == "toggle":
            base_is_day = self._resolve_day_mode_for_toggle()
            is_day_mode = not base_is_day
        elif mode in ("day", "night"):
            is_day_mode = (mode == "day")
        else:
            raise ValueError("Invalid mode. Use 'day', 'night' or 'toggle'.")

        # Update cache
        self._is_day_mode = is_day_mode

        # --- Check if transport is available --------------------------------
        has_transport = (
            getattr(self.client, "_socket", None) is not None
        ) or (
            getattr(self.client, "_websocket", None) is not None
        )
        if not (api_is_connected and has_transport):
            if ENABLE_LOGGING:
                logger.warning("Client not connected – skipping send_day_night.")
            return

        # --- Send depending on backend --------------------------------------
        if backend == "Hudiy":
            # Hudiy expects SetDarkMode(enabled)
            # Mapping: day -> enabled=False, night -> enabled=True
            enabled = not is_day_mode
            if ENABLE_LOGGING:
                logger.info("Sending dark mode to Hudiy: enabled=%s", enabled)

            msg = api.SetDarkMode()
            msg.enabled = enabled
            self.client.send(api.MESSAGE_SET_DARK_MODE, 0, msg.SerializeToString())

And on the can bus part side of the script:

Code: Select all

last_msg_635 = None
light_status = None

@handle_errors
async def process_canid_635(msg):
    global light_status, last_msg_635

    # Check if this is the first received message
    first_message = last_msg_635 is None

    if first_message or msg != last_msg_635:
        # Extract byte 2 (light status from CAN)
        light_value = int(msg[2:4], 16)

        # Determine new status (0 = off, 1 = on)
        if light_value > 0:
            new_light_status = 1
        else:
            new_light_status = 0

        # If first run or status has changed -> set mode
        if first_message or (new_light_status != light_status):
            if change_dark_mode_by_car_light and api_is_connected:
                if new_light_status == 1:
                    mode = "night"
                else:
                    mode = "day"

                logger.info(f"Light status changed: Setting {mode} mode immediately.")
                event_handler.send_day_night(mode)

        # Update cached values
        light_status = new_light_status
        last_msg_635 = msg

If you want to toggle like i do with a specific key:

Code: Select all

event_handler.send_day_night("toggle")
If you want to send a initial state like i do, set this variable in the upper section of your script:

Code: Select all

initial_day_night_mode = 'night'  
or

Code: Select all

initial_day_night_mode = 'day'  

And put this in your "on_hello_response" from the EventHandler:

Code: Select all

            # 🌗 Initial Day/Night Mode (bei dir aktuell auskommentiert)
            if initial_day_night_mode == "day":
                self.send_day_night('day')
                pass
            else:
                self.send_day_night('night')
                pass
ElmodiLatta
Posts: 21
Joined: Mon Sep 15, 2025 10:11 am
Location: Italy

Re: DarkMode

Post by ElmodiLatta »

Thanks for all this information, some things with OpenAuto Pro were already done, here everything is a bit more complex for me as I am not very experienced in programming, I will read all the documentation calmly, with Arduino I read the CAN-BUS messages and then send the data via serial to the Raspberry, for now the rear camera works, the safe shutdown of the Raspberry when I turn off the car for the steering wheel controls I already have a few ideas I was just missing the light/dark part thanks again
Post Reply