Arduino / Homeduino met ESP8266 aansturen pinnen op Arduino

You can combine those flows with a virtual device that would, to Homey, look like a sensor device.

FYI

Homeyduino works fine in Homey v2

Other people had lots of crashes when they tried, so YMMV.

I have developed a LED dimmer using the Homeyduino based on Wemos Mini D1 which I control either from the app or a physical button. Works really great in version 1.5 rc14, I don’t dare to step over to 2.0😰

I forked the basis from https://github.com/Adminius/DimmerControl

I recently converted my Homeyduino project (pir, led and lightsensor BH1750) to use MQTT and it was rather painless.

Hi Marlon,

Looks interesting. Can you share your code somewhere so I can learn ;-)?
Thanks,
Sander

I don’t mind sharing the entire ino file.

#include <Wire.h>
#include <BH1750.h> // Lightsensor
#include <ESP8266WiFi.h>
#include <PubSubClient.h>         //https://github.com/knolleary/pubsubclient
#define ledPin D7 // Green LED
#define pirPin D1 // Input for PIR HC-SR501
BH1750 lightMeter(0x23);

int state = LOW; // by default, no motion detected
int pirPinValue; // variable to store read PIR Value

unsigned long previousLuminosity = 0;
unsigned long previousMillis = 0;
const unsigned long ldrInterval = 2 * 60 * 1000; //default interval for lightsensor in milliseconds

String clientId = "ESP_" + String(ESP.getChipId(), HEX);
char *ssid = "ssid";
char *password = "password";

const char *mqttServer = "192.168.1.61";
const int mqttPort = 8883;
const char *mqttUser = "test";
const char *mqttPassword = "uno";
const char *motion_topic = "home/hallway/pir/motion";
const char *luminance_topic = "home/hallway/pir/luminance";

//WiFiClientSecure is required if you are using mqtts usually port 8883
WiFiClientSecure espClient;
// If you are using port 1883 without a certificatie then use WiFiClient instead
PubSubClient client(espClient);

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(pirPin, INPUT);
  digitalWrite(ledPin, LOW); // led off

  // Initialize the I2C bus (BH1750 library doesn't do this automatically)
  Wire.begin(D3, D4);
  // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3);

  // begin returns a boolean that can be used to detect setup problems.
  if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
    Serial.println(F("BH1750 Advanced begin"));
  }
  else {
    Serial.println(F("Error initialising BH1750"));
  }

  previousMillis = ldrInterval;
  randomSeed(analogRead(A0));
}

void loop()
{
  //always running no delay	
  lightDetection(false);
  motionDetection();
}

void lightDetection(bool immediate)
{
  if (immediate || previousMillis == 0 || readLight())
  {
    float lux = lightMeter.readLightLevel();
    Serial.print("Luminosity "); Serial.println(lux);

    wifiConnect();

    client.publish(luminance_topic, String(lux).c_str(), true);
  }
}

bool readLight()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis > ldrInterval)
  {
    previousMillis = currentMillis;
    return true;
  }
  else
  {
    return false;
  }
}

void motionDetection()
{
  pirPinValue = digitalRead(pirPin);
  if (pirPinValue == HIGH)
  {
    digitalWrite(ledPin, HIGH); // turn LED ON
    delay(100);                 // delay 100 milliseconds
    if (state == LOW)
    {
      Serial.println("Motion detected!");
      state = HIGH;
      lightDetection(true); // before setting motion alarm, send lightsensor value first
      delay(50);
      setMotionAlarm(true);
    }
  }
  else
  {
    digitalWrite(ledPin, LOW); // turn LED OFF
    delay(200);                // delay 200 milliseconds

    if (state == HIGH)
    {
      Serial.println("Motion stopped!");
      state = LOW;
      setMotionAlarm(false);
    }
  }
}

