From 527f872b2b1ff83e47fe8ffeba37328efa52d1d8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Nov 2025 02:10:13 +0000 Subject: [PATCH 1/4] Update downstream dependencies for ovos-bus-client --- downstream_report.txt | 67 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/downstream_report.txt b/downstream_report.txt index 8814f3d..711675c 100644 --- a/downstream_report.txt +++ b/downstream_report.txt @@ -1,10 +1,10 @@ -ovos-bus-client==1.3.6a1 -├── ovos_wikipedia_solver==0.1.2 [requires: ovos-bus-client>=1.0.1] +ovos_bus_client==1.3.7 +├── ovos_wikipedia_solver==0.1.2 [requires: ovos_bus_client>=1.0.1] │ └── ovos-skill-wikipedia==0.8.13 [requires: ovos_wikipedia_solver>=0.0.1,<1.0.0] -├── ovos_gui==1.3.4 [requires: ovos-bus-client>=1.0.0,<2.0.0] -├── ovos_audio==1.1.0 [requires: ovos-bus-client>=0.0.8,<2.0.0] +├── ovos_gui==1.3.4 [requires: ovos_bus_client>=1.0.0,<2.0.0] +├── ovos_audio==1.1.0 [requires: ovos_bus_client>=0.0.8,<2.0.0] │ └── ovos-skill-laugh==0.2.3 [requires: ovos_audio] -├── ovos-workshop==7.0.9a1 [requires: ovos-bus-client>=0.0.8,<2.0.0] +├── ovos-workshop==7.0.9a1 [requires: ovos_bus_client>=0.0.8,<2.0.0] │ ├── ovos-skill-screenshot==0.0.7 [requires: ovos-workshop] │ ├── ovos-skill-fallback-unknown==0.1.9 [requires: ovos-workshop>=6.0.0,<8.0.0] │ ├── ovos-skill-parrot==0.1.26a1 [requires: ovos-workshop>=7.0.0,<8.0.0] @@ -51,18 +51,18 @@ ovos-bus-client==1.3.6a1 │ ├── ovos-skill-wikipedia==0.8.13 [requires: ovos-workshop>=3.4.0,<8.0.0] │ ├── ovos-skill-moviemaster==0.0.12 [requires: ovos-workshop>=0.0.11,<8.0.0] │ └── ovos-skill-days-in-history==0.3.11 [requires: ovos-workshop>=3.1.0,<8.0.0] -├── ovos_PHAL_plugin_system==1.3.4 [requires: ovos-bus-client>=1.1.0,<2.0.0] -├── ovos_common_query_pipeline_plugin==1.1.9 [requires: ovos-bus-client] -├── ovos-skill-laugh==0.2.3 [requires: ovos-bus-client>=1.0.1] -├── ovos-skill-local-media==0.2.13a1 [requires: ovos-bus-client>=0.0.9,<2.0.0] -├── ovos-skill-pyradios==0.1.5 [requires: ovos-bus-client>=0.0.9] -├── ovos_core==2.1.1 [requires: ovos-bus-client>=1.3.6a1,<2.0.0] +├── ovos_PHAL_plugin_system==1.3.4 [requires: ovos_bus_client>=1.1.0,<2.0.0] +├── ovos_common_query_pipeline_plugin==1.1.9 [requires: ovos_bus_client] +├── ovos-skill-laugh==0.2.3 [requires: ovos_bus_client>=1.0.1] +├── ovos-skill-local-media==0.2.13a1 [requires: ovos_bus_client>=0.0.9,<2.0.0] +├── ovos-skill-pyradios==0.1.5 [requires: ovos_bus_client>=0.0.9] +├── ovos_core==2.1.1 [requires: ovos_bus_client>=1.3.6a1,<2.0.0] │ └── ovoscope==0.7.2 [requires: ovos_core>=2.0.4a2] -├── ovos_m2v_pipeline==0.0.7 [requires: ovos-bus-client] -├── ovos_PHAL_plugin_wallpaper_manager==0.2.6 [requires: ovos-bus-client>=0.0.3,<2.0.0] -├── ovos_ww_plugin_vosk==0.1.8 [requires: ovos-bus-client>=0.0.6] -├── ovos-PHAL-plugin-oauth==0.1.3 [requires: ovos-bus-client>=0.0.3,<2.0.0] -├── ovos-plugin-manager==1.0.4a2 [requires: ovos-bus-client>=0.0.8,<2.0.0] +├── ovos_m2v_pipeline==0.0.7 [requires: ovos_bus_client] +├── ovos_PHAL_plugin_wallpaper_manager==0.2.6 [requires: ovos_bus_client>=0.0.3,<2.0.0] +├── ovos_ww_plugin_vosk==0.1.8 [requires: ovos_bus_client>=0.0.6] +├── ovos-PHAL-plugin-oauth==0.1.3 [requires: ovos_bus_client>=0.0.3,<2.0.0] +├── ovos-plugin-manager==1.0.4a2 [requires: ovos_bus_client>=0.0.8,<2.0.0] │ ├── ovos-stt-plugin-citrinet==0.0.9 [requires: ovos-plugin-manager>=1.0.0,<2.0.0] │ ├── ovos-ocp-m3u-plugin==0.0.2a2 [requires: ovos-plugin-manager] │ │ └── ovos-ocp-news-plugin==0.1.2 [requires: ovos-ocp-m3u-plugin>=0.0.1,<1.0.0] @@ -201,27 +201,28 @@ ovos-bus-client==1.3.6a1 │ ├── ovos-PHAL-plugin-mk2-fan-control==0.0.1 [requires: ovos-plugin-manager>=0.0.1] │ ├── ovos-stt-plugin-fasterwhisper==0.0.1a8 [requires: ovos-plugin-manager>=0.0.23a10] │ ├── ovos_phal_plugin_connectivity_events==0.1.3 [requires: ovos-plugin-manager>=0.0.21,<3.0.0] +│ ├── ovos-stt-plugin-whisper==0.1.4 [requires: ovos-plugin-manager>=0.0.26,<3.0.0] │ ├── ovos_solver_failure_plugin==0.0.3 [requires: ovos-plugin-manager>=0.0.26,<3.0.0] │ │ └── ovos_persona==0.6.24 [requires: ovos_solver_failure_plugin] │ ├── ovos_tts_plugin_server==0.0.5a1 [requires: ovos-plugin-manager>=1.0.0,<3.0.0] │ ├── ovos-stt-plugin-nos==0.2.0 [requires: ovos-plugin-manager>=0.0.24] │ ├── ovos-tts-plugin-pico==0.0.4a2 [requires: ovos-plugin-manager>=0.0.1a12] │ └── ovos_utterance_corrections_plugin==0.1.2 [requires: ovos-plugin-manager>=0.0.1,<3.0.0] -├── ovos-skill-naptime==0.3.16a1 [requires: ovos-bus-client>=1.2.0,<2.0.0] -├── ovos_plugin_common_play==1.2.2a1 [requires: ovos-bus-client>=0.0.7,<2.0.0] -├── ovos_PHAL_plugin_alsa==0.1.5 [requires: ovos-bus-client>=0.0.4,<2.0.0] -├── ovos-skill-alerts==0.1.28a1 [requires: ovos-bus-client>=0.0.3,<2.0.0] -├── ovos-dinkum-listener==0.5.1a1 [requires: ovos-bus-client>=1.3.4,<2.0.0] -├── ovos-skill-iss-location==0.2.16 [requires: ovos-bus-client>=1.0.1] -├── ovos_PHAL==0.2.11 [requires: ovos-bus-client>=0.0.8,<2.0.0] -├── ovos-skill-somafm==0.1.6a1 [requires: ovos-bus-client>=0.1.0] -├── ovos_gui_plugin_shell_companion==1.0.6 [requires: ovos-bus-client>=0.0.8,<2.0.0] -├── ovos-skill-homescreen==3.0.3 [requires: ovos-bus-client>=1.0.0,<2.0.0] -├── ovos-PHAL-plugin-balena-wifi==1.2.2 [requires: ovos-bus-client>=0.0.6,<2.0.0] -├── ovos-skill-news==0.4.6a1 [requires: ovos-bus-client>=0.0.9,<2.0.0] -├── ovos_phal_plugin_connectivity_events==0.1.3 [requires: ovos-bus-client>=0.0.3,<2.0.0] -├── ovos-skill-confucius-quotes==0.1.13 [requires: ovos-bus-client>=1.0.1] -├── ovos-skill-youtube-music==0.1.7 [requires: ovos-bus-client>=0.0.9] -├── ovos-messagebus==0.0.11a1 [requires: ovos-bus-client>=0.0.7,<2.0.0] -└── ovos-mark1-utils==0.0.1 [requires: ovos-bus-client] +├── ovos-skill-naptime==0.3.16a1 [requires: ovos_bus_client>=1.2.0,<2.0.0] +├── ovos_plugin_common_play==1.2.2a1 [requires: ovos_bus_client>=0.0.7,<2.0.0] +├── ovos_PHAL_plugin_alsa==0.1.5 [requires: ovos_bus_client>=0.0.4,<2.0.0] +├── ovos-skill-alerts==0.1.28a1 [requires: ovos_bus_client>=0.0.3,<2.0.0] +├── ovos-dinkum-listener==0.5.1a1 [requires: ovos_bus_client>=1.3.4,<2.0.0] +├── ovos-skill-iss-location==0.2.16 [requires: ovos_bus_client>=1.0.1] +├── ovos_PHAL==0.2.11 [requires: ovos_bus_client>=0.0.8,<2.0.0] +├── ovos-skill-somafm==0.1.6a1 [requires: ovos_bus_client>=0.1.0] +├── ovos_gui_plugin_shell_companion==1.0.6 [requires: ovos_bus_client>=0.0.8,<2.0.0] +├── ovos-skill-homescreen==3.0.3 [requires: ovos_bus_client>=1.0.0,<2.0.0] +├── ovos-PHAL-plugin-balena-wifi==1.2.2 [requires: ovos_bus_client>=0.0.6,<2.0.0] +├── ovos-skill-news==0.4.6a1 [requires: ovos_bus_client>=0.0.9,<2.0.0] +├── ovos_phal_plugin_connectivity_events==0.1.3 [requires: ovos_bus_client>=0.0.3,<2.0.0] +├── ovos-skill-confucius-quotes==0.1.13 [requires: ovos_bus_client>=1.0.1] +├── ovos-skill-youtube-music==0.1.7 [requires: ovos_bus_client>=0.0.9] +├── ovos-messagebus==0.0.11a1 [requires: ovos_bus_client>=0.0.7,<2.0.0] +└── ovos-mark1-utils==0.0.1 [requires: ovos_bus_client] └── ovos-PHAL-plugin-mk1==0.1.3 [requires: ovos-mark1-utils>=0.0.1] From d9c88677d870cf4aa20de4e80772ca2644d11eba Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Sun, 9 Nov 2025 16:11:39 +0000 Subject: [PATCH 2/4] refactor: migrate bus api client to ovos-bus-client package (#177) * refactor: migrate bus api client to ovos-bus-client package * fix: ttestts * fix: mock test --- .github/workflows/unit_tests.yml | 9 +- ovos_bus_client/apis/events.py | 229 +++++++++++++++++++++++++ ovos_bus_client/session.py | 7 + ovos_bus_client/util/scheduler.py | 41 ++--- test/unittests/test_event_scheduler.py | 7 +- 5 files changed, 258 insertions(+), 35 deletions(-) create mode 100644 ovos_bus_client/apis/events.py diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 8b35717..bd2c85e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -32,7 +32,7 @@ jobs: unit_tests: strategy: matrix: - python-version: [3.9, "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -62,10 +62,3 @@ jobs: run: | pip install -U "pyee==8.1.0" pytest --cov=ovos_bus_client --cov-report=xml --cov-append test/unittests - - name: Upload coverage - if: "${{ matrix.python-version == '3.9' }}" - uses: codecov/codecov-action@v5 - with: - token: ${{secrets.CODECOV_TOKEN}} - files: coverage.xml - verbose: true diff --git a/ovos_bus_client/apis/events.py b/ovos_bus_client/apis/events.py new file mode 100644 index 0000000..7a8d6e0 --- /dev/null +++ b/ovos_bus_client/apis/events.py @@ -0,0 +1,229 @@ +import time +from datetime import datetime, timedelta +from typing import Callable, Optional, Union + +from ovos_utils.events import EventContainer, create_basic_wrapper +from ovos_bus_client.message import Message, dig_for_message +from ovos_utils.log import LOG +from ovos_config.locale import get_default_tz +from ovos_utils.time import now_local + + +class EventSchedulerInterface: + """Interface for accessing the event scheduler over the message bus.""" + + def __init__(self, bus=None, skill_id=None): + self.skill_id = skill_id or self.__class__.__name__.lower() + self.bus = bus + self.events = EventContainer(bus) + self.scheduled_repeats = [] + + def set_bus(self, bus): + """Attach the messagebus of the parent skill + + Args: + bus (MessageBusClient): websocket connection to the messagebus + """ + self.bus = bus + self.events.set_bus(bus) + + def set_id(self, skill_id: str): + """ + Attach the skill_id of the parent skill + + Args: + skill_id (str): skill_id of the parent skill + """ + self.skill_id = skill_id + + def _get_source_message(self): + message = dig_for_message() or Message("") + message.context['skill_id'] = self.skill_id + return message + + def _create_unique_name(self, name: str) -> str: + """ + Return a name unique to this skill using the format [skill_id]:[name]. + @param name: Name to use internally + @return name unique to this skill + """ + # TODO: Is a null name valid or should it raise an exception? + return self.skill_id + ':' + (name or '') + + def _schedule_event(self, handler: Callable[..., None], + when: Union[datetime, int, float], + data: Optional[dict], + name: Optional[str], + repeat_interval: Optional[Union[float, int]] = None, + context: Optional[dict] = None): + """ + Underlying method for schedule_event and schedule_repeating_event. + Takes scheduling information and sends it off on the message bus. + @param handler: method to be called at the scheduled time(s) + @param when: time (tzaware or default to system tz) or delta seconds to + first call the handler + @param data: Message data to send to `handler + @param name: Event name, must be unique in the context of this object + @param repeat_interval: time in seconds between calls + @param context: Message context to send to `handler` + + """ + if isinstance(when, (int, float)): + if when < 0: + raise ValueError(f"Expected datetime or positive int/float. " + f"got: {when}") + when = now_local() + timedelta(seconds=when) + if not isinstance(when, datetime): + raise TypeError(f"Expected datetime, int, or float but got: {when}") + if when.tzinfo is None: + # ensure correct timezone before conversion to unix timestamp + # naive datetime objects method relies on the platform C mktime() function to perform the conversion + # and may not match mycroft.conf + when = when.replace(tzinfo=get_default_tz()) + if not name: + name = self.skill_id + handler.__name__ + unique_name = self._create_unique_name(name) + if repeat_interval: + self.scheduled_repeats.append(name) # store "friendly name" + + data = data or {} + + def on_error(e): + LOG.exception(f'An error occurred executing the scheduled event: ' + f'{e}') + + wrapped = create_basic_wrapper(handler, on_error) + self.events.add(unique_name, wrapped, once=not repeat_interval) + event_data = {'time': when.timestamp(), # Epoch timestamp + 'event': unique_name, + 'repeat': repeat_interval, + 'data': data} + + message = self._get_source_message() + context = context or message.context + context["skill_id"] = self.skill_id + self.bus.emit(Message('mycroft.scheduler.schedule_event', + data=event_data, context=context)) + + def schedule_event(self, handler: Callable[..., None], + when: Union[datetime, int, float], + data: Optional[dict] = None, + name: Optional[str] = None, + context: Optional[dict] = None): + """ + Schedule a single-shot event. + @param handler: method to be called at the scheduled time(s) + @param when: time (tzaware or default to system tz) or delta seconds + to first call the handler + @param data: Message data to send to `handler + @param name: Event name, must be unique in the context of this object + @param context: Message context to send to `handler` + """ + self._schedule_event(handler, when, data, name, context=context) + + def schedule_repeating_event(self, + handler: Callable[..., None], + when: Optional[Union[datetime, int, float]], + interval: Union[float, int], + data: Optional[dict] = None, + name: Optional[str] = None, + context: Optional[dict] = None): + """ + Schedule a repeating event. + @param handler: method to be called at the scheduled time(s) + @param when: time (tzaware or default to system tz) or delta seconds to + first call the handler. If None, first call is in `repeat_interval` + @param data: Message data to send to `handler + @param name: Event name, must be unique in the context of this object + @param interval: time in seconds between calls + @param context: Message context to send to `handler` + """ + # Ensure name is defined to avoid re-scheduling + name = name or self.skill_id + handler.__name__ + + # Do not schedule if this event is already scheduled by the skill + if name not in self.scheduled_repeats: + # If only interval is given set to trigger in [interval] seconds + # from now. + if not when: + when = now_local() + timedelta(seconds=interval) + self._schedule_event(handler, when, data, name, interval, context) + else: + LOG.debug('The event is already scheduled, cancel previous ' + 'event if this scheduling should replace the last.') + + def update_scheduled_event(self, name: str, data: Optional[dict] = None): + """ + Change data of event. + + Args: + name (str): reference name of event (from original scheduling) + data (dict): new data to update event with + """ + data = { + 'event': self._create_unique_name(name), + 'data': data or {} + } + message = self._get_source_message() + self.bus.emit(message.forward('mycroft.schedule.update_event', data)) + + def cancel_scheduled_event(self, name: str): + """ + Cancel a pending event. The event will no longer be scheduled. + + Args: + name (str): reference name of event (from original scheduling) + """ + unique_name = self._create_unique_name(name) + data = {'event': unique_name} + if name in self.scheduled_repeats: + self.scheduled_repeats.remove(name) + if self.events.remove(unique_name): + message = self._get_source_message() + self.bus.emit(message.forward('mycroft.scheduler.remove_event', data)) + + def get_scheduled_event_status(self, name: str) -> int: + """ + Get scheduled event data and return the amount of time left + + Args: + name (str): reference name of event (from original scheduling) + + Returns: + int: the time left in seconds + + Raises: + Exception: Raised if event is not found + """ + event_name = self._create_unique_name(name) + data = {'name': event_name} + + reply_name = f'mycroft.event_status.callback.{event_name}' + message = self._get_source_message() + msg = message.forward('mycroft.scheduler.get_event', data) + status = self.bus.wait_for_response(msg, reply_type=reply_name) + + if status: + event_time = int(status.data[0][0]) + current_time = int(time.time()) + time_left_in_seconds = event_time - current_time + LOG.info(time_left_in_seconds) + return time_left_in_seconds + else: + raise Exception("Event Status Messagebus Timeout") + + def cancel_all_repeating_events(self): + """ + Cancel any repeating events started by the skill. + """ + # NOTE: Gotta make a copy of the list due to the removes that happen + # in cancel_scheduled_event(). + for e in list(self.scheduled_repeats): + self.cancel_scheduled_event(e) + + def shutdown(self): + """ + Shutdown the interface unregistering any event handlers. + """ + self.cancel_all_repeating_events() + self.events.clear() diff --git a/ovos_bus_client/session.py b/ovos_bus_client/session.py index 1305cc7..8c3b1a3 100644 --- a/ovos_bus_client/session.py +++ b/ovos_bus_client/session.py @@ -330,6 +330,13 @@ def __init__(self, session_id: str = None, self.location_preferences = location_prefs or Configuration().get("location", {}) + @property + def timezone(self) -> Optional[str]: + """ + Get the timezone code, such as 'America/Los_Angeles' + """ + return self.location_preferences.get('timezone', {}).get('code') + @property def active(self) -> bool: """ diff --git a/ovos_bus_client/util/scheduler.py b/ovos_bus_client/util/scheduler.py index 0353797..cdc9342 100644 --- a/ovos_bus_client/util/scheduler.py +++ b/ovos_bus_client/util/scheduler.py @@ -30,7 +30,7 @@ from ovos_config.config import Configuration from ovos_config.locations import get_xdg_data_save_path, get_xdg_config_save_path from ovos_utils.log import LOG - +from ovos_utils.time import now_local from ovos_bus_client.message import Message @@ -71,12 +71,10 @@ def __init__(self, bus, schedule_file: str = 'schedule.json', autostart: bool = self.event_lock = Lock() # to check if its our first connection to the internet via clock_skew - self._last_sync = time.time() + self._last_sync: datetime.datetime = now_local() self._dropped_events = 0 - self._past_date = datetime.datetime(day=1, month=12, year=2024) - # Convert Unix timestamp to human-readable datetime - pretty_last_sync = datetime.datetime.fromtimestamp(self._last_sync).strftime("%Y-%m-%d %H:%M:%S") - LOG.debug(f"Boot time clock: {pretty_last_sync}") + self._past_date = datetime.datetime(day=1, month=12, year=2024, tzinfo=self._last_sync.tzinfo) + LOG.debug(f"Boot time clock: {self._last_sync}") self.bus = bus @@ -91,11 +89,11 @@ def __init__(self, bus, schedule_file: str = 'schedule.json', autostart: bool = if self.schedule_file: self.load() - self.bus.on('mycroft.scheduler.schedule_event', self.schedule_event_handler) - self.bus.on('mycroft.scheduler.remove_event', self.remove_event_handler) - self.bus.on('mycroft.scheduler.update_event', self.update_event_handler) - self.bus.on('mycroft.scheduler.get_event', self.get_event_handler) - self.bus.on('mycroft.scheduler.list_events', self.list_events_handler) + self.bus.on('mycroft.scheduler.schedule_event', self.handle_schedule_event) + self.bus.on('mycroft.scheduler.remove_event', self.handle_remove_event) + self.bus.on('mycroft.scheduler.update_event', self.handle_update_event) + self.bus.on('mycroft.scheduler.get_event', self.handle_get_event) + self.bus.on('mycroft.scheduler.list_events', self.handle_list_events) self.bus.on('system.clock.synced', self.handle_system_clock_sync) # emitted by raspOVOS self._running = Event() @@ -205,7 +203,7 @@ def schedule_event(self, event: str, sched_time: float, context to send when the handler is called """ - if datetime.datetime.fromtimestamp(self._last_sync) < self._past_date: + if self._last_sync < self._past_date: # this works around problems in raspOVOS images and other # systems without RTC that didnt sync clock with the internet yet # eg. issue demonstration without this: @@ -232,7 +230,7 @@ def schedule_event(self, event: str, sched_time: float, LOG.warning(f"Added event is scheduled in the past and " f"will be called immediately: {event}") - def schedule_event_handler(self, message: Message): + def handle_schedule_event(self, message: Message): """ Messagebus interface to the schedule_event method. Required data in the message envelope is @@ -268,15 +266,12 @@ def remove_event(self, event: str): def handle_system_clock_sync(self, message: Message): # clock sync, are we in the past? - if datetime.datetime.fromtimestamp(self._last_sync) < self._past_date: + if self._last_sync < self._past_date: LOG.warning(f"Clock was in the past!!! {self._dropped_events} scheduled events have been dropped") + self._last_sync = now_local() + LOG.info(f"clock sync: {self._last_sync}") - self._last_sync = time.time() - # Convert Unix timestamp to human-readable datetime - pretty_last_sync = datetime.datetime.fromtimestamp(self._last_sync).strftime("%Y-%m-%d %H:%M:%S") - LOG.info(f"clock sync: {pretty_last_sync}") - - def remove_event_handler(self, message: Message): + def handle_remove_event(self, message: Message): """ Messagebus interface to the remove_event method. """ @@ -300,7 +295,7 @@ def update_event(self, event: str, data: dict): event_time, repeat, _, context = self.events[event][0] self.events[event][0] = (event_time, repeat, data, context) - def update_event_handler(self, message: Message): + def handle_update_event(self, message: Message): """ Messagebus interface to the update_event method. """ @@ -308,7 +303,7 @@ def update_event_handler(self, message: Message): data = message.data.get('data') self.update_event(event, data) - def list_events_handler(self, message: Message): + def handle_list_events(self, message: Message): """ Messagebus interface to the list_events method. """ @@ -316,7 +311,7 @@ def list_events_handler(self, message: Message): events_snapshot = dict(self.events) self.bus.emit(message.response(data={"scheduled_events": events_snapshot})) - def get_event_handler(self, message: Message): + def handle_get_event(self, message: Message): """ Messagebus interface to get_event. diff --git a/test/unittests/test_event_scheduler.py b/test/unittests/test_event_scheduler.py index a04ca7d..4a4d89e 100644 --- a/test/unittests/test_event_scheduler.py +++ b/test/unittests/test_event_scheduler.py @@ -126,12 +126,11 @@ def test_list_events_handler(self, mock_open, mock_dump, mock_load, mock_thread) mock_message.context = {"source": "test"} # Call the handler - es.list_events_handler(mock_message) + es.handle_list_events(mock_message) # Verify message.reply was called with correct msg_type and data - mock_message.reply.assert_called_once() - call_args = mock_message.reply.call_args - self.assertEqual(call_args[0][0], "mycroft.scheduler.list_events.response") + mock_message.response.assert_called_once() + call_args = mock_message.response.call_args self.assertIn("scheduled_events", call_args[1]["data"]) # Verify emitter.emit was called with the reply message From 4570dcc9385497d3708a62f698124251194fd67e Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Sun, 9 Nov 2025 16:11:53 +0000 Subject: [PATCH 3/4] Increment Version to 1.3.8a1 --- ovos_bus_client/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ovos_bus_client/version.py b/ovos_bus_client/version.py index 9eb0621..720c2c0 100644 --- a/ovos_bus_client/version.py +++ b/ovos_bus_client/version.py @@ -1,6 +1,6 @@ # START_VERSION_BLOCK VERSION_MAJOR = 1 VERSION_MINOR = 3 -VERSION_BUILD = 7 -VERSION_ALPHA = 0 +VERSION_BUILD = 8 +VERSION_ALPHA = 1 # END_VERSION_BLOCK From 058d90ef34d89608fde19c50365768f3e95b5f98 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Sun, 9 Nov 2025 16:12:17 +0000 Subject: [PATCH 4/4] Update Changelog --- CHANGELOG.md | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7392164..f05bfb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,41 +1,12 @@ # Changelog -## [1.3.7a1](https://github.com/OpenVoiceOS/ovos-bus-client/tree/1.3.7a1) (2025-11-06) +## [1.3.8a1](https://github.com/OpenVoiceOS/ovos-bus-client/tree/1.3.8a1) (2025-11-09) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-bus-client/compare/1.3.6a2...1.3.7a1) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-bus-client/compare/1.3.7...1.3.8a1) **Merged pull requests:** -- fix: Update requirements.txt [\#175](https://github.com/OpenVoiceOS/ovos-bus-client/pull/175) ([JarbasAl](https://github.com/JarbasAl)) - -## [1.3.6a2](https://github.com/OpenVoiceOS/ovos-bus-client/tree/1.3.6a2) (2025-11-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-bus-client/compare/1.3.6a1...1.3.6a2) - -**Implemented enhancements:** - -- EventScheduler full CRUD [\#80](https://github.com/OpenVoiceOS/ovos-bus-client/issues/80) - -**Merged pull requests:** - -- Update setup.py [\#173](https://github.com/OpenVoiceOS/ovos-bus-client/pull/173) ([JarbasAl](https://github.com/JarbasAl)) -- feat\(EventScheduler\): list\_events API [\#172](https://github.com/OpenVoiceOS/ovos-bus-client/pull/172) ([mikejgray](https://github.com/mikejgray)) - -## [1.3.6a1](https://github.com/OpenVoiceOS/ovos-bus-client/tree/1.3.6a1) (2025-09-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-bus-client/compare/1.3.5a1...1.3.6a1) - -**Merged pull requests:** - -- fix: make orjson optional [\#169](https://github.com/OpenVoiceOS/ovos-bus-client/pull/169) ([JarbasAl](https://github.com/JarbasAl)) - -## [1.3.5a1](https://github.com/OpenVoiceOS/ovos-bus-client/tree/1.3.5a1) (2025-06-16) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-bus-client/compare/1.3.4...1.3.5a1) - -**Merged pull requests:** - -- Update ovos-config requirement from \<2.0.0,\>=0.0.12 to \>=0.0.12,\<3.0.0 [\#167](https://github.com/OpenVoiceOS/ovos-bus-client/pull/167) ([dependabot[bot]](https://github.com/apps/dependabot)) +- refactor: migrate bus api client to ovos-bus-client package [\#177](https://github.com/OpenVoiceOS/ovos-bus-client/pull/177) ([JarbasAl](https://github.com/JarbasAl))