esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
420 stars 26 forks source link

MAX44009 / GY-49 ambient light sensor support ? #29

Closed vincegre closed 2 years ago

vincegre commented 5 years ago

Is it planned to get support or is there a workaround already for MAX44009 / GY-49 ambient light sensor ? It's an I2C module pretty efficient for light sensing. Basic description of it here: https://www.aliexpress.com/snapshot/0.html?spm=a2g0s.9042647.6.2.2bfd4c4ddKFYKF&orderId=507448985225914&productId=32804395737

Thanks

Vincèn

Esiravegna commented 5 years ago

I do already have these implemented as a custom sensor, if it'd may help, I can share the code with you guys.

vincegre commented 5 years ago

I do already have these implemented as a custom sensor, if it'd may help, I can share the code with you guys.

yep please it would be really nice ;)

Esiravegna commented 5 years ago

There you go:

#include "esphomelib/application.h"
#include <Max44009.h>

using namespace esphomelib;

class MAX44009Sensor : public sensor::PollingSensorComponent {
 public:
    Max44009 tsl = Max44009(0x4A, 21, 22); //these are the i2c pins being used

  MAX44009Sensor(const std::string &name, uint32_t update_interval) : sensor::PollingSensorComponent(
    name, update_interval) {}

  void update() override {
    float lux = tsl.getLux(); // in lux
    int err = tsl.getError();
    if(err) 
      ESP_LOGI("luxmeter", "Got error code: %1i", err);  
    else   
      //ESP_LOGD(TAG, "Got lux=%.1flux", lux);   
      push_new_value(lux); 
  }

   std::string icon() override {
    return "mdi:theme-light-dark";
  }

    std::string unit_of_measurement() override { return "Lux"; }
  int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy.
};

And this in your setup method after the markers:

 auto *luxmeter = App.register_component( new MAX44009Sensor("Light Level", 30 * 1000)); 
 App.register_sensor(luxmeter);
vincegre commented 5 years ago

There you go:

Thanks for the share ;) Where should I put that code to be able to compile it in esphomelib ? and how did you declare in configuration file ?

Esiravegna commented 5 years ago

The configuration file is used to generate code, hardly the custom sensors would use any YAML. Please refer to this guide in order to use it :).

vincegre commented 5 years ago

@OttoWinter any chance to get that sensor implemented anytime soon ? thanks ;)

Codename-11 commented 5 years ago

In case anyone stumbles across this thread, which seems to be the only one regarding this sensor, the above code provided me with some errors after implementation due to changes in the esphome library. I by no means can write in C++, however by attemting to read the error codes, I was able to sucessfully compile the program with the below code. Pay attention to the I2C pins defined in both the C++ code, and make sure you define them in your YAML config. If there are any errors or something I missed I'm open to anyone's help. Like I said, this is merely a few changes after reading error codes from compiling. Hope this helps! :)

#include "esphome.h"
#include "Max44009.h"

using namespace esphome;

class MAX44009Sensor : public sensor::PollingSensorComponent {
 public:
    Max44009 tsl = Max44009(0x4A, 21, 22); //these are the i2c pins being used

  MAX44009Sensor(const std::string &name, uint32_t update_interval) : sensor::PollingSensorComponent(
    name, update_interval) {}

  void update() override {
    float lux = tsl.getLux(); // in lux
    int err = tsl.getError();
    if(err) 
      ESP_LOGI("luxmeter", "Got error code: %1i", err);  
    else   
      //ESP_LOGD(TAG, "Got lux=%.1flux", lux);   
      publish_state(lux); 
  }

   std::string icon() override {
    return "mdi:theme-light-dark";
  }

    std::string unit_of_measurement() override { return "Lux"; }
  int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy.
};
'
jamien82 commented 5 years ago

Hi, Im having trouble with this verifying. Any ideas

esphome:
  name: weather
  platform: ESP8266
  board: d1_mini_pro
  includes:
  - Max44009jamie.h

wifi:
  ssid: "embedded"
  password: "******"

# Enable logging
logger:

i2c:
  sda: 4
  scl: 5
  scan: True

ads1115:
  - address: 0x48

dallas:
  - pin: GPIO2

