diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..88e8aa6
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,18 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+/.gitattributes linguist-generated
+/.github/workflows/license_tests.yml linguist-generated
+/.github/workflows/propose_release.yml linguist-generated
+/.github/workflows/publish_alpha.yml linguist-generated
+/.github/workflows/publish_release.yml linguist-generated
+/.github/workflows/pull-request-lint.yml linguist-generated
+/.github/workflows/skill_tests.yml linguist-generated
+/.github/workflows/update_skill_json.yml linguist-generated
+/.gitignore linguist-generated
+/.projen/** linguist-generated
+/.projen/deps.json linguist-generated
+/.projen/files.json linguist-generated
+/.projen/tasks.json linguist-generated
+/requirements.txt linguist-generated
+/setup.py linguist-generated
+/version.py linguist-generated
\ No newline at end of file
diff --git a/.github/workflows/license_tests.yml b/.github/workflows/license_tests.yml
new file mode 100644
index 0000000..d1a6943
--- /dev/null
+++ b/.github/workflows/license_tests.yml
@@ -0,0 +1,16 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: license_tests
+on:
+ push: {}
+ workflow_dispatch: {}
+ pull_request:
+ branches:
+ - master
+ - main
+jobs:
+ license_tests:
+ name: license_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/license_tests.yml@master
diff --git a/.github/workflows/propose_release.yml b/.github/workflows/propose_release.yml
new file mode 100644
index 0000000..9c17c54
--- /dev/null
+++ b/.github/workflows/propose_release.yml
@@ -0,0 +1,41 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: propose_release
+on:
+ workflow_dispatch:
+ inputs:
+ release_type:
+ type: choice
+ description: Release Type
+ options:
+ - build
+ - minor
+ - major
+ - patch
+ - alpha
+jobs:
+ update_version:
+ name: update_version
+ permissions:
+ contents: write
+ packages: write
+ uses: neongeckocom/.github/.github/workflows/propose_semver_release.yml@master
+ with:
+ release_type: ${{ inputs.release_type }}
+ version_file: version.py
+ alpha_var: VERSION_ALPHA
+ build_var: VERSION_BUILD
+ minor_var: VERSION_MINOR
+ major_var: VERSION_MAJOR
+ update_changelog: true
+ branch: dev
+ pull_changes:
+ needs: update_version
+ permissions:
+ contents: write
+ uses: neongeckocom/.github/.github/workflows/pull_master.yml@master
+ with:
+ pr_assignee: ${{ github.actor }}
+ pr_draft: false
+ pr_title: ${{ needs.update_version.outputs.version }}
+ pr_body: ${{ needs.update_version.outputs.changelog }}
diff --git a/.github/workflows/publish_alpha.yml b/.github/workflows/publish_alpha.yml
new file mode 100644
index 0000000..41db5ec
--- /dev/null
+++ b/.github/workflows/publish_alpha.yml
@@ -0,0 +1,33 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: publish_alpha
+on:
+ push:
+ branches:
+ - dev
+ paths:
+ - "!version.py"
+ - "!test/**"
+ - "!examples/**"
+ - "!.github/**"
+ - "!.gitignore"
+ - "!LICENSE"
+ - "!CHANGELOG.md"
+ - "!MANIFEST.in"
+ - "!README.md"
+ - "!scripts/*"
+ workflow_dispatch: {}
+jobs:
+ publish_alpha_release:
+ permissions:
+ contents: write
+ packages: write
+ uses: neongeckocom/.github/.github/workflows/publish_alpha_release.yml@master
+ with:
+ version_file: version.py
+ publish_prerelease: true
+ update_changelog: true
+ alpha_var: VERSION_ALPHA
+ build_var: VERSION_BUILD
+ minor_var: VERSION_MINOR
+ major_var: VERSION_MAJOR
diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml
new file mode 100644
index 0000000..83fb68f
--- /dev/null
+++ b/.github/workflows/publish_release.yml
@@ -0,0 +1,16 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: publish_release
+on:
+ push:
+ branches:
+ - master
+ - main
+jobs:
+ build_and_publish_pypi_and_release:
+ permissions:
+ contents: write
+ packages: write
+ uses: neongeckocom/.github/.github/workflows/publish_stable_release.yml@master
+ secrets:
+ PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
diff --git a/.github/workflows/pull-request-lint.yml b/.github/workflows/pull-request-lint.yml
new file mode 100644
index 0000000..b3b262d
--- /dev/null
+++ b/.github/workflows/pull-request-lint.yml
@@ -0,0 +1,29 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: pull-request-lint
+on:
+ pull_request_target:
+ types:
+ - labeled
+ - opened
+ - synchronize
+ - reopened
+ - ready_for_review
+ - edited
+jobs:
+ validate:
+ name: Validate PR title
+ runs-on: ubuntu-latest
+ permissions:
+ pull-requests: write
+ steps:
+ - uses: amannn/action-semantic-pull-request@v5.0.2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ types: |-
+ feat
+ fix
+ chore
+ requireScope: false
+ githubBaseUrl: ${{ github.api_url }}
diff --git a/.github/workflows/skill_tests.yml b/.github/workflows/skill_tests.yml
new file mode 100644
index 0000000..d46565d
--- /dev/null
+++ b/.github/workflows/skill_tests.yml
@@ -0,0 +1,32 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: skill_tests
+on:
+ pull_request: {}
+ workflow_dispatch: {}
+jobs:
+ py_build_tests:
+ name: py_build_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/python_build_tests.yml@master
+ skill_unit_tests:
+ name: skill_unit_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/skill_tests.yml@master
+ skill_intent_tests:
+ name: skill_intent_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/skill_test_intents.yml@master
+ skill_resource_tests:
+ name: skill_resource_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/skill_test_resources.yml@master
+ skill_install_tests:
+ name: skill_install_tests
+ permissions:
+ contents: read
+ uses: neongeckocom/.github/.github/workflows/skill_test_installation.yml@master
diff --git a/.github/workflows/update_skill_json.yml b/.github/workflows/update_skill_json.yml
new file mode 100644
index 0000000..0392efc
--- /dev/null
+++ b/.github/workflows/update_skill_json.yml
@@ -0,0 +1,11 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+
+name: update_skill_json
+on:
+ push: {}
+jobs:
+ update-skill-json:
+ name: update_skill_json
+ permissions:
+ contents: write
+ uses: neongeckocom/.github/.github/workflows/skill_update_json_spec.yml@master
diff --git a/.gitignore b/.gitignore
index 4eb3651..2ef43af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,93 @@
+# ~~ Generated by projen. To modify, edit .projenrc.json and run "npx projen".
+node_modules/
+!/.gitattributes
+!/.projen/tasks.json
+!/.projen/deps.json
+!/.projen/files.json
+!/.github/workflows/pull-request-lint.yml
+.DS_Store
+node_modules
__pycache__/
-*.qmlc
-settings.json
-
+*.py[cod]
+*$py.class
+*.so
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+*.manifest
+*.spec
+pip-log.txt
+pip-delete-this-directory.txt
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+*.mo
+*.pot
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+instance/
+.webassets-cache
+.scrapy
+docs/_build/
+.pybuilder/
+target/
+.ipynb_checkpoints
+profile_default/
+ipython_config.py
+__pypackages__/
+celerybeat-schedule
+celerybeat.pid
+*.sage.py
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+.spyderproject
+.spyproject
+.ropeproject
+/site
+.mypy_cache/
+.dmypy.json
+dmypy.json
+.pyre/
+.pytype/
+cython_debug/
+!/setup.py
+!/requirements.txt
+!/version.py
+!/.github/workflows/license_tests.yml
+!/.github/workflows/propose_release.yml
+!/.github/workflows/publish_alpha.yml
+!/.github/workflows/publish_release.yml
+!/.github/workflows/skill_tests.yml
+!/.github/workflows/update_skill_json.yml
diff --git a/.pep8speaks.yml b/.pep8speaks.yml
deleted file mode 100644
index d9412fc..0000000
--- a/.pep8speaks.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-pycodestyle:
- max-line-length: 79
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index da9f3f3..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-arch:
- - amd64
- - arm64
-os: linux
-language: python
-before_install:
- - pip install pep8
-python:
- - "3.6"
- - "3.7"
- - "3.8"
- - "3.9"
-script:
- - pep8 __init__.py
diff --git a/README.md b/README.md
index cd04436..6856f7a 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,25 @@
-
-[![Build Status](https://travis-ci.com/smartgic/mycroft-magicmirror-wakeword-skill.svg?branch=20.8.1)](https://travis-ci.com/github/smartgic/mycroft-magicmirror-wakeword-skill) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-pink.svg?style=flat)](https://github.com/smartgic/mycroft-magicmirror-wakeword-skill/pulls) [![Skill: MIT](https://img.shields.io/badge/mycroft.ai-skill-blue)](https://mycroft.ai) [![Discord](https://img.shields.io/discord/809074036733902888)](https://discord.gg/Vu7Wmd9j)
-
+[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-pink.svg?style=flat)](https://github.com/smartgic/mycroft-magicmirror-wakeword-skill/pulls) [![Skill: MIT](https://img.shields.io/badge/ovos-skill-blue)](https://openvoiceos.org) [![Discord](https://img.shields.io/discord/809074036733902888)](https://discord.gg/Vu7Wmd9j)
# MagicMirror² wake word detection
-Image and message indicators Mycroft AI on MagicMirrot²
+Image and message display on MagicMirror² when Open Voice OS is listening.
## About
[MagicMirror²](https://magicmirror.builders/) is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.
-This skill interacts with MagicMirror² to let you know if Mycroft is listening. When a wake word is detected the an image and message are display on the screen and when the recording is done image and the message disappear.
+This skill interacts with MagicMirror² to let you know if OVOS is listening. When a wake word is detected the an image and message are display on the screen and when the recording is done image and the message disappear.
-
+
## Examples
-There is no example because there is no voice interaction with Mycroft AI.
+There is no example because there is no voice interaction with Open Voice OS.
## Installation
-Make sure to be within the Mycroft `virtualenv` before running the `msm` command.
-
-```
-$ . mycroft-core/venv-activate.sh
-$ msm install https://github.com/smartgic/mycroft-magicmirror-wakeword-skill.git
+```shell
+$ pip install ovos-magicmirror-wakeword-skill
```
## Configuration
@@ -35,6 +30,12 @@ This skill utilizes the `settings.json` file which allows you to configure this
Fill this out with your appropriate information and hit save.
+## MagicMirror configuration
+
+In order to reach the `/ovos` route on your MagicMirror, you need to allow the remote connection for a specific IP address or for a network range.
+
+Please have a look here: https://github.com/smartgic/MMM-ovos-wakeword
+
## Credits
Smart'Gic
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index 246253d..0000000
--- a/__init__.py
+++ /dev/null
@@ -1,106 +0,0 @@
-"""MagicMirror wake word entrypoint skill
-"""
-from mycroft import MycroftSkill
-import json
-import requests
-
-__author__ = 'smartgic'
-
-
-class MagicMirrorWakeWord(MycroftSkill):
- """This is the place where all the magic happens for the Sonos
- controller skill.
- """
-
- def __init__(self):
- MycroftSkill.__init__(self)
-
- # Initialize variables with empty or None values
- self.configured = False
- self.headers = {}
-
- def _setup(self):
- """Provision initialized variables and retrieve configuration
- from home.mycroft.ai.
- """
- self.url = self.settings.get('url')
- self.key = self.settings.get('key')
- self.verify = self.settings.get('verify')
-
- # Make sure the requirements are fulfill.
- if not self.url or not self.key:
- self.speak_dialog('error.setup',
- data={"field": "address or api key"})
- self.log.warning('MagicMirror address or API key not defined')
- else:
- self.configured = True
-
- # Construct the headers dict.
- self.headers['Content-Type'] = 'application/json'
- self.headers['X-Api-Key'] = self.key
-
- self.log.info('MagicMirror address: {}'.format(self.url))
-
- def initialize(self):
- """The initialize method is called after the Skill is fully
- constructed and registered with the system. It is used to perform
- any final setup for the Skill including accessing Skill settings.
- https://tinyurl.com/4pevkdhj
- """
- self.settings_change_callback = self.on_websettings_changed
- self.on_websettings_changed()
-
- def on_websettings_changed(self):
- """Each Mycroft device will check for updates to a users settings
- regularly, and write these to the Skills settings.json.
- https://tinyurl.com/f2bkymw
- """
- self._setup()
- self._run()
-
- def _run(self):
- """Based on event, functions will be called to send different
- notifications.
- """
- if self.configured:
- try:
- # Catch events
- self.add_event('recognizer_loop:record_begin',
- self._handle_listener_started)
- self.add_event('recognizer_loop:record_end',
- self._handle_listener_ended)
- except Exception:
- self.log.error('Cannot initialize MagicMirror skill')
- self.speak_dialog('error.initialize')
-
- def _handle_listener_started(self):
- """Handle the record_begin event detection.
- """
- payload = {"notification": "MYCROFT_SEND_MESSAGE",
- "payload": "Listening"}
- try:
- requests.post(url=self.url + '/mycroft',
- data=json.dumps(payload),
- headers=self.headers,
- verify=self.verify)
- except requests.exceptions.RequestException as err:
- return err
-
- def _handle_listener_ended(self):
- """Handle the record_end event detection.
- """
- payload = {"notification": "MYCROFT_DELETE_MESSAGE",
- "payload": "delete"}
- try:
- requests.post(url=self.url + '/mycroft',
- data=json.dumps(payload),
- headers=self.headers,
- verify=self.verify)
- except requests.exceptions.RequestException as err:
- return err
-
-
-def create_skill():
- """Main function to register the skill
- """
- return MagicMirrorWakeWord()
diff --git a/dialog/en-us/error.initialize.dialog b/dialog/en-us/error.initialize.dialog
deleted file mode 100644
index 3aae84f..0000000
--- a/dialog/en-us/error.initialize.dialog
+++ /dev/null
@@ -1 +0,0 @@
-I am having trouble to initialize the Magic Mirror wake word skill. The Skill will not load.
\ No newline at end of file
diff --git a/dialog/fr-fr/ error.initialize.dialog b/dialog/fr-fr/ error.initialize.dialog
deleted file mode 100644
index 6c1fb76..0000000
--- a/dialog/fr-fr/ error.initialize.dialog
+++ /dev/null
@@ -1 +0,0 @@
-Je rencontre des difficultés à initialiser la compétence Magic Mirror wake word. La compétence ne sera pas chargée.
\ No newline at end of file
diff --git a/manifest.yml b/manifest.yml
deleted file mode 100644
index faac28c..0000000
--- a/manifest.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-dependencies:
- python:
- - requests
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..41073de
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+ovos-workshop
+requests
diff --git a/settingsmeta.json b/settingsmeta.json
new file mode 100644
index 0000000..870e08d
--- /dev/null
+++ b/settingsmeta.json
@@ -0,0 +1,35 @@
+{
+ "skillMetadata": {
+ "sections": [
+ {
+ "name": "Configuration",
+ "fields": [
+ {
+ "name": "url",
+ "type": "text",
+ "label": "MagicMirror URL",
+ "value": "http://localhost:8080"
+ },
+ {
+ "name": "key",
+ "type": "password",
+ "label": "MagicMirror API key",
+ "value": ""
+ },
+ {
+ "name": "timeout",
+ "type": "number",
+ "label": "HTTP request timeout in second",
+ "value": 10
+ },
+ {
+ "name": "verify",
+ "type": "checkbox",
+ "label": "Verify SSL certificate",
+ "value": false
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/settingsmeta.yaml b/settingsmeta.yaml
deleted file mode 100644
index 1511d16..0000000
--- a/settingsmeta.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-skillMetadata:
- sections:
- - name: Configuration
- fields:
- - name: url
- type: text
- label: MagicMirror URL
- value: "http://localhost:8080"
- - name: key
- type: password
- label: MagicMirror API key
- value: ""
- - name: verify
- type: checkbox
- label: Verify SSL certificate
- value: "false"
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..b467826
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+from setuptools import setup
+from os import walk, path
+
+BASEDIR = path.abspath(path.dirname(__file__))
+URL = "https://github.com/smartgic/skill-ovos-mm-wakeword"
+SKILL_CLAZZ = "MagicMirrorWakeWord"
+PYPI_NAME = "skill-ovos-mm-wakeword"
+
+SKILL_AUTHOR, SKILL_NAME = URL.split(".com/")[-1].split("/")
+SKILL_PKG = SKILL_NAME.lower().replace("-", "_")
+PLUGIN_ENTRY_POINT = (
+ f"{SKILL_NAME.lower()}.{SKILL_AUTHOR.lower()}={SKILL_PKG}:{SKILL_CLAZZ}"
+)
+BASE_PATH = BASE_PATH = path.abspath(path.join(path.dirname(__file__), ""))
+
+
+def get_version():
+ """Find the version of the package"""
+ version = None
+ version_file = path.join(BASE_PATH, "version.py")
+ major, minor, build, alpha = (None, None, None, None)
+ with open(version_file) as f:
+ for line in f:
+ if "VERSION_MAJOR" in line:
+ major = line.split("=")[1].strip()
+ elif "VERSION_MINOR" in line:
+ minor = line.split("=")[1].strip()
+ elif "VERSION_BUILD" in line:
+ build = line.split("=")[1].strip()
+ elif "VERSION_ALPHA" in line:
+ alpha = line.split("=")[1].strip()
+
+ if (major and minor and build and alpha) or "# END_VERSION_BLOCK" in line:
+ break
+ version = f"{major}.{minor}.{build}"
+ if alpha and int(alpha) > 0:
+ version += f"a{alpha}"
+ return version
+
+
+def get_requirements(requirements_filename: str):
+ requirements_file = path.join(path.dirname(__file__), requirements_filename)
+ with open(requirements_file, "r", encoding="utf-8") as r:
+ requirements = r.readlines()
+ requirements = [
+ r.strip() for r in requirements if r.strip() and not r.strip().startswith("#")
+ ]
+ return requirements
+
+
+def find_resource_files():
+ resource_base_dirs = ("locale", "intents", "dialog", "vocab", "regex", "ui")
+ package_data = ["*.json"]
+ for res in resource_base_dirs:
+ if path.isdir(path.join(BASE_PATH, res)):
+ for directory, _, files in walk(path.join(BASE_PATH, res)):
+ if files:
+ package_data.append(
+ path.join(directory.replace(BASE_PATH, "").lstrip("/"), "*")
+ )
+ return package_data
+
+
+with open("README.md", "r") as f:
+ long_description = f.read()
+
+setup(
+ name=PYPI_NAME,
+ version=get_version(),
+ description="",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ url=URL,
+ author="Gaëtan Trellu",
+ author_email="gaetan.trellu@gmail.com",
+ license="MIT",
+ package_dir={SKILL_PKG: "skill_mm_wakeword"},
+ package_data={SKILL_PKG: find_resource_files()},
+ packages=[SKILL_PKG],
+ include_package_data=True,
+ install_requires=get_requirements("requirements.txt"),
+ keywords="ovos skill voice assistant",
+ entry_points={"ovos.plugin.skill": PLUGIN_ENTRY_POINT},
+)
diff --git a/skill.json b/skill.json
new file mode 100644
index 0000000..f077e5a
--- /dev/null
+++ b/skill.json
@@ -0,0 +1,52 @@
+{
+ "title": "MagicMirror\u00b2 wake word detection",
+ "url": "https://github.com/smartgic/skill-ovos-mm-wakeword",
+ "summary": "Image and message display on MagicMirror\u00b2 when Open Voice OS is listening.",
+ "short_description": "Image and message display on MagicMirror\u00b2 when Open Voice OS is listening.",
+ "description": "[MagicMirror\u00b2](https://magicmirror.builders/) is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror\u00b2 allows you to convert your hallway or bathroom mirror into your personal assistant. This skill interacts with MagicMirror\u00b2 to let you know if OVOS is listening. When a wake word is detected the an image and message are display on the screen and when the recording is done image and the message disappear. ",
+ "examples": [],
+ "desktopFile": false,
+ "warning": "",
+ "systemDeps": false,
+ "requirements": {
+ "python": [
+ "ovos-workshop",
+ "requests"
+ ],
+ "system": {},
+ "skill": []
+ },
+ "incompatible_skills": [],
+ "platforms": [
+ "i386",
+ "x86_64",
+ "ia64",
+ "arm64",
+ "arm"
+ ],
+ "branch": "master",
+ "license": null,
+ "icon": "docs/magicmirror.png",
+ "category": "IoT",
+ "categories": [
+ "IoT"
+ ],
+ "tags": [
+ "smartmirror",
+ "magicmirror",
+ "wakeword",
+ "raspberrypi",
+ "smarthome",
+ "picroft"
+ ],
+ "credits": [
+ "Smart'Gic"
+ ],
+ "skillname": "skill-ovos-mm-wakeword",
+ "authorname": "smartgic",
+ "foldername": null,
+ "header": "[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-pink.svg?style=flat)](https://github.com/smartgic/mycroft-magicmirror-wakeword-skill/pulls) [![Skill: MIT](https://img.shields.io/badge/ovos-skill-blue)](https://openvoiceos.org) [![Discord](https://img.shields.io/discord/809074036733902888)](https://discord.gg/Vu7Wmd9j)",
+ "installation": "```shell $ pip install ovos-magicmirror-wakeword-skill ```",
+ "configuration": "This skill utilizes the `settings.json` file which allows you to configure this skill via `home.mycroft.ai` after a few seconds of having the skill installed you should see something like below in the https://home.mycroft.ai/#/skill location: Fill this out with your appropriate information and hit save.",
+ "magicmirror configuration": "In order to reach the `/ovos` route on your MagicMirror, you need to allow the remote connection for a specific IP address or for a network range. Please have a look here: https://github.com/smartgic/MMM-ovos-wakeword"
+}
\ No newline at end of file
diff --git a/skill_mm_wakeword/__init__.py b/skill_mm_wakeword/__init__.py
new file mode 100644
index 0000000..98f1f54
--- /dev/null
+++ b/skill_mm_wakeword/__init__.py
@@ -0,0 +1,62 @@
+import json
+import requests
+
+from ovos_bus_client.message import Message
+from ovos_utils.log import LOG
+from ovos_workshop.skills import OVOSSkill
+
+
+class MagicMirrorWakeWord(OVOSSkill):
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.configured = False
+ self.headers = {}
+
+ def setup(self):
+ if not self.settings.get("url") or not self.settings.get("key"):
+ self.speak_dialog("error_setup", data={"fields": "address or key"})
+ LOG.warning("MagicMirror address or API key not defined")
+ else:
+ self.configured = True
+ self.headers["Content-Type"] = "application/json"
+ self.headers["X-Api-Key"] = self.settings.get("key")
+ LOG.info("MagicMirror address: %s", self.settings.get("url"))
+
+ def initialize(self):
+ self.setup()
+ self.add_event("recognizer_loop:record_begin", self.handle_listener_started)
+ self.add_event("recognizer_loop:record_end", self.handle_listener_ended)
+
+ def handle_listener_started(
+ self, message: Message
+ ): # pylint: disable=unused-argument
+ """Handle the record_begin event detection."""
+ payload = {"notification": "OVOS_SEND_MESSAGE", "payload": "Listening"}
+ try:
+ requests.post(
+ url=self.settings.get("url") + "/ovos",
+ data=json.dumps(payload),
+ headers=self.headers,
+ verify=self.settings.get("verify", False),
+ timeout=self.settings.get("timeout", 10),
+ )
+ except requests.exceptions.RequestException as err:
+ LOG.error(err)
+
+ def handle_listener_ended(
+ self, message: Message
+ ): # pylint: disable=unused-argument
+ """Handle the record_end event detection."""
+ payload = {"notification": "OVOS_DELETE_MESSAGE", "payload": "delete"}
+ try:
+ requests.post(
+ url=self.settings.get("url") + "/ovos",
+ data=json.dumps(payload),
+ headers=self.headers,
+ verify=self.settings.get("verify", False),
+ timeout=self.settings.get("timeout", 10),
+ )
+ except requests.exceptions.RequestException as err:
+ LOG.error(err)
diff --git a/dialog/en-us/error.setup.dialog b/skill_mm_wakeword/locale/en-us/dialog/error_setup.dialog
similarity index 58%
rename from dialog/en-us/error.setup.dialog
rename to skill_mm_wakeword/locale/en-us/dialog/error_setup.dialog
index 992ea02..f0f6161 100644
--- a/dialog/en-us/error.setup.dialog
+++ b/skill_mm_wakeword/locale/en-us/dialog/error_setup.dialog
@@ -1 +1 @@
-Please configure the Magic Mirror wake word skill settings at home dot mycroft dot ai, {field} are missing.
\ No newline at end of file
+Please configure the Magic Mirror wake word skill settings at home dot mycroft dot ai, {fields} are missing.
diff --git a/dialog/fr-fr/error.setup.dialog b/skill_mm_wakeword/locale/fr-fr/dialog/error_setup.dialog
similarity index 53%
rename from dialog/fr-fr/error.setup.dialog
rename to skill_mm_wakeword/locale/fr-fr/dialog/error_setup.dialog
index f21e881..7675df7 100644
--- a/dialog/fr-fr/error.setup.dialog
+++ b/skill_mm_wakeword/locale/fr-fr/dialog/error_setup.dialog
@@ -1 +1 @@
-Veuillez configurer la compétence Magic Mirror wake word en visitant home dot mycroft dot ai, {field} sont manquants.
\ No newline at end of file
+Veuillez configurer la compétence Magic Mirror wake word en visitant home dot mycroft dot ai, {fields} sont manquants.
diff --git a/skill_mm_wakeword/version.py b/skill_mm_wakeword/version.py
new file mode 100644
index 0000000..3d24a62
--- /dev/null
+++ b/skill_mm_wakeword/version.py
@@ -0,0 +1,4 @@
+VERSION_MAJOR = 0
+VERSION_MINOR = 0
+VERSION_BUILD = 1
+VERSION_ALPHA = 0
\ No newline at end of file