Skip to content

Commit

Permalink
Merge pull request #26 from ntrp/master
Browse files Browse the repository at this point in the history
Implement external settings
  • Loading branch information
Romkabouter authored Nov 22, 2020
2 parents 6817f8f + 4c1092a commit 5ef30cb
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 43 deletions.
1 change: 1 addition & 0 deletions PlatformIO/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
settings.ini
46 changes: 46 additions & 0 deletions PlatformIO/load_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Import ("env")
import os.path
import configparser
import hashlib
from string import Template

settings = "settings.ini"
sectionMatrix = "Matrix"
sectionWifi = "Wifi"
sectionOta = "OTA"
sectionMqtt = "MQTT"

if os.path.isfile(settings):
config = configparser.RawConfigParser()
config.read(settings)

otaPasswordHash = hashlib.md5(config[sectionOta]['password'].encode()).hexdigest()

env.Append(CPPDEFINES=[
("WIFI_SSID", "\\\"" + config[sectionWifi]["ssid"] + "\\\""),
("WIFI_PASS", "\\\"" + config[sectionWifi]["password"] + "\\\""),
("OTA_PASS_HASH", "\\\"" + otaPasswordHash + "\\\""),
("SITEID", "\\\"" + config[sectionMatrix]["siteId"] + "\\\""),
("HOSTNAME", "\\\"" + config[sectionMatrix]["hostname"] + "\\\""),
("MQTT_IP", "IPAddress\(" + config[sectionMqtt]["ip"].replace(".", ",") + "\)"),
("MQTT_HOST", "\\\"" + config[sectionMqtt]["hostname"] + "\\\""),
("MQTT_PORT", "\\\"" + config[sectionMqtt]["port"] + "\\\""),
("MQTT_USER", "\\\"" + config[sectionMqtt]["username"] + "\\\""),
("MQTT_PASS", "\\\"" + config[sectionMqtt]["password"] + "\\\""),
("MQTT_MAX_PACKET_SIZE", config[sectionMqtt]["maxPacketSize"])
])

env.Replace(
UPLOAD_PROTOCOL="espota",
UPLOAD_PORT=config[sectionMatrix]["hostname"],
UPLOAD_FLAGS=[
"--port=" + config[sectionOta]["port"],
"--auth=" + config[sectionOta]["password"],
"--timeout=30",
"--f=.pio/build/esp32dev/firmware.bin"
],
)
else:
print()
print("Please copy 'settings.ini.example' to 'settings.ini' and set the correct values before building")
exit(1)
21 changes: 2 additions & 19 deletions PlatformIO/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,23 @@
build_flags =
'-DFIXED_POINT=1'
'-DOUTSIDE_SPEEX=1'
'-DWIFI_SSID="SSID"' ; Change to your wifi ssid
'-DWIFI_PASS="password"' ; Change to your wifi password
'-DHOSTNAME="192.168.43.140"' ; Should match above upload_port
'-DSITEID="matrixvoice"' ; siteid is part of the MQTT topic
'-DMODELID="alexa"' ; modelid is part of the MQTT topic
'-DOTA_PASS_HASH="createmd5hash"' ; hashed with MD5 https://www.md5hashgenerator.com/
'-DMQTT_IP=IPAddress(192, 168, 43, 54)' ; Change to the IP of your MQTT broker
'-DMQTT_HOST="192.168.43.54"' ; Change to the IP of your MQTT broker
'-DMQTT_PORT=1883' ; Change to the port of your MQTT broker
'-DMQTT_USER="username"' ; Change to your MQTT username
'-DMQTT_PASS="password"' ; Change to your MQTT password
'-DMQTT_MAX_PACKET_SIZE=2000' ; This is required, otherwise audiopackets will not be send
'-lnn_model_alexa_wn3'
'-Llib/esp_sr'
'-lwakenet'
'-ldl_lib'
'-lc_speech_features'