sensor:
  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 6.144
    name: "ADS1115 Channel A0-GND"
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      oversampling: 16x
    pressure:
      name: "BME280 Pressure"
    humidity:
      name: "BME280 Humidity"
    address: 0x76
    update_interval: 60s
  - platform: dallas
    address: 0x40031724D569FF28
    name: "Temperature #1"
  - platform: custom
    auto *luxmeter = App.register_component( new MAX44009Sensor("Light Level", 30 * 1000)); 
    App.register_sensor(luxmeter);
    sensors:
    - name: "My Custom lux Sensor"
      unit_of_measurement: lux
      accuracy_decimals: 1

# Enable Home Assistant API
api:

ota:

Validate window

INFO Reading configuration...
ERROR Error while reading config: Invalid YAML syntax. Please see YAML syntax reference or use an online YAML syntax validator:

while scanning a simple key
  in "/config/esphome/weather.yaml", line 45, column 5:
        auto *luxmeter = App.register_co ... 
        ^
could not find expected ':'
  in "/config/esphome/weather.yaml", line 46, column 5:
        App.register_sensor(luxmeter);
        ^
randybb commented 5 years ago

Any news about official integration?

LiuVik commented 5 years ago

Hi Tim. help me pls - MAX44009 do not working ,i create MAX4409.h with yours code, put's him into hassio and in config i showed next: i2c: sda: 4 scl: 5 scan: True id: bus_a

sensor: platform: |- custom auto luxmeter = App.register_component( new MAX44009Sensor("Light Level", 30 1000)); App.register_sensor(luxmeter); sensors:

whats wrong ?

Codename-11 commented 5 years ago

@LiuVik can you give us a little more information on your setup and where you placed files, code, etc? Your text was a little confusing.

egranto commented 4 years ago

Create a file on \homeassistant\config\esphome i named mine cjmcu.h add `#include "esphome.h"

include

include

class max44009 : public PollingComponent, public Sensor { Max44009 light = Max44009(0x4A, 4, 5); //these are the i2c pins being used public:

// constructor max44009() : PollingComponent(60000) {}

void setup() override { Wire.begin(); } void update() override { float lux = light.getLux(); // in lux publish_state(lux); } std::string icon() override { return "mdi:theme-light-dark"; }

std::string unit_of_measurement() override { return "Lux"; }
int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy.

};`

on your YAML just need ` includes:

and then - platform: custom lambda: |- auto my_sensor = new max44009(); App.register_component(my_sensor); return {my_sensor};

sensors:
  name: "Light Sensor:"`
grimmsq commented 4 years ago

Hello, I've been struggling with these for some time now, maybe you can help me

I've created a file called lux.h that I placed in \config\esphome with the following content

"#include "esphome.h"

include "Max44009.h"

class max44009 : public PollingComponent, public Sensor { public: Max44009 light = Max44009(0x4A, 4, 5); //these are the i2c pins being used // constructor max44009() : PollingComponent(60000) {}

void update() override { float lux = light.getLux(); // in lux int err = light.getError(); if(err) ESP_LOGI("luxmeter", "Got error code: %1i", err);
else
//ESP_LOGD(TAG, "Got lux=%.1flux", lux);
publish_state(lux); } std::string icon() override { return "mdi:theme-light-dark"; }

std::string unit_of_measurement() override { return "Lux"; } int8_t accuracy_decimals() override { return 2; } // 2 decimal places of accuracy. };"

After that I added this in the .yaml file

esphome: name: seraf platform: ESP8266 board: d1_mini includes:

wifi: ssid: "XXXXX" password: "XXXXX"

Enable fallback hotspot (captive portal) in case wifi connection fails

ap: ssid: "Seraf Fallback Hotspot" password: "XXXXX"

captive_portal:

Enable logging

logger:

Enable Home Assistant API

api: i2c: sda: 4 scl: 5 scan: True id: bus_a ota: sensor:

When I compile it i get the following error:

In file included from src/main.cpp:19:0: src/lux.h:8:3: error: 'Max44009' does not name a type Max44009 light = Max44009(0x4A, 4, 5); //these are the i2c pins being used ^ src/lux.h: In member function 'virtual void max44009::update()': src/lux.h:14:15: error: 'light' was not declared in this scope float lux = light.getLux(); // in lux

Can you please tell me what am I doing wrong? Thanks in advance!

iamnikv commented 4 years ago

Hello, @grimmsq I managed to make the sensor work with the following configuration:

In the ESPHome config folder I created the file ESPHomeMax44009Sensor.h. Here is the path to the file: homeassistant/config/esphome/CustomLibs/ESPHomeMax44009Sensor.h My .yaml file is one directory up in: homeassistant/config/esphome/weatherstation.yaml.

Here is the contents of the ESPHomeMax44009Sensor.h:

#include "esphome.h"
#include "Max44009.h"

class MAX44009Sensor : public PollingComponent, public Sensor  {
 public:
  Max44009 myLux = Max44009(0x4A, 4, 5); //these are the i2c pins being used

