diff --git a/CHANGELOG.md b/CHANGELOG.md index c69a7117..2a2099c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,16 @@ # Changelog -## [0.3.9a1](https://github.com/OpenVoiceOS/skill-ovos-date-time/tree/0.3.9a1) (2024-11-11) +## [0.4.0a1](https://github.com/OpenVoiceOS/skill-ovos-date-time/tree/0.4.0a1) (2024-11-12) -[Full Changelog](https://github.com/OpenVoiceOS/skill-ovos-date-time/compare/0.3.8a3...0.3.9a1) +[Full Changelog](https://github.com/OpenVoiceOS/skill-ovos-date-time/compare/0.3.9...0.4.0a1) -**Merged pull requests:** - -- fix: drop lingua-franca [\#71](https://github.com/OpenVoiceOS/skill-ovos-date-time/pull/71) ([JarbasAl](https://github.com/JarbasAl)) - -## [0.3.8a3](https://github.com/OpenVoiceOS/skill-ovos-date-time/tree/0.3.8a3) (2024-11-10) - -[Full Changelog](https://github.com/OpenVoiceOS/skill-ovos-date-time/compare/0.3.8a2...0.3.8a3) - -## [0.3.8a2](https://github.com/OpenVoiceOS/skill-ovos-date-time/tree/0.3.8a2) (2024-11-10) - -[Full Changelog](https://github.com/OpenVoiceOS/skill-ovos-date-time/compare/0.3.8a1...0.3.8a2) - -## [0.3.8a1](https://github.com/OpenVoiceOS/skill-ovos-date-time/tree/0.3.8a1) (2024-11-10) +**Implemented enhancements:** -[Full Changelog](https://github.com/OpenVoiceOS/skill-ovos-date-time/compare/0.3.7...0.3.8a1) +- play sound - when hour changes [\#47](https://github.com/OpenVoiceOS/skill-ovos-date-time/issues/47) **Merged pull requests:** -- Nl-nl translation [\#69](https://github.com/OpenVoiceOS/skill-ovos-date-time/pull/69) ([gitlocalize-app[bot]](https://github.com/apps/gitlocalize-app)) -- Nl-NL translation [\#68](https://github.com/OpenVoiceOS/skill-ovos-date-time/pull/68) ([gitlocalize-app[bot]](https://github.com/apps/gitlocalize-app)) -- Nl-nl translation [\#67](https://github.com/OpenVoiceOS/skill-ovos-date-time/pull/67) ([gitlocalize-app[bot]](https://github.com/apps/gitlocalize-app)) +- feat: hour chime [\#66](https://github.com/OpenVoiceOS/skill-ovos-date-time/pull/66) ([JarbasAl](https://github.com/JarbasAl)) diff --git a/MANIFEST.in b/MANIFEST.in index 17379123..7415bc78 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,5 @@ -recursive-include dialog * -recursive-include vocab * recursive-include locale * recursive-include res * -recursive-include qt5 * -recursive-include skill * +recursive-include gui * include *.json include *.txt \ No newline at end of file diff --git a/README.md b/README.md index ad8f5aab..a9e7fdeb 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,7 @@ Get the time, date, day of the week ## About -Get the local time or time for major cities around the world. Times -are given in 12-hour (2:30 pm) or 24-hour format (14:30) based on the -Time Format setting in your `mycroft.conf` - +Get the local time or time for major cities around the world. Times are given in 12-hour (2:30 pm) or 24-hour format (14:30) based on the Time Format setting in your `mycroft.conf` ## Examples * "What time is it?" @@ -16,8 +13,29 @@ Time Format setting in your `mycroft.conf` * "How many days until July 4th" * "What day is Memorial Day 2020?" +## Configuration + +You can adjust certain aspects of this skill's behavior by configuring the `settings.json` file. + +2 sound files are included with the skill, `"casio-watch.wav"` and `"clock-chime.mp3"`, to audibly signal when the hour changes + +Below is an example configuration file with explanations for each option. + +```json +{ + "play_hour_chime": true, + "hour_sound": "clock-chime.mp3" +} +``` + +- **`play_hour_chime`**: (boolean) Enables or disables the hourly chime notification. If `true`, the skill will play an audio chime at the start of every hour. Default is `false`. +- **`hour_sound`**: (string) Specifies the file path to the audio file used for the hourly chime. By default, it points to `casio-watch.wav` in the `res` folder. You can customize this with the path to any audio file you prefer. + ## Credits -Mycroft AI (@MycroftAI) + +- [casio-watch.wav by @Pablobd](https://freesound.org/people/Pablobd/sounds/492481/) under the [CC0 1.0 Universal License](https://creativecommons.org/publicdomain/zero/1.0/) +- [clock-chime.mp3 by @ecfike](https://pixabay.com/sound-effects/clock-chime-88027/) under the [Pixabay Content License](https://pixabay.com/service/license-summary/) +- Original skill by Mycroft AI (@MycroftAI) ## Category **Daily** diff --git a/__init__.py b/__init__.py index 10ef134b..38c08890 100644 --- a/__init__.py +++ b/__init__.py @@ -11,8 +11,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - import datetime +import os import re from typing import Optional @@ -67,8 +67,63 @@ def runtime_requirements(self): no_gui_fallback=True) def initialize(self): - """Initialize the skill by pre-loading lingua-franca.""" + """Initialize the skill by pre-loading language settings and scheduling + the hourly chime. + + This method is called automatically when the skill starts, preloading + language-related formatting for date and time and setting up the initial + scheduling for the hourly chime event. + """ date_time_format.cache(self.lang) + self._schedule_hour_chime() + + def _handle_play_hour_chime(self, message: Message): + """Play the hourly chime audio and re-schedule the next chime event. + + Args: + message (Message): message object + + This method checks if the hourly chime setting is enabled. If it is, it + plays the specified chime audio. Then, it re-schedules the next hourly + chime event. + """ + if self.play_hour_chime: + self.play_audio(self.hour_chime, instant=True) + self._schedule_hour_chime() + + def _schedule_hour_chime(self): + """Schedule the next hourly chime event for the start of the next hour. + + This method calculates the time for the upcoming hour, setting it as + the scheduled time for the next chime event. + """ + n = now_local() + datetime.timedelta(hours=1) + self.schedule_event(self._handle_play_hour_chime, + when=datetime.datetime(year=n.year, month=n.month, day=n.day, + hour=n.hour, minute=0, second=0)) + + @property + def play_hour_chime(self) -> bool: + """Check if the hourly chime setting is enabled. + + Returns: + bool: True if the chime should be played on the hour, False otherwise. + """ + return self.settings.get("play_hour_chime", False) + + @property + def hour_chime(self) -> str: + """Get the file path for the hourly chime sound. + + Returns: + str: The file path to the chime audio file. If not set in settings, + defaults to 'casio-watch.wav' in the 'res' folder. + """ + snd = self.settings.get("hour_sound", "casio-watch.wav") + if not os.path.isfile(snd): + snd2 = f"{os.path.dirname(__file__)}/res/{snd}" + snd = snd2 if os.path.isfile(snd2) else snd + return snd @property def use_24hour(self): @@ -95,7 +150,8 @@ def _extract_location(self, utt: str) -> str: pass return None - def _get_timezone_from_builtins(self, location_string: str) -> datetime.tzinfo: + @staticmethod + def _get_timezone_from_builtins(location_string: str) -> Optional[datetime.tzinfo]: """Get timezone from built-in resources.""" if "/" not in location_string: try: @@ -130,7 +186,7 @@ def _get_timezone_from_table(self, location_string: str) -> Optional[datetime.tz return pytz.timezone(timezones[timezone].strip()) return None - def _get_timezone_from_fuzzymatch(self, location_string: str) -> datetime.tzinfo: + def _get_timezone_from_fuzzymatch(self, location_string: str) -> Optional[datetime.tzinfo]: """Fuzzymatch a location against the pytz timezones. The pytz timezones consists of @@ -187,7 +243,7 @@ def get_timezone_in_location(self, location_string: str) -> datetime.tzinfo: ###################################################################### # utils def get_datetime(self, location: str = None, - anchor_date: datetime.datetime = None) -> datetime.datetime: + anchor_date: datetime.datetime = None) -> Optional[datetime.datetime]: """return anchor_date/now_local at location/session_tz""" if location: tz = self.get_timezone_in_location(location) @@ -430,7 +486,7 @@ def show_date_mark1(self, dt: datetime.datetime): show = self.get_display_date(anchor_date=dt) LOG.debug(f"sending date to mk1 {show}") self.bus.emit(Message("ovos.mk1.display_date", - {"text": show})) + {"text": show})) def show_date_gui(self, dt: datetime.datetime, location: str): self.gui.clear() @@ -454,7 +510,7 @@ def show_time(self, display_time: str): def show_time_mark1(self, display_time: str): LOG.debug(f"Emitting ovos.mk1.display_time with time: {display_time}") self.bus.emit(Message("ovos.mk1.display_time", - {"text": display_time})) + {"text": display_time})) def show_time_gui(self, display_time): """ Display time on the GUI. """ diff --git a/res/casio-watch.wav b/res/casio-watch.wav new file mode 100644 index 00000000..f51fcef1 Binary files /dev/null and b/res/casio-watch.wav differ diff --git a/res/clock-chime.mp3 b/res/clock-chime.mp3 new file mode 100644 index 00000000..3b9610e7 Binary files /dev/null and b/res/clock-chime.mp3 differ diff --git a/setup.py b/setup.py index 49d3e010..fa00f0e7 100755 --- a/setup.py +++ b/setup.py @@ -30,9 +30,9 @@ def get_requirements(requirements_filename: str): def find_resource_files(): - resource_base_dirs = ("locale", "gui") + resource_base_dirs = ("locale", "gui", "res") base_dir = path.dirname(__file__) - package_data = ["*.json"] + package_data = ["*.json", "*.mp3", "*.wav"] for res in resource_base_dirs: if path.isdir(path.join(base_dir, res)): for (directory, _, files) in walk(path.join(base_dir, res)): diff --git a/version.py b/version.py index c759aba7..1b5d2672 100644 --- a/version.py +++ b/version.py @@ -1,6 +1,6 @@ # START_VERSION_BLOCK VERSION_MAJOR = 0 -VERSION_MINOR = 3 -VERSION_BUILD = 9 -VERSION_ALPHA = 0 +VERSION_MINOR = 4 +VERSION_BUILD = 0 +VERSION_ALPHA = 1 # END_VERSION_BLOCK