mirror of
				https://github.com/OpenVoiceOS/OpenVoiceOS
				synced 2025-06-05 22:19:21 +02:00 
			
		
		
		
	MycroftOS: GUI: Add of updated volume skill and mark2-skill
This commit is contained in:
		@@ -311,6 +311,7 @@ BR2_PACKAGE_CMOCKA=y
 | 
			
		||||
BR2_PACKAGE_ELL=y
 | 
			
		||||
BR2_PACKAGE_LIBCAP_NG=y
 | 
			
		||||
BR2_PACKAGE_LIBUV=y
 | 
			
		||||
BR2_PACKAGE_LINUX_PAM=y
 | 
			
		||||
BR2_PACKAGE_PROTOBUF=y
 | 
			
		||||
BR2_PACKAGE_LIBESTR=y
 | 
			
		||||
BR2_PACKAGE_LIBFRIBIDI=y
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
settings.json
 | 
			
		||||
 | 
			
		||||
# python compiled files
 | 
			
		||||
*.pyc
 | 
			
		||||
 | 
			
		||||
# Vim temp files
 | 
			
		||||
.*.sw?
 | 
			
		||||
@@ -1,202 +0,0 @@
 | 
			
		||||
 | 
			
		||||
                                 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.
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
# <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
 | 
			
		||||
@@ -1,399 +0,0 @@
 | 
			
		||||
# 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.
										
									
								
							@@ -1,2 +0,0 @@
 | 
			
		||||
Lydstyrken er allerede på maximum
 | 
			
		||||
Jeg kan ikke blive højere
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume resuceret to {{volume}}
 | 
			
		||||
Volume mindsket til {{volume}}
 | 
			
		||||
