Skip to content

Commit

Permalink
Release 1.2.0 (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidchyrzynski authored Mar 23, 2021
1 parent 70ccd26 commit 15562fa
Show file tree
Hide file tree
Showing 42 changed files with 3,342 additions and 942 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Changelog

## 1.2.0

**Breaking changes:**
* Refactored HASensor implementation. Please take a look at updated example in `examples/sensor/sensor.ino`

**New features:**
* Added support for HVAC
* Added support for excluding devices types from the compilation using defines (see `src/ArduinoHADefines.h`)
* Added support for setting icon in HASwitch and HASensor
* Added support for setting retain flag in HASwitch
* Added support for text (const char*) payload in HASensor
* Added support for fans (HAFan)
* Added support for connecting to the MQTT broker using hostname
* Added `onConnected()` method in the HAMqtt
* Added `onConnectionFailed()` method in the HAMqtt
* Added support for MQTT LWT (see `examples/advanced-availability/advanced-availability.ino`)

**Updates:**
* Optimized codebase and logic in all devices types
* Updated all examples
* Fixed compilation warnings in all classes
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@ but I successfully use it on ESP8266/ESP8255 boards in my projects.
## Features

* MQTT discovery (device is added to the Home Assistant panel automatically)
* MQTT Last Will and Testament
* Auto reconnect with MQTT broker

## Examples

* [Binary Sensor](examples/binary-sensor/binary-sensor.ino)
* [Fan](examples/fan/fan.ino)
* [LED switch](examples/led-switch/led-switch.ino)
* [MQTT with credentials](examples/mqtt-with-credentials/mqtt-with-credentials.ino)
* [Multi-state button](examples/multi-state-button/multi-state-button.ino)
* [Sensor (temperature, humidity, etc.)](examples/sensor/sensor.ino)
* [HVAC](examples/hvac/hvac.ino)
* [NodeMCU Wi-Fi](examples/nodemcu/nodemcu.ino)
* [Arduino Nano 33 IoT Wi-Fi (SAMD)](examples/nano33iot/nano33iot.ino)
* [Availability feature](examples/availability)
* [Advanced availability (MQTT LWT)](examples/advanced-availability/advanced-availability.ino)
* [MQTT with credentials](examples/mqtt-with-credentials/mqtt-with-credentials.ino)
* [MQTT events](examples/mqtt-events/mqtt-events.ino)

## Tested boards

Expand All @@ -39,10 +44,21 @@ but I successfully use it on ESP8266/ESP8255 boards in my projects.
## Supported HA types

* Binary sensors
* Fans
* Device triggers
* Switches
* Sensors
* Tag scanner
* HVACs *(side note: HVACs requires more flash size than other HA types. It's not suitable for Arduino Nano/Uno)*

## Roadmap

* FAQ + Home Assistant setup instructions
* Documentation of the library
* Unit tests
* Reduce flash memory usage
* Add support for HA covers
* Add support for HA lights

## Unsupported features

Expand Down
64 changes: 64 additions & 0 deletions examples/advanced-availability/advanced-availability.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <Ethernet.h>
#include <ArduinoHA.h>

#define INPUT_PIN 9
#define BROKER_ADDR IPAddress(192,168,0,17)

byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};
unsigned long lastReadAt = millis();
unsigned long lastAvailabilityToggleAt = millis();
bool lastInputState = false;

EthernetClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);

// "input" may be anything you want to be displayed in HA panel
// "door" is device class (based on the class HA displays different icons in the panel)
// "true" is initial state of the sensor. In this example it's "true" as we use pullup resistor
HABinarySensor sensor("input", "door", true);

void setup() {
pinMode(INPUT_PIN, INPUT_PULLUP);
lastInputState = digitalRead(INPUT_PIN);

// you don't need to verify return status
Ethernet.begin(mac);

lastReadAt = millis();
lastAvailabilityToggleAt = millis();

// set device's details (optional)
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");

// This method enables availability for all device types registered on the device.
// For example, if you have 5 sensors on the same device, you can enable
// shared availability and change availability state of all sensors using
// single method call "device.setAvailability(false|true)"
device.enableSharedAvailability();

// Optionally, you can enable MQTT LWT feature. If device will lose connection
// to the broker, all device types related to it will be marked as offline in
// the Home Assistant Panel.
device.enableLastWill();

mqtt.begin(BROKER_ADDR);
}