  MAX44009Sensor() : PollingComponent(15000) {} // 15 seconds update interval

  void setup() override {}

  void update() override 
  {
    float lux = myLux.getLux(); // in lux

    publish_state(lux); 
  }
};

And this is how I use it in weatherstation.yaml:

substitutions:
  display_name: outsideWeather

esphome:
  name: weather_station
  platform: ESP8266
#  board: d1_mini_pro
  board: d1_mini
  includes:
    - CustomLibs/ESPHomeMax44009Sensor.h
  libraries:
    - "Max44009"

wifi:
  ssid: !secret iot_wifi_ssid
  password: !secret iot_wifi_pass
  fast_connect: true
  manual_ip:
    static_ip: !secret ip_weatherstation
    gateway: !secret ip_gateway
    subnet: !secret ip_subnet
    dns1: !secret ip_dns1

#api:

# Enable logging
logger:

mqtt:
  broker: !secret mqtt_broker
  username: !secret mqtt_username
  password: !secret mqtt_password
  birth_message:
    topic: solarsensor/birthdisable
    payload: disable
  will_message:
    topic: solarsensor/willdisable
    payload: disable

ota:

i2c:
 - id: ic_1
   sda: 4
   scl: 5
   scan: false

sensor:
  - platform: hdc1080
    temperature:
      name: ${display_name} HDC1080 Temp
    humidity:
      name: ${display_name} HDC1080 Humi
    address: 0x40
    update_interval: 30s

  - platform: dht
    temperature:
      name: ${display_name} DHT Temperature
    humidity:
      name: ${display_name} DHT Humidity
    pin: D4
    update_interval: 30s

  - platform: custom
    lambda: |-
      auto lux_sensor = new MAX44009Sensor();
      App.register_component(lux_sensor);
      return {lux_sensor};

    sensors:
      name: ${display_name} Lux
      unit_of_measurement: lx

  - platform: adc
    pin: A0
    name: ${display_name} Battery
    update_interval: 15s
    filters:
      - multiply: 5.5238

deep_sleep:
  run_duration: 40s
  sleep_duration: 5min

I followed the official ESPHome Custom Sensor Component guide here and the digiblurDIY's video about Solar Powered Weather Station here.

This works for me and I hope it works for you as well.

mar00 commented 4 years ago

mam problem z codem program przy weryfikacji zatrzymuje sie na linii . brak jest dokladnego wyjasnienia przyczyny error. SSDAX44009I2C:13:18: error: no matching function for call to 'MAX44009::MAX44009(int)'

MAX44009 Lux(0x4A);

drtaul commented 4 years ago

Tried the different approaches provided in this thread with no success getting the MAX44009 to operate with basic ambient light readings. Finally took the code from Dan Tudose and implemented a sensor component using native ESPHome APIs (removed the arduino references making it dead simple).

This is all towards completing a DIY weather station that integrates with Home Assistant and weewx weather station data server. I have starting capturing what I did including this sensor and others in a github repository.

Hope it is helpful.

I will note that as part of this effort I discovered how to add ESPHome components locally via the 'custom_components' subdirectory. I just happened upon a discussion of this facility that made my life so much easier.

CMDR-Sloma commented 4 years ago

Tried the different approaches provided in this thread with no success getting the MAX44009 to operate with basic ambient light readings. Finally took the code from Dan Tudose and implemented a sensor component using native ESPHome APIs (removed the arduino references making it dead simple).

This is all towards completing a DIY weather station that integrates with Home Assistant and weewx weather station data server. I have starting capturing what I did including this sensor and others in a github repository.

Hope it is helpful.

I will note that as part of this effort I discovered how to add ESPHome components locally via the 'custom_components' subdirectory. I just happened upon a discussion of this facility that made my life so much easier.

I have tried it and as well other methods but none seems to work.

CMDR-Sloma commented 4 years ago

Hello, @grimmsq I managed to make the sensor work with the following configuration:

In the ESPHome config folder I created the file ESPHomeMax44009Sensor.h. Here is the path to the file: homeassistant/config/esphome/CustomLibs/ESPHomeMax44009Sensor.h My .yaml file is one directory up in: homeassistant/config/esphome/weatherstation.yaml.

Here is the contents of the ESPHomeMax44009Sensor.h:

#include "esphome.h"
#include "Max44009.h"

class MAX44009Sensor : public PollingComponent, public Sensor  {
 public:
  Max44009 myLux = Max44009(0x4A, 4, 5); //these are the i2c pins being used

