mirror of
				https://github.com/OpenVoiceOS/OpenVoiceOS
				synced 2025-06-05 22:19:21 +02:00 
			
		
		
		
	MycroftOS: Add patched volume skill by default.
- This will change later on when the enclosure code is ready and take care of the volume control. For now we use ALSA and added the MycroftOS to ALSA_PLATFORMS
This commit is contained in:
		
							
								
								
									
										7
									
								
								buildroot-external/rootfs-overlay/opt/mycroft/skills/mycroft-volume.mycroftai/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								buildroot-external/rootfs-overlay/opt/mycroft/skills/mycroft-volume.mycroftai/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | settings.json | ||||||
|  |  | ||||||
|  | # python compiled files | ||||||
|  | *.pyc | ||||||
|  |  | ||||||
|  | # Vim temp files | ||||||
|  | .*.sw? | ||||||
| @@ -0,0 +1,202 @@ | |||||||
|  |  | ||||||
|  |                                  Apache License | ||||||
|  |                            Version 2.0, January 2004 | ||||||
|  |                         http://www.apache.org/licenses/ | ||||||
|  |  | ||||||
|  |    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||||
|  |  | ||||||
|  |    1. Definitions. | ||||||
|  |  | ||||||
|  |       "License" shall mean the terms and conditions for use, reproduction, | ||||||
|  |       and distribution as defined by Sections 1 through 9 of this document. | ||||||
|  |  | ||||||
|  |       "Licensor" shall mean the copyright owner or entity authorized by | ||||||
|  |       the copyright owner that is granting the License. | ||||||
|  |  | ||||||
|  |       "Legal Entity" shall mean the union of the acting entity and all | ||||||
|  |       other entities that control, are controlled by, or are under common | ||||||
|  |       control with that entity. For the purposes of this definition, | ||||||
|  |       "control" means (i) the power, direct or indirect, to cause the | ||||||
|  |       direction or management of such entity, whether by contract or | ||||||
|  |       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||||
|  |       outstanding shares, or (iii) beneficial ownership of such entity. | ||||||
|  |  | ||||||
|  |       "You" (or "Your") shall mean an individual or Legal Entity | ||||||
|  |       exercising permissions granted by this License. | ||||||
|  |  | ||||||
|  |       "Source" form shall mean the preferred form for making modifications, | ||||||
|  |       including but not limited to software source code, documentation | ||||||
|  |       source, and configuration files. | ||||||
|  |  | ||||||
|  |       "Object" form shall mean any form resulting from mechanical | ||||||
|  |       transformation or translation of a Source form, including but | ||||||
|  |       not limited to compiled object code, generated documentation, | ||||||
|  |       and conversions to other media types. | ||||||
|  |  | ||||||
|  |       "Work" shall mean the work of authorship, whether in Source or | ||||||
|  |       Object form, made available under the License, as indicated by a | ||||||
|  |       copyright notice that is included in or attached to the work | ||||||
|  |       (an example is provided in the Appendix below). | ||||||
|  |  | ||||||
|  |       "Derivative Works" shall mean any work, whether in Source or Object | ||||||
|  |       form, that is based on (or derived from) the Work and for which the | ||||||
|  |       editorial revisions, annotations, elaborations, or other modifications | ||||||
|  |       represent, as a whole, an original work of authorship. For the purposes | ||||||
|  |       of this License, Derivative Works shall not include works that remain | ||||||
|  |       separable from, or merely link (or bind by name) to the interfaces of, | ||||||
|  |       the Work and Derivative Works thereof. | ||||||
|  |  | ||||||
|  |       "Contribution" shall mean any work of authorship, including | ||||||
|  |       the original version of the Work and any modifications or additions | ||||||
|  |       to that Work or Derivative Works thereof, that is intentionally | ||||||
|  |       submitted to Licensor for inclusion in the Work by the copyright owner | ||||||
|  |       or by an individual or Legal Entity authorized to submit on behalf of | ||||||
|  |       the copyright owner. For the purposes of this definition, "submitted" | ||||||
|  |       means any form of electronic, verbal, or written communication sent | ||||||
|  |       to the Licensor or its representatives, including but not limited to | ||||||
|  |       communication on electronic mailing lists, source code control systems, | ||||||
|  |       and issue tracking systems that are managed by, or on behalf of, the | ||||||
|  |       Licensor for the purpose of discussing and improving the Work, but | ||||||
|  |       excluding communication that is conspicuously marked or otherwise | ||||||
|  |       designated in writing by the copyright owner as "Not a Contribution." | ||||||
|  |  | ||||||
|  |       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||||
|  |       on behalf of whom a Contribution has been received by Licensor and | ||||||
|  |       subsequently incorporated within the Work. | ||||||
|  |  | ||||||
|  |    2. Grant of Copyright License. Subject to the terms and conditions of | ||||||
|  |       this License, each Contributor hereby grants to You a perpetual, | ||||||
|  |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||||
|  |       copyright license to reproduce, prepare Derivative Works of, | ||||||
|  |       publicly display, publicly perform, sublicense, and distribute the | ||||||
|  |       Work and such Derivative Works in Source or Object form. | ||||||
|  |  | ||||||
|  |    3. Grant of Patent License. Subject to the terms and conditions of | ||||||
|  |       this License, each Contributor hereby grants to You a perpetual, | ||||||
|  |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||||
|  |       (except as stated in this section) patent license to make, have made, | ||||||
|  |       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||||
|  |       where such license applies only to those patent claims licensable | ||||||
|  |       by such Contributor that are necessarily infringed by their | ||||||
|  |       Contribution(s) alone or by combination of their Contribution(s) | ||||||
|  |       with the Work to which such Contribution(s) was submitted. If You | ||||||
|  |       institute patent litigation against any entity (including a | ||||||
|  |       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||||
|  |       or a Contribution incorporated within the Work constitutes direct | ||||||
|  |       or contributory patent infringement, then any patent licenses | ||||||
|  |       granted to You under this License for that Work shall terminate | ||||||
|  |       as of the date such litigation is filed. | ||||||
|  |  | ||||||
|  |    4. Redistribution. You may reproduce and distribute copies of the | ||||||
|  |       Work or Derivative Works thereof in any medium, with or without | ||||||
|  |       modifications, and in Source or Object form, provided that You | ||||||
|  |       meet the following conditions: | ||||||
|  |  | ||||||
|  |       (a) You must give any other recipients of the Work or | ||||||
|  |           Derivative Works a copy of this License; and | ||||||
|  |  | ||||||
|  |       (b) You must cause any modified files to carry prominent notices | ||||||
|  |           stating that You changed the files; and | ||||||
|  |  | ||||||
|  |       (c) You must retain, in the Source form of any Derivative Works | ||||||
|  |           that You distribute, all copyright, patent, trademark, and | ||||||
|  |           attribution notices from the Source form of the Work, | ||||||
|  |           excluding those notices that do not pertain to any part of | ||||||
|  |           the Derivative Works; and | ||||||
|  |  | ||||||
|  |       (d) If the Work includes a "NOTICE" text file as part of its | ||||||
|  |           distribution, then any Derivative Works that You distribute must | ||||||
|  |           include a readable copy of the attribution notices contained | ||||||
|  |           within such NOTICE file, excluding those notices that do not | ||||||
|  |           pertain to any part of the Derivative Works, in at least one | ||||||
|  |           of the following places: within a NOTICE text file distributed | ||||||
|  |           as part of the Derivative Works; within the Source form or | ||||||
|  |           documentation, if provided along with the Derivative Works; or, | ||||||
|  |           within a display generated by the Derivative Works, if and | ||||||
|  |           wherever such third-party notices normally appear. The contents | ||||||
|  |           of the NOTICE file are for informational purposes only and | ||||||
|  |           do not modify the License. You may add Your own attribution | ||||||
|  |           notices within Derivative Works that You distribute, alongside | ||||||
|  |           or as an addendum to the NOTICE text from the Work, provided | ||||||
|  |           that such additional attribution notices cannot be construed | ||||||
|  |           as modifying the License. | ||||||
|  |  | ||||||
|  |       You may add Your own copyright statement to Your modifications and | ||||||
|  |       may provide additional or different license terms and conditions | ||||||
|  |       for use, reproduction, or distribution of Your modifications, or | ||||||
|  |       for any such Derivative Works as a whole, provided Your use, | ||||||
|  |       reproduction, and distribution of the Work otherwise complies with | ||||||
|  |       the conditions stated in this License. | ||||||
|  |  | ||||||
|  |    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||||
|  |       any Contribution intentionally submitted for inclusion in the Work | ||||||
|  |       by You to the Licensor shall be under the terms and conditions of | ||||||
|  |       this License, without any additional terms or conditions. | ||||||
|  |       Notwithstanding the above, nothing herein shall supersede or modify | ||||||
|  |       the terms of any separate license agreement you may have executed | ||||||
|  |       with Licensor regarding such Contributions. | ||||||
|  |  | ||||||
|  |    6. Trademarks. This License does not grant permission to use the trade | ||||||
|  |       names, trademarks, service marks, or product names of the Licensor, | ||||||
|  |       except as required for reasonable and customary use in describing the | ||||||
|  |       origin of the Work and reproducing the content of the NOTICE file. | ||||||
|  |  | ||||||
|  |    7. Disclaimer of Warranty. Unless required by applicable law or | ||||||
|  |       agreed to in writing, Licensor provides the Work (and each | ||||||
|  |       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||||
|  |       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||||
|  |       implied, including, without limitation, any warranties or conditions | ||||||
|  |       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||||
|  |       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||||
|  |       appropriateness of using or redistributing the Work and assume any | ||||||
|  |       risks associated with Your exercise of permissions under this License. | ||||||
|  |  | ||||||
|  |    8. Limitation of Liability. In no event and under no legal theory, | ||||||
|  |       whether in tort (including negligence), contract, or otherwise, | ||||||
|  |       unless required by applicable law (such as deliberate and grossly | ||||||
|  |       negligent acts) or agreed to in writing, shall any Contributor be | ||||||
|  |       liable to You for damages, including any direct, indirect, special, | ||||||
|  |       incidental, or consequential damages of any character arising as a | ||||||
|  |       result of this License or out of the use or inability to use the | ||||||
|  |       Work (including but not limited to damages for loss of goodwill, | ||||||
|  |       work stoppage, computer failure or malfunction, or any and all | ||||||
|  |       other commercial damages or losses), even if such Contributor | ||||||
|  |       has been advised of the possibility of such damages. | ||||||
|  |  | ||||||
|  |    9. Accepting Warranty or Additional Liability. While redistributing | ||||||
|  |       the Work or Derivative Works thereof, You may choose to offer, | ||||||
|  |       and charge a fee for, acceptance of support, warranty, indemnity, | ||||||
|  |       or other liability obligations and/or rights consistent with this | ||||||
|  |       License. However, in accepting such obligations, You may act only | ||||||
|  |       on Your own behalf and on Your sole responsibility, not on behalf | ||||||
|  |       of any other Contributor, and only if You agree to indemnify, | ||||||
|  |       defend, and hold each Contributor harmless for any liability | ||||||
|  |       incurred by, or claims asserted against, such Contributor by reason | ||||||
|  |       of your accepting any such warranty or additional liability. | ||||||
|  |  | ||||||
|  |    END OF TERMS AND CONDITIONS | ||||||
|  |  | ||||||
|  |    APPENDIX: How to apply the Apache License to your work. | ||||||
|  |  | ||||||
|  |       To apply the Apache License to your work, attach the following | ||||||
|  |       boilerplate notice, with the fields enclosed by brackets "[]" | ||||||
|  |       replaced with your own identifying information. (Don't include | ||||||
|  |       the brackets!)  The text should be enclosed in the appropriate | ||||||
|  |       comment syntax for the file format. We also recommend that a | ||||||
|  |       file or class name and description of purpose be included on the | ||||||
|  |       same "printed page" as the copyright notice for easier | ||||||
|  |       identification within third-party archives. | ||||||
|  |  | ||||||
|  |    Copyright [yyyy] [name of copyright owner] | ||||||
|  |  | ||||||
|  |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |    you may not use this file except in compliance with the License. | ||||||
|  |    You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |    Unless required by applicable law or agreed to in writing, software | ||||||
|  |    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |    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. | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | # <img src='https://raw.githack.com/FortAwesome/Font-Awesome/master/svgs/solid/volume-down.svg' card_color='#22a7f0' width='50' height='50' style='vertical-align:bottom'/> Volume Control | ||||||
|  | Control the volume of your system | ||||||
|  |  | ||||||
|  | ## About | ||||||
|  | Control the volume of Mycroft with verbal commands or by spinning the physical | ||||||
|  | button on a Mark 1. | ||||||
|  |  | ||||||
|  | ## Examples | ||||||
|  | * "Turn up the volume" | ||||||
|  | * "Decrease the audio" | ||||||
|  | * "Mute audio" | ||||||
|  | * "Set volume to 5" | ||||||
|  | * "Set volume to 75 percent" | ||||||
|  |  | ||||||
|  | ## Credits | ||||||
|  | Mycroft AI (@MycroftAI) | ||||||
|  |  | ||||||
|  | ## Category | ||||||
|  | **Configuration** | ||||||
|  |  | ||||||
|  | ## Tags | ||||||
|  | #volume | ||||||
|  | #volume-control | ||||||
|  | #sound | ||||||
|  | #system | ||||||
| @@ -0,0 +1,399 @@ | |||||||
|  | # Copyright 2017 Mycroft AI Inc. | ||||||
|  | # | ||||||
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #    http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software | ||||||
|  | # distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | # 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. | ||||||
|  | # | ||||||
|  | from alsaaudio import Mixer, mixers as alsa_mixers | ||||||
|  | from os.path import dirname, join | ||||||
|  |  | ||||||
|  | from adapt.intent import IntentBuilder | ||||||
|  | from mycroft.audio import wait_while_speaking | ||||||
|  | from mycroft.messagebus.message import Message | ||||||
|  | from mycroft.skills.core import MycroftSkill, intent_handler | ||||||
|  | from mycroft.util import play_wav | ||||||
|  | from mycroft.util.parse import extract_number | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ALSA_PLATFORMS = ['MycroftOS', 'mycroft_mark_1', 'picroft', 'unknown'] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class VolumeSkill(MycroftSkill): | ||||||
|  |     """ | ||||||
|  |     Control the audio volume for the Mycroft system | ||||||
|  |  | ||||||
|  |     Terminology: | ||||||
|  |        "Level" =  Mycroft volume levels, from 0 to 10 | ||||||
|  |        "Volume" = ALSA mixer setting, from 0 to 100 | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     MIN_LEVEL = 0 | ||||||
|  |     MAX_LEVEL = 10 | ||||||
|  |  | ||||||
|  |     # TODO: Translation layer (have to match word in Level.voc) | ||||||
|  |     VOLUME_WORDS = { | ||||||
|  |         'loud': 9, | ||||||
|  |         'normal': 6, | ||||||
|  |         'quiet': 3 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     def __init__(self): | ||||||
|  |         super(VolumeSkill, self).__init__("VolumeSkill") | ||||||
|  |         self.settings["default_level"] = 6  # can be 0 (off) to 10 (max) | ||||||
|  |         self.settings["min_volume"] = 0     # can be 0 to 100 | ||||||
|  |         if self.config_core['enclosure'].get('platform') == 'mycroft_mark_1': | ||||||
|  |             self.settings["max_volume"] = 83   # can be 0 to 83 | ||||||
|  |         else: | ||||||
|  |             self.settings["max_volume"] = 100   # can be 0 to 100 | ||||||
|  |         self.volume_sound = join(dirname(__file__), "blop-mark-diangelo.wav") | ||||||
|  |         self.vol_before_mute = None | ||||||
|  |         self._mixer = None | ||||||
|  |  | ||||||
|  |     def _clear_mixer(self): | ||||||
|  |         """For Unknown platforms reinstantiate the mixer. | ||||||
|  |  | ||||||
|  |         For mycroft_mark_1 do not reinstantiate the mixer. | ||||||
|  |         """ | ||||||
|  |         platform = self.config_core['enclosure'].get('platform', 'unknown') | ||||||
|  |         if platform != 'mycroft_mark_1': | ||||||
|  |             self._mixer = None | ||||||
|  |  | ||||||
|  |     def _get_mixer(self): | ||||||
|  |         self.log.debug('Finding Alsa Mixer for control...') | ||||||
|  |         mixer = None | ||||||
|  |         try: | ||||||
|  |             # If there are only 1 mixer use that one | ||||||
|  |             mixers = alsa_mixers() | ||||||
|  |             if len(mixers) == 1: | ||||||
|  |                 mixer = Mixer(mixers[0]) | ||||||
|  |             elif 'Master' in mixers: | ||||||
|  |                 # Try using the default mixer (Master) | ||||||
|  |                 mixer = Mixer('Master') | ||||||
|  |             elif 'PCM' in mixers: | ||||||
|  |                 # PCM is another common one | ||||||
|  |                 mixer = Mixer('PCM') | ||||||
|  |             elif 'Digital' in mixers: | ||||||
|  |                 # My mixer is called 'Digital' (JustBoom DAC) | ||||||
|  |                 mixer = Mixer('Digital') | ||||||
|  |             else: | ||||||
|  |                 # should be equivalent to 'Master' | ||||||
|  |                 mixer = Mixer() | ||||||
|  |         except Exception: | ||||||
|  |             # Retry instanciating the mixer with the built-in default | ||||||
|  |             try: | ||||||
|  |                 mixer = Mixer() | ||||||
|  |             except Exception as e: | ||||||
|  |                 self.log.error('Couldn\'t allocate mixer, {}'.format(repr(e))) | ||||||
|  |         self._mixer = mixer | ||||||
|  |         return mixer | ||||||
|  |  | ||||||
|  |     def initialize(self): | ||||||
|  |         # Register handlers to detect percentages as reported by STT | ||||||
|  |         for i in range(101):  # numbers 0 to 100 | ||||||
|  |             self.register_vocabulary(str(i) + '%', 'Percent') | ||||||
|  |  | ||||||
|  |         # Register handlers for messagebus events | ||||||
|  |         self.add_event('mycroft.volume.increase', | ||||||
|  |                        self.handle_increase_volume) | ||||||
|  |         self.add_event('mycroft.volume.decrease', | ||||||
|  |                        self.handle_decrease_volume) | ||||||
|  |         self.add_event('mycroft.volume.mute', | ||||||
|  |                        self.handle_mute_volume) | ||||||
|  |         self.add_event('mycroft.volume.unmute', | ||||||
|  |                        self.handle_unmute_volume) | ||||||
|  |         self.add_event('recognizer_loop:record_begin', | ||||||
|  |                        self.duck) | ||||||
|  |         self.add_event('recognizer_loop:record_end', | ||||||
|  |                        self.unduck) | ||||||
|  |  | ||||||
|  |         self.vol_before_mute = self.__get_system_volume() | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def mixer(self): | ||||||
|  |         platform = self.config_core['enclosure'].get('platform', 'unknown') | ||||||
|  |         if platform in ALSA_PLATFORMS: | ||||||
|  |             return self._mixer or self._get_mixer() | ||||||
|  |         else: | ||||||
|  |             return None | ||||||
|  |  | ||||||
|  |     def _setvolume(self, vol, emit=True): | ||||||
|  |         # Update ALSA | ||||||
|  |         if self.mixer: | ||||||
|  |             self.log.debug(vol) | ||||||
|  |             self.mixer.setvolume(vol) | ||||||
|  |         # TODO: Remove this and control volume at the Enclosure level in | ||||||
|  |         # response to the mycroft.volume.set message. | ||||||
|  |  | ||||||
|  |         if emit: | ||||||
|  |             # Notify non-ALSA systems of volume change | ||||||
|  |             self.bus.emit(Message('mycroft.volume.set', | ||||||
|  |                                   data={"percent": vol/100.0})) | ||||||
|  |  | ||||||
|  |     # Change Volume to X (Number 0 to) Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("SetVolume").require("Volume") | ||||||
|  |                     .optionally("Increase").optionally("Decrease") | ||||||
|  |                     .optionally("To").require("Level")) | ||||||
|  |     def handle_set_volume(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         default_vol = self.__get_system_volume(50) | ||||||
|  |  | ||||||
|  |         level = self.__get_volume_level(message, default_vol) | ||||||
|  |         self._setvolume(self.__level_to_volume(level)) | ||||||
|  |         if level == self.MAX_LEVEL: | ||||||
|  |             self.speak_dialog('max.volume') | ||||||
|  |         else: | ||||||
|  |             self.speak_dialog('set.volume', data={'volume': level}) | ||||||
|  |  | ||||||
|  |     # Set Volume Percent Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("SetVolumePercent").require("Volume") | ||||||
|  |                     .optionally("Increase").optionally("Decrease") | ||||||
|  |                     .optionally("To").require("Percent")) | ||||||
|  |     def handle_set_volume_percent(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         percent = extract_number(message.data['utterance'].replace('%', '')) | ||||||
|  |         percent = int(percent) | ||||||
|  |         self._setvolume(percent) | ||||||
|  |         self.speak_dialog('set.volume.percent', data={'level': percent}) | ||||||
|  |  | ||||||
|  |     # Volume Status Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("QueryVolume").optionally("Query") | ||||||
|  |                     .require("Volume")) | ||||||
|  |     def handle_query_volume(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         level = self.__volume_to_level(self.__get_system_volume(0, show=True)) | ||||||
|  |         self.speak_dialog('volume.is', data={'volume': round(level)}) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("QueryVolumePhrase").require("QueryPhrase") | ||||||
|  |                     .optionally("Volume")) | ||||||
|  |     def handle_query_volume_phrase(self, message): | ||||||
|  |         self.handle_query_volume(message) | ||||||
|  |  | ||||||
|  |     def __communicate_volume_change(self, message, dialog, code, changed): | ||||||
|  |         play_sound = message.data.get('play_sound', False) | ||||||
|  |         if play_sound: | ||||||
|  |             if changed: | ||||||
|  |                 play_wav(self.volume_sound) | ||||||
|  |         else: | ||||||
|  |             if (not changed) and (code != 0): | ||||||
|  |                 self.speak_dialog('already.max.volume', data={'volume': code}) | ||||||
|  |  | ||||||
|  |     # Increase Volume Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("IncreaseVolume").require("Volume") | ||||||
|  |                     .require("Increase")) | ||||||
|  |     def handle_increase_volume(self, message): | ||||||
|  |         self.__communicate_volume_change(message, 'increase.volume', | ||||||
|  |                                          *self.__update_volume(+1)) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("IncreaseVolumeSet").require("Set") | ||||||
|  |                     .optionally("Volume").require("Increase")) | ||||||
|  |     def handle_increase_volume_set(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         self.handle_increase_volume(message) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("IncreaseVolumePhrase") | ||||||
|  |                     .require("IncreasePhrase")) | ||||||
|  |     def handle_increase_volume_phrase(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         self.handle_increase_volume(message) | ||||||
|  |  | ||||||
|  |     # Decrease Volume Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("DecreaseVolume").require("Volume") | ||||||
|  |                     .require("Decrease")) | ||||||
|  |     def handle_decrease_volume(self, message): | ||||||
|  |         self.__communicate_volume_change(message, 'decrease.volume', | ||||||
|  |                                          *self.__update_volume(-1)) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("DecreaseVolumeSet").require("Set") | ||||||
|  |                     .optionally("Volume").require("Decrease")) | ||||||
|  |     def handle_decrease_volume_set(self, message): | ||||||
|  |         self.handle_decrease_volume(message) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("DecreaseVolumePhrase") | ||||||
|  |                     .require("DecreasePhrase")) | ||||||
|  |     def handle_decrease_volume_phrase(self, message): | ||||||
|  |         self.handle_decrease_volume(message) | ||||||
|  |  | ||||||
|  |     # Maximum Volume Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("MaxVolume").optionally("Set") | ||||||
|  |                     .require("Volume").optionally("Increase") | ||||||
|  |                     .require("MaxVolume")) | ||||||
|  |     def handle_max_volume(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         self._setvolume(self.settings["max_volume"]) | ||||||
|  |         speak_message = message.data.get('speak_message', True) | ||||||
|  |         if speak_message: | ||||||
|  |             self.speak_dialog('max.volume') | ||||||
|  |             wait_while_speaking() | ||||||
|  |         self.bus.emit(Message('mycroft.volume.duck')) | ||||||
|  |  | ||||||
|  |     @intent_handler(IntentBuilder("MaxVolumeIncreaseMax") | ||||||
|  |                     .require("MaxVolumePhrase").optionally("Volume") | ||||||
|  |                     .require("Increase").optionally("MaxVolume")) | ||||||
|  |     def handle_max_volume_increase_to_max(self, message): | ||||||
|  |         self.handle_max_volume(message) | ||||||
|  |  | ||||||
|  |     def duck(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         if self.settings.get('ducking', True): | ||||||
|  |             self._mute_volume() | ||||||
|  |  | ||||||
|  |     def unduck(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         if self.settings.get('ducking', True): | ||||||
|  |             self._unmute_volume() | ||||||
|  |  | ||||||
|  |     def _mute_volume(self, message=None, speak=False): | ||||||
|  |         self.log.debug('MUTING!') | ||||||
|  |         self.vol_before_mute = self.__get_system_volume() | ||||||
|  |         self.log.debug(self.vol_before_mute) | ||||||
|  |         if speak: | ||||||
|  |             self.speak_dialog('mute.volume') | ||||||
|  |             wait_while_speaking() | ||||||
|  |         self._setvolume(0, emit=False) | ||||||
|  |         self.bus.emit(Message('mycroft.volume.duck')) | ||||||
|  |  | ||||||
|  |     # Mute Volume Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("MuteVolume").require( | ||||||
|  |         "Volume").require("Mute")) | ||||||
|  |     def handle_mute_volume(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         self._mute_volume(speak=message.data.get('speak_message', True)) | ||||||
|  |  | ||||||
|  |     def _unmute_volume(self, message=None, speak=False): | ||||||
|  |         if self.vol_before_mute is None: | ||||||
|  |             vol = self.__level_to_volume(self.settings["default_level"]) | ||||||
|  |         else: | ||||||
|  |             vol = self.vol_before_mute | ||||||
|  |         self.vol_before_mute = None | ||||||
|  |  | ||||||
|  |         self._setvolume(vol, emit=False) | ||||||
|  |         self.bus.emit(Message('mycroft.volume.unduck')) | ||||||
|  |  | ||||||
|  |         if speak: | ||||||
|  |             self.speak_dialog('reset.volume', | ||||||
|  |                               data={'volume': | ||||||
|  |                                     self.settings["default_level"]}) | ||||||
|  |  | ||||||
|  |     # Unmute/Reset Volume Intent Handlers | ||||||
|  |     @intent_handler(IntentBuilder("UnmuteVolume").require("Volume") | ||||||
|  |                     .require("Unmute")) | ||||||
|  |     def handle_unmute_volume(self, message): | ||||||
|  |         self._clear_mixer() | ||||||
|  |         self._unmute_volume(speak=message.data.get('speak_message', True)) | ||||||
|  |  | ||||||
|  |     def __volume_to_level(self, volume): | ||||||
|  |         """ | ||||||
|  |             Convert a 'volume' to a 'level' | ||||||
|  |  | ||||||
|  |             Args: | ||||||
|  |                 volume (int): min_volume..max_volume | ||||||
|  |             Returns: | ||||||
|  |                 int: the equivalent level | ||||||
|  |         """ | ||||||
|  |         range = self.MAX_LEVEL - self.MIN_LEVEL | ||||||
|  |         min_vol = self.settings["min_volume"] | ||||||
|  |         max_vol = self.settings["max_volume"] | ||||||
|  |         prop = float(volume - min_vol) / max_vol | ||||||
|  |         level = int(round(self.MIN_LEVEL + range * prop)) | ||||||
|  |         if level > self.MAX_LEVEL: | ||||||
|  |             level = self.MAX_LEVEL | ||||||
|  |         elif level < self.MIN_LEVEL: | ||||||
|  |             level = self.MIN_LEVEL | ||||||
|  |         return level | ||||||
|  |  | ||||||
|  |     def __level_to_volume(self, level): | ||||||
|  |         """ | ||||||
|  |             Convert a 'level' to a 'volume' | ||||||
|  |  | ||||||
|  |             Args: | ||||||
|  |                 level (int): 0..MAX_LEVEL | ||||||
|  |             Returns: | ||||||
|  |                 int: the equivalent volume | ||||||
|  |         """ | ||||||
|  |         range = self.settings["max_volume"] - self.settings["min_volume"] | ||||||
|  |         prop = float(level) / self.MAX_LEVEL | ||||||
|  |         volume = int(round(self.settings["min_volume"] + int(range) * prop)) | ||||||
|  |  | ||||||
|  |         return volume | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|  |     def __bound_level(level): | ||||||
|  |         if level > VolumeSkill.MAX_LEVEL: | ||||||
|  |             level = VolumeSkill.MAX_LEVEL | ||||||
|  |         elif level < VolumeSkill.MIN_LEVEL: | ||||||
|  |             level = VolumeSkill.MIN_LEVEL | ||||||
|  |         return level | ||||||
|  |  | ||||||
|  |     def __update_volume(self, change=0): | ||||||
|  |         """ | ||||||
|  |             Attempt to change audio level | ||||||
|  |  | ||||||
|  |             Args: | ||||||
|  |                 change (int): +1 or -1; the step to change by | ||||||
|  |  | ||||||
|  |             Returns: tuple(new level code int(0..10), | ||||||
|  |                            whether level changed (bool)) | ||||||
|  |         """ | ||||||
|  |         old_level = self.__volume_to_level(self.__get_system_volume(0)) | ||||||
|  |         new_level = self.__bound_level(old_level + change) | ||||||
|  |         self.enclosure.eyes_volume(new_level) | ||||||
|  |         self._setvolume(self.__level_to_volume(new_level)) | ||||||
|  |         return new_level, new_level != old_level | ||||||
|  |  | ||||||
|  |     def __get_system_volume(self, default=50, show=False): | ||||||
|  |         """ Get volume, either from mixer or ask on messagebus. | ||||||
|  |  | ||||||
|  |         The show parameter should only be True when a user is requesting | ||||||
|  |         the volume and not the system. | ||||||
|  |         TODO: Remove usage of Mixer and move that stuff to enclosure. | ||||||
|  |         """ | ||||||
|  |         vol = default | ||||||
|  |         if self.mixer: | ||||||
|  |             vol = min(self.mixer.getvolume()[0], 100) | ||||||
|  |             self.log.debug('Volume before mute: {}'.format(vol)) | ||||||
|  |         else: | ||||||
|  |             vol_msg = self.bus.wait_for_response( | ||||||
|  |                                 Message("mycroft.volume.get", {'show': show})) | ||||||
|  |             if vol_msg: | ||||||
|  |                 vol = int(vol_msg.data["percent"] * 100) | ||||||
|  |  | ||||||
|  |         return vol | ||||||
|  |  | ||||||
|  |     def __get_volume_level(self, message, default=None): | ||||||
|  |         """ Retrievs volume from message. """ | ||||||
|  |         level_str = message.data.get('Level', default) | ||||||
|  |         level = self.settings["default_level"] | ||||||
|  |  | ||||||
|  |         try: | ||||||
|  |             level = self.VOLUME_WORDS[level_str] | ||||||
|  |         except KeyError: | ||||||
|  |             try: | ||||||
|  |                 level = int(extract_number(level_str)) | ||||||
|  |                 if (level == self.MAX_LEVEL + 1): | ||||||
|  |                     # Assume that user meant max volume | ||||||
|  |                     level = self.MAX_LEVEL | ||||||
|  |                 elif (level > self.MAX_LEVEL): | ||||||
|  |                     # Guess that the user said something like 100 percent | ||||||
|  |                     # so convert that into a level value | ||||||
|  |                     level = self.MAX_LEVEL * level/100 | ||||||
|  |             except ValueError: | ||||||
|  |                 pass | ||||||
|  |  | ||||||
|  |         level = self.__bound_level(level) | ||||||
|  |         return level | ||||||
|  |  | ||||||
|  |     def shutdown(self): | ||||||
|  |         if self.vol_before_mute is not None: | ||||||
|  |             self._unmute_volume() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def create_skill(): | ||||||
|  |     return VolumeSkill() | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | Lydstyrken er allerede på maximum | ||||||
|  | Jeg kan ikke blive højere | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume resuceret to {{volume}} | ||||||
|  | Volume mindsket til {{volume}} | ||||||
|  | Volume er nu {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume er nu {{volume}} | ||||||
|  | Lydstyrke forøget til {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Audio bliver muted | ||||||
|  | Lyd bliver muted | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Lydstyrke nulstillet til {{volume} | ||||||
|  | Lydstyrke nulstillet til {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lydstyrke stillet til {{volume}} | ||||||
|  | Lydstyrke indstillet til {{volume}} | ||||||
|  | Lydstyrken ændret til {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lydstyrken er sat til {{level}} procent | ||||||
|  | Lydstyrkem er opdateret til {{level}} procent | ||||||
|  | Lydstyrken er ændret til {{evel}} percent | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Lydstyrken er sat til {{volume}} | ||||||
|  | Lydstyrken er {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Die Lautstärke ist bereits auf Maximum | ||||||
|  | Ich kann nicht lauter werden | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lautstärke auf {{volume}} reduziert | ||||||
|  | Lautstärke auf {{volume}} reduziert | ||||||
|  | Lautstärke ist jetzt {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Lautstärke ist jetzt {{volume}} | ||||||
|  | Lautstärke auf {{volume}} erhöht | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lautstärke auf maximum eingestellt | ||||||
|  | Lautstärke auf Maximum gesetzt | ||||||
|  | Lautstärke auf maximum geändert | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Audio wird gedämpft | ||||||
|  | Der Ton wird gedämpft | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Lautstärke auf {{volume}} zurückgesetzt | ||||||
|  | Lautstärke auf {{volume}} wiederhergestellt | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lautstärke auf {{volume}} eingestellt | ||||||
|  | Lautstärke auf {{volume}} aktualisiert | ||||||
|  | Lautstärke auf {{volume}} geändert | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Lautstärke gesetzt auf {{level}} Prozent | ||||||
|  | Lautstärke aktualisiert auf {{level}} Prozent | ||||||
|  | Lautstärke auf {{level}} Prozent geändert | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Die Lautstärke ist auf {{volume}} gesetzt | ||||||
|  | Die Lautstärke ist bei {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume is already at maximum | ||||||
|  | I can't get any louder | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume reduced to {{volume}} | ||||||
|  | Volume decreased to {{volume}} | ||||||
|  | Volume is now {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume is now {{volume}} | ||||||
|  | Volume increased to {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume set to maximum level | ||||||
|  | Volume updated to maximum level | ||||||
|  | Volume changed to maximum level | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Audio is going to be muted | ||||||
|  | Sound is going to be muted | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume reset to {{volume}} | ||||||
|  | Volume restored to {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume set to {{volume}} | ||||||
|  | Volume updated to {{volume}} | ||||||
|  | Volume changed to {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume set to {{level}} percent | ||||||
|  | Volume updated to {{level}} percent | ||||||
|  | Volume changed to {{level}} percent | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | The volume is set to {{volume}} | ||||||
|  | The volume is at {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | El volumen ya está al máximo | ||||||
|  | No se puede poner más fuerte | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volumen reducido a {{volume}} | ||||||
|  | Volumen bajado a {{volume}} | ||||||
|  | El volumen está al {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | El volumen está al {{volume}} | ||||||
|  | Volumen subido al {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volumen a máximo nivel | ||||||
|  | Volumen actualizado a máximo nivel | ||||||
|  | Volumen cambiado a máximo nivel | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | El audio se silenciará | ||||||
|  | El sonido se silenciará | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | El volumen se volverá a poner al {{volume}} | ||||||
|  | El volumen restaurado al {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volumen puesto al {{volume}} | ||||||
|  | Volumen actualizado al {{volume}} | ||||||
|  | Volumen cambiado al {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volumen establecido al {{level}} por ciento | ||||||
|  | Volumen actualizado al {{level}} por ciento | ||||||
|  | Volumen cambiado al {{level}} por ciento | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | El volumen está establecido al {{volume}} | ||||||
|  | El volumen está al {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Le volume est déjà au maximum | ||||||
|  | Je ne peux pas être plus fort | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Le volume a été réduit à {{volume}} | ||||||
|  | Le volume a été baissé à {{volume}} | ||||||
|  | Le volume est maintenant à {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Le volume est maintenant à {{volume}} | ||||||
|  | Le volume a été augmenté à {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | L'audio va être mis en muet | ||||||
|  | Le son va être mis en muet | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume réinitialisé à {{volume}} | ||||||
|  | Volume restauré à {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume définit à {{volume}} | ||||||
|  | Volume mis à jour à {{volume}} | ||||||
|  | Volume changé à {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Le volume a été définit à {{volume}} | ||||||
|  | Le volume est à {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | A hangerő már maximumon van | ||||||
|  | Hangosabbra nem megy | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | A hangerő csökkentve. Új szint: {{volume}} | ||||||
|  | A hangerő lecsökkent a következő szintre: {{volume}} | ||||||
|  | A hangerő új szintje: {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | A hangerő új szintje: {{volume}} | ||||||
|  | A hangerő megnövelve. Új szint: {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | A hang elnémul | ||||||
|  | A hang elnémítva | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | A hangerő visszaállítva, értéke: {{volume}} | ||||||
|  | A hangerőt visszaállítottam, az új szint: {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | A hangerő beállítva a következő szintre: {{volume}} | ||||||
|  | A hangerő megváltozott. Új értéke: {{volume}} | ||||||
|  | A hangerő új értéke a következő: {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | A hangerő szintje: {{volume}} | ||||||
|  | A hangerő értéke {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Il volume è già al massimo | ||||||
|  | Non posso aumentare di più il volume | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume ridotto a {{volume}} | ||||||
|  | Volume diminuito a {{volume}} | ||||||
|  | Il volume adesso è {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Il volume adesso è {{volume}} | ||||||
|  | Volume aumentato a {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume impostato a livello massimo | ||||||
|  | Volume aggiornato al massimo livello | ||||||
|  | Volume cambiato su livello massimo | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | L'audio sta per essere disattivato | ||||||
|  | Il suono sta per essere disattivato | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volume reimpostato a {{volume}} | ||||||
|  | Volume ripristinato a {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume impostato a {{volume}} | ||||||
|  | Volume aggiornato a {{volume}} | ||||||
|  | Volume modificato a {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume impostato a {{level}} percento | ||||||
|  | Volume aggiornato al {{level}} percento | ||||||
|  | Volume modificato al {{level}} percento | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Il volume è impostato a {{volume}} | ||||||
|  | Il volume è a {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Het geluidsniveau is al op maximum | ||||||
|  | Ik kan niet harder | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Geluidsniveau verlaagd naar {{volume}} | ||||||
|  | Geluidsniveau afgenomen tot {{volume}} | ||||||
|  | Geluidsniveau is nu {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Geluidsniveau is nu {{volume}} | ||||||
|  | Geluidsniveau toegenomen tot {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Audio zal worden gedempt | ||||||
|  | Geluid zal worden gedempt | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Geluidsniveau reset naar {{volume}} | ||||||
|  | Geluidsniveau hersteld naar {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Geluidsniveau gezet op {{volume}} | ||||||
|  | Geluidsniveau bijgewerkt naar {{volume}} | ||||||
|  | Geluidsniveau gewijzigd naar {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volume op {{level}} procent ingesteld | ||||||
|  | Volume naar {{level}} procent bijgewerkt | ||||||
|  | Volume in {{level}} procent veranderd | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Het geluidsniveau is gezet op {{volume}} | ||||||
|  | Het geluidsniveau staat op {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Громкость уже на максимуме | ||||||
|  | Я не могу быть громче | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Громкость уменьшена к {{volume}} | ||||||
|  | Громкость убавлена до {{volume}} | ||||||
|  | Громкость теперь {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Громкость теперь {{volume}} | ||||||
|  | Громкость увеличена до {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Перехожу в режим без звука | ||||||
|  | Звук будет выключен | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Громкость перезагружена на {{volume}} | ||||||
|  | Громкость восстановлена до {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Громкость установлена на {{volume}} | ||||||
|  | Громкость обновлена до {{volume}} | ||||||
|  | Громкость изменена на {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Уровень звука установлен на {{volume}} | ||||||
|  | Уровень звука {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volymen är redan på max | ||||||
|  | Jag kan inte höja mer | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volymen har sänkts till {{volume}} | ||||||
|  | Volymen sänktes till {{volume}} | ||||||
|  | Volymen är nu {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volymen är nu {{volume}} | ||||||
|  | Volymen ökades till {{volume}} | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Audio kommer att tystas | ||||||
|  | Ljudet kommer att tystas | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volymen har återställts till {{volume}} | ||||||
|  | Volymen har återställts till {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volymen har satts till {{volume}} | ||||||
|  | Volymen har ändrats till {{volume}} | ||||||
|  | Volymen är nu {{volume}} | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | Volymen har satts till {{level}} procent | ||||||
|  | Volymen har ändrats till {{level}} procent | ||||||
|  | Volymen är nu {{level}} procent | ||||||
| @@ -0,0 +1,2 @@ | |||||||
|  | Volymen är satt till {{volume}} | ||||||
|  | Volymen är satt till {{volume}} | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | skillMetadata: | ||||||
|  |   sections: | ||||||
|  |   - name: Ducking | ||||||
|  |     fields: | ||||||
|  |     - name: ducking | ||||||
|  |       type: checkbox | ||||||
|  |       label: Duck while listening | ||||||
|  |       value: "true" | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "set volume to 3", | ||||||
|  |   "intent_type": "SetVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Level": "3" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "reset volume", | ||||||
|  |   "intent_type": "UnmuteVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Unmute": "reset" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "update volume to 11", | ||||||
|  |   "intent_type": "SetVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Level": "11" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "increase volume", | ||||||
|  |   "intent_type": "IncreaseVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Increase": "increase" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "rise volume", | ||||||
|  |   "intent_type": "IncreaseVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Increase": "rise" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "decrease volume", | ||||||
|  |   "intent_type": "DecreaseVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Decrease": "decrease" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "reduce volume", | ||||||
|  |   "intent_type": "DecreaseVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Decrease": "reduce" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "set volume to quiet", | ||||||
|  |   "intent_type": "SetVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Level": "quiet" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "update volume to normal", | ||||||
|  |   "intent_type": "SetVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Level": "normal" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "utterance": "change volume to loud", | ||||||
|  |   "intent_type": "SetVolume", | ||||||
|  |   "intent": { | ||||||
|  |     "Volume": "volume", | ||||||
|  |     "Level": "loud" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | sænk | ||||||
|  | reducere | ||||||
|  | sænk | ||||||
|  | sænk | ||||||
|  | lavere | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | hæv | ||||||
|  | hæv | ||||||
|  | boost | ||||||
|  | øg | ||||||
|  | skru op | ||||||
|  | højere | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | 0 | ||||||
|  | 1 | ||||||
|  | 2 | ||||||
|  | 3 | ||||||
|  | 4 | ||||||
|  | 5 | ||||||
|  | 6 | ||||||
|  | 7 | ||||||
|  | 8 | ||||||
|  | 9 | ||||||
|  | 10 | ||||||
|  | 11 | ||||||
|  | stille | ||||||
|  | normal | ||||||
|  | højt | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user