[env:esp32dev]
extra_scripts = pre:load_settings.py
platform = [email protected]
upload_protocol = espota
board = esp32dev
framework = arduino
board_build.partitions = ../OTABuilder/partitions_two_ota.csv
; MatrixVoice ESP32 LAN name or IP, should match HOSTNAME in build_flags
upload_port = '192.168.43.140'
build_flags = ${common.build_flags}

; MatrixVoice OTA password (auth), should match hashed password (OTA_PASS_HASH) in build_flags
upload_flags =
--port=3232
--auth=unhashedmd5pass
--f=.pio/build/esp32dev/firmware.bin

lib_deps =
https://github.com/matrix-io/matrixio_hal_esp32.git
https://github.com/matrix-io/esp32-arduino-ota.git
Expand All @@ -54,4 +37,4 @@ lib_deps =
https://github.com/me-no-dev/AsyncTCP.git
https://github.com/knolleary/pubsubclient.git
https://github.com/bblanchon/ArduinoJson.git
ESP Async WebServer
ESP Async WebServer
19 changes: 19 additions & 0 deletions PlatformIO/settings.ini.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[Matrix]
hostname=192.168.43.140
siteId=matrixvoice

[Wifi]
ssid=SSID
password=password

[OTA]
password=OTA
port=3232

[MQTT]
ip=192.168.43.54
hostname=192.168.43.54
port=1883
username=username
password=password
maxPacketSize=2000
54 changes: 30 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,24 @@ The Arduino code is no longer maintained and will not be further developed, I fo
To get the code running I suggest you first reset the Voice if you have flashed it previously

- Follow Step 1 and 2 (or all steps) from this guide https://matrix-io.github.io/matrix-documentation/matrix-voice/esp32/
- ssh into the pi, execute this command: voice_esp32_enable. If you get a permission denied, execute the command again.
- esptool.py --chip esp32 --port /dev/ttyS0 --baud 115200 --before default_reset --after hard_reset erase_flash
- Reboot the Pi.
- Follow this guide on HacksterIO to get started: https://www.hackster.io/matrix-labs/program-matrix-voice-esp32-with-vs-code-using-platformio-3dd498, but in step 2 use "https://github.com/Romkabouter/Matrix-Voice-ESP32-MQTT-Audio-Streamer.git" and not the esp32-platformio repository. Also, the platform.ui file can be found in the PlatformIO subfolder, make the changes from step 3 in that file.
- After that you can use OTA, the platformIO is more stable then the Arduino version
- Once your environment is set up go into the PlatformIO directory
- Copy and configure the `settings.ini.example` to `settings.ini` and configure the proper parameters. Any `$` in the `settings.ini` will be threated as an environment variable, did not find a way to escape it yet, fixes or workarounds are welcome
- Build the project with PlatformIO, for example run `pio run` from the commandline
- Remotely flash the bin file using the provided script `sh deploy.sh pi@raspberry_ip_address`
- From this point one the MatrixVoice can run standalone and you should be able to update via OTA by running `pio run --target upload`

## Arduino (deprecated)

In the folder "MatrixVoiceAudioServer", there are two bin files:

- bootloader.bin
- partitions_two_ota.bin
These files are needed in order to do the first flashing. You can build your own versions of it by checking out the OTABuilder folder.
In OTABuilder is a program in c++, which does nothing but if you do a make menuconfig you will see that the partition is set to OTA.
When you do a make, the partitions_two_ota.bin will be in the build folder and the bootloader.bin in the build/bootloader folder.
These files are needed in order to do the first flashing. You can build your own versions of it by checking out the OTABuilder folder.
In OTABuilder is a program in c++, which does nothing but if you do a make menuconfig you will see that the partition is set to OTA.
When you do a make, the partitions_two_ota.bin will be in the build folder and the bootloader.bin in the build/bootloader folder.

To flash the OTA version for the first time, attach the Voice to a Raspberry Pi.