  MAX44009Sensor() : PollingComponent(15000) {} // 15 seconds update interval

  void setup() override {}

  void update() override 
  {
    float lux = myLux.getLux(); // in lux

    publish_state(lux); 
  }
};

And this is how I use it in weatherstation.yaml:

substitutions:
  display_name: outsideWeather

esphome:
  name: weather_station
  platform: ESP8266
#  board: d1_mini_pro
  board: d1_mini
  includes:
    - CustomLibs/ESPHomeMax44009Sensor.h
  libraries:
    - "Max44009"

wifi:
  ssid: !secret iot_wifi_ssid
  password: !secret iot_wifi_pass
  fast_connect: true
  manual_ip:
    static_ip: !secret ip_weatherstation
    gateway: !secret ip_gateway
    subnet: !secret ip_subnet
    dns1: !secret ip_dns1

#api:

# Enable logging
logger:

mqtt:
  broker: !secret mqtt_broker
  username: !secret mqtt_username
  password: !secret mqtt_password
  birth_message:
    topic: solarsensor/birthdisable
    payload: disable
  will_message:
    topic: solarsensor/willdisable
    payload: disable

ota:

i2c:
 - id: ic_1
   sda: 4
   scl: 5
   scan: false

sensor:
  - platform: hdc1080
    temperature:
      name: ${display_name} HDC1080 Temp
    humidity:
      name: ${display_name} HDC1080 Humi
    address: 0x40
    update_interval: 30s

  - platform: dht
    temperature:
      name: ${display_name} DHT Temperature
    humidity:
      name: ${display_name} DHT Humidity
    pin: D4
    update_interval: 30s

  - platform: custom
    lambda: |-
      auto lux_sensor = new MAX44009Sensor();
      App.register_component(lux_sensor);
      return {lux_sensor};

    sensors:
      name: ${display_name} Lux
      unit_of_measurement: lx

  - platform: adc
    pin: A0
    name: ${display_name} Battery
    update_interval: 15s
    filters:
      - multiply: 5.5238

deep_sleep:
  run_duration: 40s
  sleep_duration: 5min

I followed the official ESPHome Custom Sensor Component guide here and the digiblurDIY's video about Solar Powered Weather Station here.

This works for me and I hope it works for you as well.

I had to edit this in order to get it to work, the code for the sensor was inconsistent and ESPHome was returning errors during compiling. Once I replaced every instance of MAX44009Sensor with MAX44009 in ESPHomeMax44009Sensor.h it compiled fine. The code below should work as long the pins for the sensor are the same:

#include "esphome.h"
#include "Max44009.h"

class MAX44009 : public PollingComponent, public Sensor {
 public:
  Max44009 solarLux = Max44009(0x4A, 4, 5); // these are the i2c pins being used, make sure to replace 4, 5 if you are using different ones
  // Constructor
  MAX44009() : PollingComponent(60000) {} // 60 seconds update interval

  void setup() override {}