void loop() {
Ethernet.maintain();
mqtt.loop();

if ((millis() - lastReadAt) > 30) { // read in 30ms interval
// library produces MQTT message if a new state is different than the previous one
sensor.setState(digitalRead(INPUT_PIN));
lastInputState = sensor.getState();
lastReadAt = millis();
}

if ((millis() - lastAvailabilityToggleAt) > 5000) {
device.setAvailability(!device.isOnline());
lastAvailabilityToggleAt = millis();
}
}
2 changes: 2 additions & 0 deletions examples/availability/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ It's supported only by following device types:
* Binary sensor
* Sensor
* Switch
* HVACs
* Fans

## Initialization and usage

Expand Down
3 changes: 2 additions & 1 deletion examples/availability/availability.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ HAMqtt mqtt(client, device);
// "input" may be anything you want to be displayed in HA panel
// "door" is device class (based on the class HA displays different icons in the panel)
// "true" is initial state of the sensor. In this example it's "true" as we use pullup resistor
HABinarySensor sensor("input", "door", true, mqtt);
HABinarySensor sensor("input", "door", true);

void setup() {
pinMode(INPUT_PIN, INPUT_PULLUP);
Expand All @@ -26,6 +26,7 @@ void setup() {
Ethernet.begin(mac);

// turn on "availability" feature
// this method also sets initial availability so you can use "true" or "false"
sensor.setAvailability(false);

lastReadAt = millis();
Expand Down
2 changes: 1 addition & 1 deletion examples/binary-sensor/binary-sensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ HAMqtt mqtt(client, device);
// "input" may be anything you want to be displayed in HA panel
// "door" is device class (based on the class HA displays different icons in the panel)
// "true" is initial state of the sensor. In this example it's "true" as we use pullup resistor
HABinarySensor sensor("input", "door", true, mqtt);
HABinarySensor sensor("input", "door", true);

void setup() {
pinMode(INPUT_PIN, INPUT_PULLUP);
Expand Down
58 changes: 58 additions & 0 deletions examples/fan/fan.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <Ethernet.h>
#include <ArduinoHA.h>

#define BROKER_ADDR IPAddress(192,168,0,17)

byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};

EthernetClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);

// HAFan::SpeedsFeature enables support for setting different speeds of fan.
// You can skip this argument if you don't need speed management.
HAFan fan("ventilation", HAFan::SpeedsFeature);

void onStateChanged(bool state) {
Serial.print("State: ");
Serial.println(state);
}

void onSpeedChanged(HAFan::Speed speed) {
Serial.print("Speed: ");
if (speed == HAFan::OffSpeed) {
Serial.print("off");
} else if (speed == HAFan::LowSpeed) {
Serial.print("low");
} else if (speed == HAFan::MediumSpeed) {
Serial.print("medium");
} else if (speed == HAFan::HighSpeed) {
Serial.print("high");
}
}

void setup() {
// you don't need to verify return status
Ethernet.begin(mac);

// set device's details (optional)
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");

// configure fan (optional)
// default speeds are: Off | Low | Medium | High
fan.setSpeeds(HAFan::OffSpeed | HAFan::LowSpeed | HAFan::HighSpeed);
fan.setName("Bathroom");
fan.setRetain(true);

// handle fan states
fan.onStateChanged(onStateChanged);
fan.onSpeedChanged(onSpeedChanged);

mqtt.begin(BROKER_ADDR);
}

void loop() {
Ethernet.maintain();
mqtt.loop();
}
102 changes: 102 additions & 0 deletions examples/hvac/hvac.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include <ESP8266WiFi.h>
#include <ArduinoHA.h>

#define BROKER_ADDR IPAddress(192,168,0,17)
#define WIFI_SSID "MyNetwork"
#define WIFI_PASSWORD "MyPassword"

WiFiClient client;
HADevice device;
HAMqtt mqtt(client, device);

// see src/device-types/HAHVAC.h header for more details
HAHVAC hvac("my_name", HAHVAC::AuxHeatingFeature | HAHVAC::AwayModeFeature | HAHVAC::HoldFeature);

unsigned long lastTempPublishAt = 0;
double lastTemp = 0;

void onAuxHeatingStateChanged(bool state) {
Serial.print("Aux heating: ");
Serial.println(state);
}

void onAwayStateChanged(bool state) {
Serial.print("Away state: ");
Serial.println(state);
}

void onHoldStateChanged(bool state) {
Serial.print("Hold state: ");
Serial.println(state);
}

void onTargetTemperatureChanged(double temp) {
Serial.print("Target temperature: ");
Serial.println(temp);
}

void onModeChanged(HAHVAC::Mode mode) {
Serial.print("Mode: ");
if (mode == HAHVAC::OffMode) {
Serial.println("off");
} else if (mode == HAHVAC::AutoMode) {
Serial.println("auto");
} else if (mode == HAHVAC::CoolMode) {
Serial.println("cool");
} else if (mode == HAHVAC::HeatMode) {
Serial.println("heat");
} else if (mode == HAHVAC::DryMode) {
Serial.println("dry");
} else if (mode == HAHVAC::FanOnlyMode) {
Serial.println("fan only");
}
}

void setup() {
Serial.begin(9600);
Serial.println("Starting...");

// Unique ID must be set!
byte mac[WL_MAC_ADDR_LENGTH];
WiFi.macAddress(mac);
device.setUniqueId(mac, sizeof(mac));

// connect to wifi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500); // waiting for the connection
}
Serial.println();
Serial.println("Connected to the network");

// set device's details (optional)
device.setName("NodeMCU");
device.setSoftwareVersion("1.0.0");

// assign callbacks (optional)
hvac.onAuxHeatingStateChanged(onAuxHeatingStateChanged);
hvac.onAwayStateChanged(onAwayStateChanged);
hvac.onHoldStateChanged(onHoldStateChanged);
hvac.onTargetTemperatureChanged(onTargetTemperatureChanged);
hvac.onModeChanged(onModeChanged);

// configure HVAC (optional)
hvac.setName("My HVAC");
hvac.setMinTemp(10);
hvac.setMaxTemp(30);
hvac.setTempStep(0.5);
hvac.setRetain(true);

mqtt.begin(BROKER_ADDR);
}

