Skip to content

Commit

Permalink
Finalize version 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bergdahl committed Nov 30, 2023
1 parent e34302c commit 6e19cbf
Show file tree
Hide file tree
Showing 22 changed files with 279 additions and 209 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_executable(Arduino_WOPR
examples/JBWopr_Firmware/JBWopr_Firmware.ino
src/ha/ha_abbr.h
src/ha/mdi_consts.h
examples/JBWopr_DeviceDemo/secrets.h

)

140 changes: 89 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# JBWOPR
# JBWopr

[![arduino-library-badge](https://www.ardu-badge.com/badge/JBWopr.svg?)](https://www.ardu-badge.com/JBWopr)
![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)

JBWopr is a helper library for the Arduino platform that allows you to easily interface with the
Unexpected Maker W.O.P.R. board.
Expand Down Expand Up @@ -39,7 +42,7 @@ that you can also use as a starting point for your own firmware.

Full code documentation is available at https://jonnybergdahl.github.io/jbwopr/

## JBWoprDevicee
## JBWoprDevice

Create an instance of the `JBWoprDevice` class. Do any configuration you need to do then
and call `begin()` in your `setup()` function. Then call `loop()` in your `loop()` function.
Expand Down Expand Up @@ -153,7 +156,7 @@ The following settings are available in the web portal:

![MQTT](images/mqttconfig.png "MQTT configuration")

## MQTT Topics
### MQTT Topics

At startup, the device will publish an availability message to the `<mqtt_prefix>/<device_id>/availability` topic
with the payload `online`. It will also set the last will topic to the same topic with the payload `offline`.
Expand All @@ -162,7 +165,30 @@ You can use that to check if the device is online or not.
Current device state is posted to the `<mqtt_prefix>/<device_id>/<entity>/state` topic, it is posted when
state is changed.

### Effects
#### Device

The device will listen to messages on the following topic to restart the device.

| Topic | Example payload | Comment |
|--------------------------------------------|-----------------|-----------|
| <mqtt_prefix>/<device_id>/device/state/set | `restart` | `restart` |

#### Configuration

The device will listen to messages on the following topic to change configuration.

| Topic | Example payload | Comment |
|---------------------------------------------------------|-----------------|--------------------|
| <mqtt_prefix>/<device_id>/config/date_format/set | `%Y-%m-%d` | Date format |
| <mqtt_prefix>/<device_id>/config/time_format/set | `%H %M %S` | Time format |
| <mqtt_prefix>/<device_id>/config/defcon_brightness/set | 50 | DEFCON brightness |
| <mqtt_prefix>/<device_id>/config/display_brightness/set | 50 | Display brightness |
| <mqtt_prefix>/<device_id>/config/effects_timeout/set | 30 | Effects timeout |
| <mqtt_prefix>/<device_id>/config/use_web_portal/set | `True` | Use web portal |

> The other settings defines the MQTT configuration so can't be set over MQTT.
#### Effects

The device will post a message to the following topics when an effect state is changed.

Expand All @@ -178,7 +204,7 @@ The device will listen to messages on the following topics.
| <mqtt_prefix>/<device_id>/effect/state/set | `ON` | `ON` / `OFF` |
| <mqtt_prefix>/<device_id>/effect/name/set | `Rainbow` | Registered name, will start effect as well |

### Display
#### Display

The device will post a message to the following topics when the display state is changed.

Expand All @@ -198,7 +224,7 @@ The device will listen to command messages on the following topics.
| <mqtt_prefix>/<device_id>/display/scrolltext/set | `Hello scrolling world` | ASCII characters only |
| <mqtt_prefix>/<device_id>/display/brightness/set | `50` | `0` to `100` |

### DEFCON LED's
#### DEFCON LED's

The device will post a message to the following topics when the DEFCON LED's state is changed.

Expand All @@ -218,7 +244,7 @@ The device will listen to command messages on the following topics.
| <mqtt_prefix>/<device_id>/display/brightness/set | `50` | `0` to `100` |
| <mqtt_prefix>/<device_id>/defcon/color/set | `0,0,128` | RGB byte values in format `R,G,B` |

### Buttons
#### Buttons

The device will post a message to the following topics when a button is clicked or double-clicked.

Expand All @@ -231,72 +257,84 @@ The device will post a message to the following topics when a button is clicked

## JBWoprHomeAssistantDevice

TODO
The `JBWoprHomeAssistantDevice` class adds Home Assistant support to the `JBWoprMqttDevice` class. It will publish
discovery data to the Home Assistant MQTT discovery topic when connected to the MQTT server.

### Topics
When a connection to the MQTT server is established, the device will publish a message to the
`<mqtt_prefix>/<homeassistant prefix>/status` topic with the payload `online`, and also set the last will topic
to the same topic with the payload `offline`. Home Assistant will use that to check if the device is online or not.

| Topic | Example payload | Comment |
|---------------------------------------------|-------------------------|---------------|
| <mqtt_prefix>/<device_id>/diagnostics/state | JSON payload, See below | Diagnostics |
| <mqtt_prefix>/<device_id>/config/state | JSON payload, See below | Configuration |
| <mqtt_prefix>/<device_id>/device/set | JSON payload, See below | Device state |
It will then proceed to publish discovery data to the `<mqtt_prefix>/<homeassistant prefix>/<entity>/config` topic,
followed by publishing diagnostics and configuration state in the form of JSON messages. It will finally publish
the individual entity states.

The following settings are available in the web portal:

![WiFiManager](images/haconfig.png "Home Assistant configuration")

### Home Assistant

Once the device has published discovery data to Home Assistant, it will be available under the
MQTT integration.

If web portal is enabled, the _Visit_ section will be active.

![Home Assistant Device](images/hadeviceinfo.png "Device info")

The following entities will be available under _Controls_.

![Home Assistant Controls](images/hacontrols.png "Controls")

The following entities will be available under _Configuration_.

![Home Assistant Configuration](images/haconfiguration.png "Configuration")

The following entities will be available under _Diagnostics_.

![Home Assistant Diagnostics](images/hadiagnostics.png "Diagnostics")

### MQTT Topics

`JBWoprHomeAssistantDevice` uses the same topics as the `JBWoprMqttDevice` class, and adds the following topics.

### Diagnostics

Diagnostic information is posted at startup.
| Topic | Example payload | Comment |
|---------------------------------------------|-------------------------|---------------|
| <mqtt_prefix>/<device_id>/diagnostics/state | JSON payload, See below | Diagnostics |

```json
{
"ipAddress": "172.30.2.210",
"rssi": -50,
"version": "1.0.0-beta3"
"ipAddress": "172.30.2.110",
"rssi": -52,
"ram": 201728,
"version": "1.0.0"
}

```

### Configuration

Current configuration is posted at startup.
| Topic | Example payload | Comment |
|---------------------------------------------|-------------------------|---------------|
| <mqtt_prefix>/<device_id>/config/state | JSON payload, See below | Configuration |

```json
{
"timeFormat": "%H %M %s",
"timeFormat": "%H %M %S",
"dateFormat": "%Y-%m-%d",
"defconBrightness": 50,
"displayBrightness": 50,
"defconLedsBrightness": 50,
"effectsTimeout": 30,
"wifiHostname": "wopr-5ccf7f2b9b2c",
"hostName": "wopr-461da0d8",
"useWebPortal": true,
"useMqtt": true,
"mqttServerName": "servername.local",
"mqttServerName": "172.30.2.64",
"mqttServerPort": 1883,
"mqttUserName": "username",
"mqttPassword": "password",
"mqttPrefix": "wopr"
"mqttUserName": "user",
"mqttPassword": "pass",
"mqttPrefix": "wopr",
"useHomeAssistant": true,
"discoveryPrefix": "homeassistant"
}
```

### Device state

Current device state is posted when state is changed.

```json
{
"effect": {
"state": "ON",
"name": "Rainbow"
},
"display": {
"state": "ON",
"text": "Hello World",
"scrollText": "Hello scrolling world",
"brightness": 50
},
"defcon": {
"state": "ON",
"level": 1,
"brightness": 50,
"color": "255,0,0"
}
}
```
41 changes: 26 additions & 15 deletions examples/JBWopr_DeviceDemo/JBWopr_DeviceDemo.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
// This example shows how to use the JBWoprDevice class to create a simple
// device that can display text and scroll text on the display.
//
// NOTE: Set your WiFi SSID and Password in the secrets.h file.
//
// Use the left and right buttons to switch between effects.
//
// -----------------------------------------------------------------------------
//
// JBWopr Library - https://github.com/jonnybergdahl/Arduino_JBWopr_Library
Expand All @@ -17,7 +21,9 @@
#include <WiFi.h>
#include <jbwopr.h>
#include <jbwoprhelpers.h>
#include "effects/jbwopreffects.h"
#include <effects/jbwopreffects.h>
#include <effects/jbwoprtherickeffect.h>
#include <effects/jbwoprnokiatune.h>
#include "secrets.h"

#define BOARD_VERSION JBWoprBoardVariant::ORIGINAL
Expand Down Expand Up @@ -53,7 +59,7 @@ void setup() {
config->effectsTimeout = 2;

// We are setting log level to max log level
wopr.getLogger()->setLogLevel(LogLevel::LOG_LEVEL_TRACE);
wopr.setLogLevel(LogLevel::LOG_LEVEL_TRACE);

// Setting up the devicee
wopr.begin(BOARD_VERSION);
Expand Down Expand Up @@ -90,10 +96,11 @@ void setup() {
delay(1000);

// Use the JBTimeHelper class to get the local time zone and get the local time
Serial.println("Get time");
wopr.displayShowText("Get time", JBTextAlignment::CENTER);
tm timeinfo;
if (!JBTimeHelper::getTime(&timeinfo)) {
Serial.println("Failed to obtain time");
Serial.println("Failed to obtain time - effects that needs time will retry");
wopr.displayShowText("Time failed", JBTextAlignment::CENTER);
}
}
Expand All @@ -114,13 +121,13 @@ void loop() {
if (resetEffect) {
Serial.print("currentEffect: ");
Serial.println(currentEffect);
wopr.effectStopCurrent();
wopr.effectsStopCurrentEffect();
resetEffect = false;
startEffect();
}

// If we are not running, just display a "pause" text
if (!wopr.effectIsRunning())
if (!wopr.effectsCurrentEffectIsRunning())
{
wopr.displayShowText("<- SWITCH ->");
}
Expand Down Expand Up @@ -153,34 +160,40 @@ void startEffect() {
Serial.printf("Running effect %i: %s for %i ms\n", currentEffect, effect->getName().c_str(), duration);
wopr.displayShowText(effect->getName());
delay(1000);
wopr.effectStart(effect, duration);
wopr.effectsStartEffect(effect);
}

void setupEffects() {
// Now we create all effects and put them in a vector
// Simple text display
JBWoprTextDisplayEffect* textDisplay = new JBWoprTextDisplayEffect(&wopr);
textDisplay->setText("SOME TEXT");
JBWoprTextDisplayEffect* textDisplay = new JBWoprTextDisplayEffect(&wopr, "SOME TEXT");
effects.push_back(textDisplay);

// Centered text display
textDisplay = new JBWoprTextDisplayEffect(&wopr, JBTextAlignment::CENTER);
textDisplay = new JBWoprTextDisplayEffect(&wopr, "CENTERED", JBTextAlignment::CENTER);
textDisplay->setText("CENTERED");
effects.push_back(textDisplay);

// Scrolling text effect
JBWoprScrollTextDisplayEffect* scrollTextDisplay = new JBWoprScrollTextDisplayEffect(&wopr);
scrollTextDisplay->setText("This is some scrolling text that is longer than 12 characters");
JBWoprScrollTextDisplayEffect* scrollTextDisplay = new JBWoprScrollTextDisplayEffect(&wopr, "This is some scrolling text that is longer than 12 characters");
effects.push_back(scrollTextDisplay);

// Clock display, time only
JBWoprTimeDisplayEffect* timeEffect = new JBWoprTimeDisplayEffect(&wopr);
effects.push_back(timeEffect);

// Clock display, time only, with rainbow effect
JBWoprTimeDisplayRainbowEffect* timeRainbowEffect = new JBWoprTimeDisplayRainbowEffect(&wopr);
effects.push_back(timeRainbowEffect);

// Clock display, date only
JBWoprDateDisplayEffect* dateEffect = new JBWoprDateDisplayEffect(&wopr);
effects.push_back(dateEffect);

// Clock display, date only, with rainbow effect
JBWoprDateDisplayRainbowEffect* dateRainbowEffect = new JBWoprDateDisplayRainbowEffect(&wopr);
effects.push_back(dateRainbowEffect);

// Clock display, time and date
JBWoprDateTimeDisplayEffect* dateTimeEffect = new JBWoprDateTimeDisplayEffect(&wopr);
effects.push_back(dateTimeEffect);
Expand All @@ -194,13 +207,11 @@ void setupEffects() {
effects.push_back(missileCodeSolve1);

// Missile solve effect, message version
JBWoprMissileCodeSolveEffect* missileCodeSolve2 = new JBWoprMissileCodeSolveEffect(&wopr);
missileCodeSolve2->setCodeSolveVariant(CodeSolveVariant::MESSAGE);
JBWoprMissileCodeSolveEffect* missileCodeSolve2 = new JBWoprMissileCodeSolveEffect(&wopr, CodeSolveVariant::MESSAGE, -1, "Msge solve");
effects.push_back(missileCodeSolve2);

// Missile solve effect, random version
JBWoprMissileCodeSolveEffect* missileCodeSolve3 = new JBWoprMissileCodeSolveEffect(&wopr);
missileCodeSolve2->setCodeSolveVariant(CodeSolveVariant::RANDOM);
JBWoprMissileCodeSolveEffect* missileCodeSolve3 = new JBWoprMissileCodeSolveEffect(&wopr, CodeSolveVariant::RANDOM, -1, "Rnd solve");
effects.push_back(missileCodeSolve3);

// Defcon LED rainbow effect
Expand Down
4 changes: 2 additions & 2 deletions examples/JBWopr_DeviceDemo/secrets.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef ARDUINO_WOPR_SECRETS_H
#define ARDUINO_WOPR_SECRETS_H

#define WIFI_SSID "PUT SSID HERE";
#define WIFI_PASSWORD "PUT PASSWORD HERE";
#define WIFI_SSID "PUT SSID HERE"
#define WIFI_PASSWORD "PUT PASSWORD HERE"

#endif //ARDUINO_WOPR_SECRETS_H
Binary file added images/haconfig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/haconfiguration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/hacontrols.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/hadeviceinfo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/hadiagnostics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions src/effects/jbwopreffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ void JBWoprSongEffect::loop() {
}

if (_step >= _song->size()) {
Serial.println("Song done");
_woprDevice->audioClear();
_done = true;
_isRunning = false;
Expand All @@ -847,7 +848,7 @@ void JBWoprSongEffect::loop() {
// calculates the duration of each note
Note note = _song->at(_step);
int32_t divider = note.duration;
uint32_t noteDuration = 0;
uint32_t noteDuration;
if (divider == 0)
{
noteDuration = 0;
Expand All @@ -860,7 +861,9 @@ void JBWoprSongEffect::loop() {
noteDuration *= 1.5; // increases the duration in half for dotted notes
}

_woprDevice->audioPlayNote((note_t)note.note, note.octave);
if (note.note != 0) {
_woprDevice->audioPlayNote((note_t)note.note, note.octave);
}

std::string text = note.text;

Expand Down
Loading

0 comments on commit 6e19cbf

Please sign in to comment.