Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: not displaying on 4/6/8 mic HAT's #2

Merged
merged 5 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/license_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Run License Tests
on:
push:
workflow_dispatch:
pull_request:
branches:
- dev
jobs:
license_tests:
uses: openvoiceos/.github/.github/workflows/license_tests.yml@feat/shared_actions1
with:
system_deps: python3-lgpio liblgpio-dev
pip_packages: wheel
5 changes: 3 additions & 2 deletions readme.md → README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Add the following to your `~/.config/mycroft/mycroft.conf` file
{
"PHAL": {
"ovos-PHAL-plugin-dotstar": {
"dotstar_hat": "ADAFRUIT2"
"dotstar_hat": "ADAFRUIT2MIC"
}
}
}
Expand All @@ -62,8 +62,9 @@ There are two pre-existing plugins that either need uninstalled with pip, or bla

### TODO

- [ ] Add more animations
- [x] Add more animations
- [ ] User configurable colors
- [ ] User configurable animations
- [ ] Add github tests and automation

Please enjoy this plugin and don't be afraid to create an [issue](#) if you run into any problems.
118 changes: 69 additions & 49 deletions ovos_PHAL_plugin_dotstar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,43 @@
from time import sleep

from adafruit_dotstar import DotStar
import board
from gpiozero import LED
from RPi.GPIO import cleanup

from ovos_bus_client.message import Message
from ovos_plugin_manager.phal import PHALPlugin
from ovos_plugin_manager.templates.phal import PHALValidator
from ovos_utils.log import LOG
from ovos_config.config import Configuration

from ovos_PHAL.detection import is_respeaker_2mic, is_respeaker_4mic, is_respeaker_6mic
from ovos_i2c_detection import is_wm8960, is_respeaker_4mic, is_respeaker_6mic

from lingua_franca.util.colors import Color
from lingua_franca.internal import load_language

from ovos_PHAL_plugin_dotstar.boards import RESPEAKER2MIC, RESPEAKER4_6_8MIC, ADAFRUIT2MIC
# from ovos_PHAL_plugin_dotstar.boards import RESPEAKER2MIC, RESPEAKER4_6_8MIC, ADAFRUIT2MIC
from ovos_PHAL_plugin_dotstar.leds import DotStarLed
from ovos_PHAL_plugin_dotstar.animations import animations

from ovos_PHAL_plugin_dotstar.light_patterns import BreathAnimation , ChaseAnimation
# File defined in ovos-i2csound
# https://github.com/OpenVoiceOS/ovos-i2csound/blob/dev/ovos-i2csound#L76
I2C_PLATFORM_FILE = "/etc/OpenVoiceOS/i2c_platform"


I2C_PLATFORM_FILE = "/home/ovos/.config/mycroft/i2c_platform"