void loop() {
mqtt.loop();

if ((millis() - lastTempPublishAt) > 3000) {
hvac.setCurrentTemperature(lastTemp);
lastTempPublishAt = millis();
lastTemp += 0.5;
}
}
5 changes: 4 additions & 1 deletion examples/led-switch/led-switch.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};
EthernetClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);
HASwitch led("led", false, mqtt); // you can use custom name in place of "led"
HASwitch led("led", false); // you can use custom name in place of "led"

void onSwitchStateChanged(bool state, HASwitch* s)
{
Expand All @@ -27,6 +27,9 @@ void setup() {
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");

// set icon (optional)
led.setIcon("mdi:lightbulb");

// handle switch state
led.onStateChanged(onSwitchStateChanged);

Expand Down
32 changes: 32 additions & 0 deletions examples/mqtt-events/mqtt-events.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <Ethernet.h>
#include <ArduinoHA.h>

#define BROKER_ADDR IPAddress(192,168,0,17)

byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};

EthernetClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);

void onMqttConnected() {
Serial.println("Connected to the broker!");
}

void onMqttConnectionFailed() {
Serial.println("Failed to connect to the broker!");
}

void setup() {
Serial.begin(9600);
Ethernet.begin(mac);

mqtt.onConnected(onMqttConnected);
mqtt.onConnectionFailed(onMqttConnectionFailed);
mqtt.begin(BROKER_ADDR);
}

void loop() {
Ethernet.maintain();
mqtt.loop();
}
2 changes: 1 addition & 1 deletion examples/mqtt-with-credentials/mqtt-with-credentials.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};
EthernetClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);
HASwitch led("led", false, mqtt); // you can use custom name in place of "led"
HASwitch led("led", false); // you can use custom name in place of "led"

void onSwitchStateChanged(bool state, HASwitch* s)
{
Expand Down
Loading

0 comments on commit 15562fa

Please sign in to comment.