  void update() override {
    float lux = solarLux.getLux(); // in lux

    publish_state(lux);
  }
};

Add to sensor in your ESPHome yaml:

  - platform: custom
    lambda: |-
      auto lux_sensor = new MAX44009();
      App.register_component(lux_sensor);
      return {lux_sensor};

    sensors:
      name: ${display_name} Lux
      unit_of_measurement: lx

Make sure your .yaml has the right number of spaces and check if the pins are the same as in ESPHomeMax44009Sensor.h.

@mar00 Sprawdź kod powyżej, powinno działać, o ile używasz tych samych pinów do komunikacji z sensorem (4,5). Na moim Wemosie piny 4,5 są oznaczone jako D1, D2.

berfenger commented 3 years ago

A few weeks ago I published an external component to support the MAX44009 sensor. Here is an example: https://github.com/berfenger/esphome_components/blob/main/example_max44009.yaml

Let me know if it works for you before issuing a merge request to the esphome mainline.

kisaev83 commented 3 years ago

Несколько недель назад я опубликовал внешний компонент для поддержки датчика MAX44009. Вот пример: https://github.com/berfenger/esphome_components/blob/main/example_max44009.yaml

Дайте мне знать, работает ли это для вас, прежде чем отправлять мерж-реквест в основную линию esphome.

Yes, it works for me. Thanks for the component! 2021-10-09_18-07-16

jerryaycock commented 2 years ago

I have tried for weeks. Getting nowhere. I thought I had a defective sensor, Ordered new one and still nothing. I have tried includes:

And my ESPHome log INFO Reading configuration /config/esphome/beachweather.yaml... INFO Detected timezone 'America/New_York' INFO Starting log output from 192.168.31.112 using esphome API INFO Successfully connected to 192.168.31.112

[11:00:01][C][logger:234]: Level: DEBUG [11:00:01][C][logger:235]: Log Baud Rate: 115200 [11:00:01][C][logger:236]: Hardware UART: UART0 [11:00:01][C][i2c.arduino:032]: I2C Bus: [11:00:01][C][i2c.arduino:033]: SDA Pin: GPIO21 [11:00:01][C][i2c.arduino:034]: SCL Pin: GPIO22 [11:00:01][C][i2c.arduino:035]: Frequency: 50000 Hz [11:00:01][C][i2c.arduino:038]: Recovery: bus successfully recovered [11:00:01][I][i2c.arduino:048]: Scanning i2c bus for active devices... [11:00:01][I][i2c.arduino:053]: Found i2c device at address 0x4A [11:00:01][I][i2c.arduino:053]: Found i2c device at address 0x76 [11:00:01][C][uart.arduino_esp32:105]: UART Bus: [11:00:02][C][uart.arduino_esp32:106]: TX Pin: GPIO1 [11:00:02][C][uart.arduino_esp32:107]: RX Pin: GPIO3 [11:00:02][C][uart.arduino_esp32:109]: RX Buffer Size: 256 [11:00:02][C][uart.arduino_esp32:111]: Baud Rate: 9600 baud [11:00:02][C][uart.arduino_esp32:112]: Data Bits: 8 [11:00:02][C][uart.arduino_esp32:113]: Parity: NONE [11:00:02][C][uart.arduino_esp32:114]: Stop bits: 1 [11:00:02][W][uart.arduino_esp32:160]: You're using the same serial port for logging and the UART component. Please disable logging over the serial port by setting logger->baud_rate to 0. [11:00:02][C][pulse_counter:148]: Pulse Counter 'Rain gauge' [11:00:02][C][pulse_counter:148]: State Class: 'measurement' [11:00:02][C][pulse_counter:148]: Unit of Measurement: 'in' [11:00:02][C][pulse_counter:148]: Accuracy Decimals: 3

[11:00:02][C][pulse_counter:149]: Pin: GPIO32 [11:00:03][C][pulse_counter:150]: Rising Edge: DISABLE [11:00:03][C][pulse_counter:151]: Falling Edge: INCREMENT [11:00:03][C][pulse_counter:152]: Filtering pulses shorter than 13 µs [11:00:03][C][pulse_counter:153]: Update Interval: 60.0s [11:00:03][C][integration:025]: Integration Sensor 'Rainfall per min' [11:00:03][C][integration:025]: State Class: '' [11:00:03][C][integration:025]: Unit of Measurement: 'in' [11:00:03][C][integration:025]: Accuracy Decimals: 5

[11:00:03][C][total_daily_energy:024]: Total Daily Energy 'Total Daily Rain' [11:00:03][C][total_daily_energy:024]: Device Class: 'energy' [11:00:03][C][total_daily_energy:024]: State Class: 'total_increasing' [11:00:03][C][total_daily_energy:024]: Unit of Measurement: 'in' [11:00:03][C][total_daily_energy:024]: Accuracy Decimals: 5

[11:00:04][C][bme280.sensor:143]: Address: 0x76 [11:00:04][C][bme280.sensor:155]: IIR Filter: OFF [11:00:04][C][bme280.sensor:156]: Update Interval: 60.0s

[11:00:04][C][bme280.sensor:158]: Device Class: 'temperature' [11:00:04][C][bme280.sensor:158]: State Class: 'measurement' [11:00:04][C][bme280.sensor:158]: Unit of Measurement: '°C' [11:00:04][C][bme280.sensor:158]: Accuracy Decimals: 1 [11:00:04][C][bme280.sensor:159]: Oversampling: 1x

[11:00:04][C][bme280.sensor:160]: Device Class: 'pressure' [11:00:04][C][bme280.sensor:160]: State Class: 'measurement' [11:00:04][C][bme280.sensor:160]: Unit of Measurement: 'hPa' [11:00:04][C][bme280.sensor:160]: Accuracy Decimals: 1 [11:00:05][C][bme280.sensor:161]: Oversampling: 1x

[11:00:05][C][bme280.sensor:162]: Device Class: 'humidity' [11:00:05][C][bme280.sensor:162]: State Class: 'measurement' [11:00:05][C][bme280.sensor:162]: Unit of Measurement: '%' [11:00:05][C][bme280.sensor:162]: Accuracy Decimals: 1 [11:00:05][C][bme280.sensor:163]: Oversampling: 1x

[11:00:05][C][pmsx003:226]: State Class: 'measurement' [11:00:05][C][pmsx003:226]: Unit of Measurement: 'µg/m³' [11:00:05][C][pmsx003:226]: Accuracy Decimals: 0

[11:00:05][C][pmsx003:227]: State Class: 'measurement' [11:00:06][C][pmsx003:227]: Unit of Measurement: 'µg/m³' [11:00:06][C][pmsx003:227]: Accuracy Decimals: 0

[11:00:06][C][pmsx003:228]: State Class: 'measurement' [11:00:06][C][pmsx003:228]: Unit of Measurement: 'µg/m³' [11:00:06][C][pmsx003:228]: Accuracy Decimals: 0

[11:00:06][C][captive_portal:151]: Captive Portal: [11:00:06][C][ota:082]: Over-The-Air Updates:

[11:00:06][C][ota:086]: Using Password. [11:00:06][C][api:134]: API Server: [11:00:06][C][api:135]: Address: 192.168.31.112:6053 [11:00:06][C][api:139]: Using noise encryption: NO [11:00:06][C][sntp:050]: SNTP Time: [11:00:06][C][sntp:051]: Server 1: '0.pool.ntp.org' [11:00:07][C][sntp:052]: Server 2: '1.pool.ntp.org' [11:00:07][C][sntp:053]: Server 3: '2.pool.ntp.org'

[11:00:07][C][mdns:085]: Hostname: beachweather

Any Pointers appreciated.

1nutzername commented 2 years ago

Thanks a lot for your solution, I've used this one a long time:

  - platform: custom
    lambda: |-
      auto lux_sensor = new MAX44009();
      App.register_component(lux_sensor);
      return {lux_sensor};

    sensors:
      name: ${display_name} Lux
      unit_of_measurement: lx

I could try your https://github.com/berfenger/esphome_components/blob/main/example_max44009.yaml @berfenger too, but as the code hasn't changed that much I guess it should work as @kisaev83 has confirmed already.

Is there any Pr yet?

BR i7i5