void setMotionAlarm(bool motionDetected) {
  wifiConnect();
  Serial.print("Publish "); sprintf(motion_topic, motionDetected ? "true": "false");
  client.publish(motion_topic, motionDetected ? "true": "false", true); // by sending true and false as text, Homey automagically converts those to actual booleans
}

void wifiConnect()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Not connected to wifi, connecting now");
    WiFi.mode(WIFI_STA); // Static
    WiFi.hostname("Navnet PIR");
    //Connect to network
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
      delay(500);
      Serial.print(".");
    }

    //Print IP address
    Serial.print("Connected to IP address: ");
    Serial.print("Ip: "); Serial.print(WiFi.localIP());
    Serial.println("\tMAC: ");  Serial.println(WiFi.macAddress());
  }

  if (!client.connected()) {
    client.setServer(mqttServer, mqttPort);
    Serial.print("Connecting to MQTT server "); Serial.print(mqttServer);

    while (!client.connected()) {
      if (client.connect(clientId.c_str(), mqttUser, mqttPassword ))
      {
        Serial.println("\tconnected");
      } else {
        delay(500);
        Serial.print(".");
      }
    }
  }
}

More info on the Homey flows and MQTT Broker settings checkout this post
Good luck! :beers:

Here’s what I wrote this evening (also for an BH1750, connected to an ESP8266):

#define MY_DEBUG
#define MY_GATEWAY_ESP8266
#define MY_GATEWAY_MQTT_CLIENT
#define MY_BAUD_RATE                    115200
#define MY_WIFI_SSID                    "XXX"
#define MY_WIFI_PASSWORD                "YYY"
#define MY_MQTT_CLIENT_ID               "esp-lightsensor"
#define MY_MQTT_PUBLISH_TOPIC_PREFIX    "my/" MY_MQTT_CLIENT_ID "/pub"
#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX  "my/" MY_MQTT_CLIENT_ID "/sub"
#define MY_CONTROLLER_IP_ADDRESS        192, 168, 23, 8
#define MY_PORT                         1883

#include <ESP8266WiFi.h>
#include <MySensors.h>
#include <Wire.h>
#include <BH1750.h>

BH1750    lightMeter;
MyMessage message (0, V_LEVEL);

void setup() {
  Wire.begin(D3, D4);
  if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
    Serial.println(F("BH1750 Advanced begin"));
  } else {
    Serial.println(F("Error initialising BH1750"));
  }
}

void presentation() {
  sendSketchInfo("LightSensor", "1.0");
  present(0, S_LIGHT_LEVEL);
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.println("Measured level: " + String(lux) + " lux.");
  send(message.set((int32_t) lux));
  delay(2000);
  ESP.deepSleep(30e6);
}

It uses the MySensors library, which does most of the heavy lifting with regards to WiFi and MQTT. I use the MQTT Broker app to provide the MQTT server.

There is a MySensors app for Homey, but I don’t think it’s being maintained anymore. I didn’t feel like using it, and instead opted for a quick-and-dirty solution:

  • use the Virtual Devices app to create a sensor with the capability “Helderheid/Luminance”
  • use the MQTT Client app to watch for updates from the light sensor node (it updates every 30 seconds) and set the measure_luminance capability of the virtual sensor device:

(the full topic used is my/esp-lightsensor/pub/0/0/1/0/37, where my/esp-lightsensor/pub is a sort of prefix, and the numbers are the MySensors encoding of the sensor type/data).

Here’s another interesting project: https://esphomelib.com/

It supports a lot of sensors and protocols, but will only work on ESP8266/ESP32 devices.

Only esp8266/32 devices? Abundantly available and dirt cheap, those ones?
But if I understand you correctly, you mean for instance mysensors is not limited to esp but could also tap in to the world of raspberry pi and the like?

As a sidenote: I could not help but notice: ESP32 Bluetooth Low Energy RSSI Sensor — ESPHome
ESP32 Bluetooth Low Energy RSSI Sensor. Esp32 has bluetooth and you can get the signalstrength (rssi) over mqtt to homey. With multiple esp32 devices you can locate where a bluetooth device is. (not all that precise, but enough to play with)