To flash the OTA version for the first time, attach the Voice to a Raspberry Pi.
- Get the HAL code from https://github.com/matrix-io/matrixio_hal_esp32/tree/master/components/hal
- Copy the folder "hal" to your Arduino IDE libraries folder
- Add to Arduino IDE: AsyncMqttClient https://github.com/marvinroger/async-mqtt-client
Expand All @@ -62,39 +64,43 @@ To flash the OTA version for the first time, attach the Voice to a Raspberry Pi.
- Make a change (or not) and do a Sketch -> Upload. The leds will turn WHITE
- Sometimes uploading fails, just retry until it succeeds.

If you change code and OTA does not work anymore for some reason, you can always start over by doing the "get started" part except for the first bullet
If you change code and OTA does not work anymore for some reason, you can always start over by doing the "get started" part except for the first bullet

## MQTT commands

The Matrix Voice Audio Server is subscribed to various topics.
The topic SITEID/everloop, where SITEID is the name you have given the device, is used for commands concerning the LED Ring.
When publishing to this topic, the everloop colors and brightness can be altered without coding, setting it to retained will update the settings as soon as the device is connected.
The message can contain 4 keys:
- brightness: integer value between 0 and 100 (%)
- idle: array of 4 codes: [red,green,blue,white], ranging 0-255
- hotword: array of 4 codes: [red,green,blue,white], ranging 0-255
- update: array of 4 codes: [red,green,blue,white], ranging 0-255
- disconnect: array of 4 codes: [red,green,blue,white], ranging 0-255

- brightness: integer value between 0 and 100 (%)
- idle: array of 4 codes: [red,green,blue,white], ranging 0-255
- hotword: array of 4 codes: [red,green,blue,white], ranging 0-255
- update: array of 4 codes: [red,green,blue,white], ranging 0-255
- disconnect: array of 4 codes: [red,green,blue,white], ranging 0-255

Example: {"brightness":20,"idle":[240,210,17,0],"hotword":[173,17,240,0],"update":[0,255,255,0]}

The topic SITEID/audio also can receive multiple commands:
* Mute/unmute microphones: publish {"mute_input":"true"} or {"mute_input":"false"}
* Mute/unmute playback: publishing {"mute_output":"true"} or {"mute_output":"false"}
* Change the amp to jack/speaker: publish {"amp_output":"0"} or {"amp_output":"1"}
* Adjust mic gain: publish {"gain":5}
* Change the framesize: publish {"framerate":256}, Limited to 32,64,128,256,512 or 1024.
* Switch local/remote hotword detection: publish {"hotword":"local"} or {"hotword":"remote"}, Local only supports "Alexa"
* Adjust volume: publish {"volume": 50}

Restart the device by publishing {"passwordhash":"yourpasswordhash"} to SITEID/restart
- Mute/unmute microphones: publish {"mute_input":"true"} or {"mute_input":"false"}
- Mute/unmute playback: publishing {"mute_output":"true"} or {"mute_output":"false"}
- Change the amp to jack/speaker: publish {"amp_output":"0"} or {"amp_output":"1"}
- Adjust mic gain: publish {"gain":5}
- Change the framesize: publish {"framerate":256}, Limited to 32,64,128,256,512 or 1024.
- Switch local/remote hotword detection: publish {"hotword":"local"} or {"hotword":"remote"}, Local only supports "Alexa"
- Adjust volume: publish {"volume": 50}

Restart the device by publishing {"passwordhash":"yourpasswordhash"} to SITEID/restart

## Roadmap

These features I want to implement in the future, not ordered in any way

- led animations
- 3D case including small speakers.

## Known issues
- Uploading sometimes fails or an error is thrown when the uploading is done.

- Uploading sometimes fails or an error is thrown when the uploading is done.
- On device hotword detection seems a bit slow and also the OTA seems to be impacted.

0 comments on commit 5ef30cb

Please sign in to comment.