PREDEFINED_CARDS = {
"WM8960": RESPEAKER2MIC,
"RESPEAKER4": RESPEAKER4_6_8MIC,
"RESPEAKER6": RESPEAKER4_6_8MIC,
"ADAFRUIT2": ADAFRUIT2MIC
PREDEFINED_HATS = {
"WM8960": DotStar(board.D11, board.D10, 3, brightness=0.2),
"RESPEAKER4": DotStar(board.D11, board.D10, 12, brightness=0.2),
"RESPEAKER6": DotStar(board.D11, board.D10, 12, brightness=0.2),
"ADAFRUIT2MIC": DotStar(board.D6, board.D5, 3, brightness=0.2)
}


def check_i2c_platform():
if exists(I2C_PLATFORM_FILE):
with open(I2C_PLATFORM_FILE, "r") as f:
platform = f.readline().strip().lower()
if platform in PREDEFINED_CARDS:
platform = f.readline().strip()
LOG.debug(f"platform in check_i2c_platform: {platform}")
if platform in PREDEFINED_HATS:
LOG.debug(f"detected {platform} in i2c_platform")
return platform
return None
Expand All @@ -49,14 +54,8 @@ def validate(config=None):
if config.get("enabled"):
LOG.debug("user enabled")
return True
# Check for a file created by ovos-i2csound
# https://github.com/OpenVoiceOS/ovos-i2csound/blob/dev/ovos-i2csound#L76
LOG.debug(f"checking file {I2C_PLATFORM_FILE}")
if check_i2c_platform():
LOG.debug("checking i2c_platform")
return True
# Try a direct hardware check
if is_respeaker_2mic() or is_respeaker_4mic() or is_respeaker_6mic():
if is_wm8960() or is_respeaker_4mic() or is_respeaker_6mic():
LOG.debug("direct hardware check")
return True
LOG.debug("no validation")
Expand All @@ -74,55 +73,76 @@ class DotStarLedControlPlugin(PHALPlugin):

def __init__(self, bus=None, config=None):
super().__init__(bus=bus, name="ovos-PHAL-plugin-dotstar", config=config)
self.leds = []
self._enable_pin = None
self.active_animation = None
self.ds = None
# Check and see if there is a configuration for a specific board
if self.config.get("dotstar_hat") and self.config.get("dotstar_hat") in PREDEFINED_CARDS:
LOG.debug(f"loading {self.config.get('dotstar_hat')}")
self.ds = PREDEFINED_CARDS[self.config.get("dotstar_hat")]

try:
self.ds = PREDEFINED_CARDS[check_i2c_platform()]
except KeyError as e:
LOG.error(e)
except Exception as e:
LOG.error(e)
finally:
if not self.ds:
self.ds = RESPEAKER4_6_8MIC

LOG.debug("Show activation lights")
self.ds.fill(Color.from_description("mycroft blue").rgb255)
if self.config.get("dotstar_hat"):
ds = self.config.get("dotstar_hat")
if ds in PREDEFINED_HATS:
LOG.debug(f"loading {ds} from config")
try:
self.ds = DotStarLed(PREDEFINED_HATS[ds])
except Exception as e:
LOG.error(f"Could not load {ds} from config: {e}")
elif isinstance(self.config.get("dotstar_hat"), dict):
try:
self.ds = DotStar(
ds["clock_pin"], ds["led_pin"], ds["num_led"], brightness=ds.get("brightness", 0.2))
self._enable_pin = ds.get("enable_pin", None)
except Exception as e:
LOG.error(f"Could not create led array: {e}")
else:
try:
self.ds = DotStarLed(PREDEFINED_HATS[check_i2c_platform()])
except KeyError as e:
LOG.debug(f"check_i2c_platform failed {e}")
except Exception as e:
LOG.error(e)
# No manual configuration and i2csound is not installed or failed
if not self.ds:
# Direct hardware checks
if is_wm8960:
self.ds = DotStarLed(PREDEFINED_HATS["WM8960"])
elif is_respeaker_4mic:
self.ds = DotStarLed(PREDEFINED_HATS["RESPEAKER4"])
elif is_respeaker_6mic:
self.ds = DotStarLed(PREDEFINED_HATS["RESPEAKER6"])
# All else fails, fall back to respeker 4mic
else:
self.ds = DotStarLed(PREDEFINED_HATS["RESPEAKER4"])

# Required for ReSpeaker 4/6/8 mic
if not is_wm8960():
LOG.debug("enable LED's")
cleanup(5)
self._enable_pin = LED(5)
self._enable_pin.on()

self.ds.fill(Color.from_description("Mycroft blue").rgb255)
sleep(1.0)
self.on_reset()

def on_record_begin(self, message=None):
LOG.debug("recording begin")
self.active_animation = BreathAnimation(
self.ds, Color.from_description("mycroft blue").rgb255)
self.active_animation.run()
self.active_animation = animations["breathe"](
self.ds, Color.from_description("mycroft blue"))
self.active_animation.start()

def on_record_end(self, message=None):
LOG.debug("record end")
self.on_reset()

def on_audio_output_start(self, message=None):
# for led in self.ds:
LOG.debug("I am talking")
self.active_animation = ChaseAnimation(
self.ds, Color.from_description("mycroft blue").rgb255)
self.active_animation.run()
self.active_animation = animations["blink"](
self.ds, Color.from_description("mycroft blue"), repeat=True)
self.active_animation.start()

def on_audio_output_end(self, message=None):
LOG.debug("done talking")
self.on_reset()

def on_think(self, message=None):
self.on_reset()

def on_reset(self, message=None):
LOG.debug("resetting")
if self.active_animation:
self.active_animation.stop()
self.active_animation = None
Expand Down
Loading