But a lot to love about esphomelib. What I like about there approach is: no programming experience required (well, editing of YAML configuration files), just playing with sensors.
I did not hear from it before, It is created/maintained by Otto Winter, an Austrian. Busy guy it seems.
Esphomelib/esphomeyaml is knee deep in the Home Assistant world. Now is that not a negative thing in principle.

But maybe Esphomelib is not the most interesting to see in that world.
Home Assistant has a “MQTT Discovery” feature, witch, from what I can see sort of automates the connection from mqtt enabled devices to usable virtual devices in Home Assistant. The configuration is done on the device itself and the topic used by the device.
And it works with:

  • Tasmota
  • Esphomelib
  • Zigbee2mqtt

To also share something: I flashed a wemos d1 mini today with Tasmota (sonoff-sensors.bin with esptool) and connected a

  • KY-018 light sensor
  • 4 Channel Relay Module Board
  • AM312 PIR motion dection
    to it and connected it via MQTT to Homey. Great fun!

Fun to see the slightly different approaches in this topic to open up the esp/arduino world to homey.

I don’t think that MySensors has “node” support for RPi, only gateway support. In other words, you can’t use it as a sensor device, but you can use it as a device that sensor nodes can communicate with. Using an RPi as a sensor node seems a bit over-the-top anyway.

And yes, the ESP32 is a capable BLE device, although you can’t use BLE and WiFi together (they share the same internal radio and antenna). But it’s relatively easy to do some BLE stuff, turn off BLE, turn on WiFi, do WiFi stuff, and to back to BLE, in a loop.

I haven’t been able to find anything on the actual protocol that HA uses to (directly) talk to esphomelib nodes, but it might be interesting to see if a Homey app can be build for it.

That would have been nice. But I’m not knee deep in HA and a simple search doesn’t cut it.
Something for another day

First off, thanks for the sketch. I try to get it to work with a secure connection, but cannot connect to the MQQT server (MQQT broker app on Homey).

You note to connect with ‘WiFiClientSecure’ if you work with port 8883 but I am a bit confused because I don’t see you include this library on the start of the sketch with '#include <WifiClientSecure.h>. Don’t you need to include this library first to get it to work?

Indeed, WiFiClientSecure and WiFiClient are part of the same library.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

Thanks for the answer. I included the library in the beginning of the sketch but still i cannot connect secure 8883 (1883 unsecured all fine). A couple of questions I still have. Maybe you can help me out.

  • How come you didn’t included the ‘WifiClientSecure library’ in your sample code you posted and have it working?
  • Don’t you need to type in a ‘certificate key’ in the arduino code to verify the MQQT-client?
  • Are you using the Homey MQQT Broker by Menno van Grinsven?

Do you need to use a secured connection? I assume that everything is connected to your local WiFi network.

I’m always tinkering with the code so I might have modified it without actually running it :wink:

Regarding the configuration of the broker and/or client take a look at this post

At the time yes, but not anymore. Now I’m running node-red in docker from my NAS. I’m really impressed with the stability and performance of it.

On a side note I’m also using node-red to transform json payloads and pass the result to another topic. really nice actually!

1 Like

Hi, got it all working now with several devices. Next step i’m considering is to create a 433Mhz version on a board without WiFi. This saves energy a collegue (not using Homey) told me. Any experience with this? Is MQTT still supported than? Different topic maybe?

You’d need a 433Mhz receiver that would receive the data sent by your device, and that receiver needs to be connected to WiFi (or at least a network) to be able to relay messages to the MQTT broker.

If your device only periodically has to send data (for instance, a temperature/humidity sensor that takes a measurement once every few minutes), you can consider using an ESP8266 that is put into deep sleep mode in between measurements, which will save a lot of power.