Volume er nu {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume er nu {{volume}}
 | 
			
		||||
Lydstyrke forøget til {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Audio bliver muted
 | 
			
		||||
Lyd bliver muted
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Lydstyrke nulstillet til {{volume}
 | 
			
		||||
Lydstyrke nulstillet til {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lydstyrke stillet til {{volume}}
 | 
			
		||||
Lydstyrke indstillet til {{volume}}
 | 
			
		||||
Lydstyrken ændret til {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lydstyrken er sat til {{level}} procent
 | 
			
		||||
Lydstyrkem er opdateret til {{level}} procent
 | 
			
		||||
Lydstyrken er ændret til {{evel}} percent
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Lydstyrken er sat til {{volume}}
 | 
			
		||||
Lydstyrken er {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Die Lautstärke ist bereits auf Maximum
 | 
			
		||||
Ich kann nicht lauter werden
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lautstärke auf {{volume}} reduziert
 | 
			
		||||
Lautstärke auf {{volume}} reduziert
 | 
			
		||||
Lautstärke ist jetzt {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Lautstärke ist jetzt {{volume}}
 | 
			
		||||
Lautstärke auf {{volume}} erhöht
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lautstärke auf maximum eingestellt
 | 
			
		||||
Lautstärke auf Maximum gesetzt
 | 
			
		||||
Lautstärke auf maximum geändert
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Audio wird gedämpft
 | 
			
		||||
Der Ton wird gedämpft
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Lautstärke auf {{volume}} zurückgesetzt
 | 
			
		||||
Lautstärke auf {{volume}} wiederhergestellt
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lautstärke auf {{volume}} eingestellt
 | 
			
		||||
Lautstärke auf {{volume}} aktualisiert
 | 
			
		||||
Lautstärke auf {{volume}} geändert
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Lautstärke gesetzt auf {{level}} Prozent
 | 
			
		||||
Lautstärke aktualisiert auf {{level}} Prozent
 | 
			
		||||
Lautstärke auf {{level}} Prozent geändert
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Die Lautstärke ist auf {{volume}} gesetzt
 | 
			
		||||
Die Lautstärke ist bei {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume is already at maximum
 | 
			
		||||
I can't get any louder
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume reduced to {{volume}}
 | 
			
		||||
Volume decreased to {{volume}}
 | 
			
		||||
Volume is now {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume is now {{volume}}
 | 
			
		||||
Volume increased to {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume set to maximum level
 | 
			
		||||
Volume updated to maximum level
 | 
			
		||||
Volume changed to maximum level
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Audio is going to be muted
 | 
			
		||||
Sound is going to be muted
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume reset to {{volume}}
 | 
			
		||||
Volume restored to {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume set to {{volume}}
 | 
			
		||||
Volume updated to {{volume}}
 | 
			
		||||
Volume changed to {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume set to {{level}} percent
 | 
			
		||||
Volume updated to {{level}} percent
 | 
			
		||||
Volume changed to {{level}} percent
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
The volume is set to {{volume}}
 | 
			
		||||
The volume is at {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
El volumen ya está al máximo
 | 
			
		||||
No se puede poner más fuerte
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volumen reducido a {{volume}}
 | 
			
		||||
Volumen bajado a {{volume}}
 | 
			
		||||
El volumen está al {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
El volumen está al {{volume}}
 | 
			
		||||
Volumen subido al {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volumen a máximo nivel
 | 
			
		||||
Volumen actualizado a máximo nivel
 | 
			
		||||
Volumen cambiado a máximo nivel
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
El audio se silenciará
 | 
			
		||||
El sonido se silenciará
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
El volumen se volverá a poner al {{volume}}
 | 
			
		||||
El volumen restaurado al {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volumen puesto al {{volume}}
 | 
			
		||||
Volumen actualizado al {{volume}}
 | 
			
		||||
Volumen cambiado al {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volumen establecido al {{level}} por ciento
 | 
			
		||||
Volumen actualizado al {{level}} por ciento
 | 
			
		||||
Volumen cambiado al {{level}} por ciento
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
El volumen está establecido al {{volume}}
 | 
			
		||||
El volumen está al {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Le volume est déjà au maximum
 | 
			
		||||
Je ne peux pas être plus fort
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Le volume a été réduit à {{volume}}
 | 
			
		||||
Le volume a été baissé à {{volume}}
 | 
			
		||||
Le volume est maintenant à {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Le volume est maintenant à {{volume}}
 | 
			
		||||
Le volume a été augmenté à {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
L'audio va être mis en muet
 | 
			
		||||
Le son va être mis en muet
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume réinitialisé à {{volume}}
 | 
			
		||||
Volume restauré à {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume définit à {{volume}}
 | 
			
		||||
Volume mis à jour à {{volume}}
 | 
			
		||||
Volume changé à {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Le volume a été définit à {{volume}}
 | 
			
		||||
Le volume est à {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
A hangerő már maximumon van
 | 
			
		||||
Hangosabbra nem megy
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
A hangerő csökkentve. Új szint: {{volume}}
 | 
			
		||||
A hangerő lecsökkent a következő szintre: {{volume}}
 | 
			
		||||
A hangerő új szintje: {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
A hangerő új szintje: {{volume}}
 | 
			
		||||
A hangerő megnövelve. Új szint: {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
A hang elnémul
 | 
			
		||||
A hang elnémítva
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
A hangerő visszaállítva, értéke: {{volume}}
 | 
			
		||||
A hangerőt visszaállítottam, az új szint: {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
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}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
A hangerő szintje: {{volume}}
 | 
			
		||||
A hangerő értéke {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Il volume è già al massimo
 | 
			
		||||
Non posso aumentare di più il volume
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume ridotto a {{volume}}
 | 
			
		||||
Volume diminuito a {{volume}}
 | 
			
		||||
Il volume adesso è {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Il volume adesso è {{volume}}
 | 
			
		||||
Volume aumentato a {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume impostato a livello massimo
 | 
			
		||||
Volume aggiornato al massimo livello
 | 
			
		||||
Volume cambiato su livello massimo
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
L'audio sta per essere disattivato
 | 
			
		||||
Il suono sta per essere disattivato
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volume reimpostato a {{volume}}
 | 
			
		||||
Volume ripristinato a {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume impostato a {{volume}}
 | 
			
		||||
Volume aggiornato a {{volume}}
 | 
			
		||||
Volume modificato a {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume impostato a {{level}} percento
 | 
			
		||||
Volume aggiornato al {{level}} percento
 | 
			
		||||
Volume modificato al {{level}} percento
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Il volume è impostato a {{volume}}
 | 
			
		||||
Il volume è a {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Het geluidsniveau is al op maximum
 | 
			
		||||
Ik kan niet harder
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Geluidsniveau verlaagd naar {{volume}}
 | 
			
		||||
Geluidsniveau afgenomen tot {{volume}}
 | 
			
		||||
Geluidsniveau is nu {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Geluidsniveau is nu {{volume}}
 | 
			
		||||
Geluidsniveau toegenomen tot {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Audio zal worden gedempt
 | 
			
		||||
Geluid zal worden gedempt
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Geluidsniveau reset naar {{volume}}
 | 
			
		||||
Geluidsniveau hersteld naar {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Geluidsniveau gezet op {{volume}}
 | 
			
		||||
Geluidsniveau bijgewerkt naar {{volume}}
 | 
			
		||||
Geluidsniveau gewijzigd naar {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volume op {{level}} procent ingesteld
 | 
			
		||||
Volume naar {{level}} procent bijgewerkt
 | 
			
		||||
Volume in {{level}} procent veranderd
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Het geluidsniveau is gezet op {{volume}}
 | 
			
		||||
Het geluidsniveau staat op {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Громкость уже на максимуме
 | 
			
		||||
Я не могу быть громче
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Громкость уменьшена к {{volume}}
 | 
			
		||||
Громкость убавлена до {{volume}}
 | 
			
		||||
Громкость теперь {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Громкость теперь {{volume}}
 | 
			
		||||
Громкость увеличена до {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Перехожу в режим без звука
 | 
			
		||||
Звук будет выключен
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Громкость перезагружена на {{volume}}
 | 
			
		||||
Громкость восстановлена до {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Громкость установлена на {{volume}}
 | 
			
		||||
Громкость обновлена до {{volume}}
 | 
			
		||||
Громкость изменена на {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Уровень звука установлен на {{volume}}
 | 
			
		||||
Уровень звука {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volymen är redan på max
 | 
			
		||||
Jag kan inte höja mer
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volymen har sänkts till {{volume}}
 | 
			
		||||
Volymen sänktes till {{volume}}
 | 
			
		||||
Volymen är nu {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volymen är nu {{volume}}
 | 
			
		||||
Volymen ökades till {{volume}}
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Audio kommer att tystas
 | 
			
		||||
Ljudet kommer att tystas
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volymen har återställts till {{volume}}
 | 
			
		||||
Volymen har återställts till {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volymen har satts till {{volume}}
 | 
			
		||||
Volymen har ändrats till {{volume}}
 | 
			
		||||
Volymen är nu {{volume}}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
Volymen har satts till {{level}} procent
 | 
			
		||||
Volymen har ändrats till {{level}} procent
 | 
			
		||||
Volymen är nu {{level}} procent
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
Volymen är satt till {{volume}}
 | 
			
		||||
Volymen är satt till {{volume}}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
skillMetadata:
 | 
			
		||||
  sections:
 | 
			
		||||
  - name: Ducking
 | 
			
		||||
    fields:
 | 
			
		||||
    - name: ducking
 | 
			
		||||
      type: checkbox
 | 
			
		||||
      label: Duck while listening
 | 
			
		||||
      value: "true"
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "set volume to 3",
 | 
			
		||||
  "intent_type": "SetVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Level": "3"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "reset volume",
 | 
			
		||||
  "intent_type": "UnmuteVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Unmute": "reset"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "update volume to 11",
 | 
			
		||||
  "intent_type": "SetVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Level": "11"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "increase volume",
 | 
			
		||||
  "intent_type": "IncreaseVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Increase": "increase"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "rise volume",
 | 
			
		||||
  "intent_type": "IncreaseVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Increase": "rise"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "decrease volume",
 | 
			
		||||
  "intent_type": "DecreaseVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Decrease": "decrease"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "reduce volume",
 | 
			
		||||
  "intent_type": "DecreaseVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Decrease": "reduce"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "set volume to quiet",
 | 
			
		||||
  "intent_type": "SetVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Level": "quiet"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "update volume to normal",
 | 
			
		||||
  "intent_type": "SetVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Level": "normal"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "utterance": "change volume to loud",
 | 
			
		||||
  "intent_type": "SetVolume",
 | 
			
		||||
  "intent": {
 | 
			
		||||
    "Volume": "volume",
 | 
			
		||||
    "Level": "loud"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
sænk
 | 
			
		||||
reducere
 | 
			
		||||
sænk
 | 
			
		||||
sænk
 | 
			
		||||
lavere
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
hæv
 | 
			
		||||
hæv
 | 
			
		||||
boost
 | 
			
		||||
øg
 | 
			
		||||
skru op
 | 
			
		||||
højere
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user