Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding SI1145 as Custom Sensor fails reading values #342

Closed
Lefuneste83 opened this issue May 25, 2019 · 3 comments
Closed

Adding SI1145 as Custom Sensor fails reading values #342

Lefuneste83 opened this issue May 25, 2019 · 3 comments

Comments

@Lefuneste83
Copy link

Lefuneste83 commented May 25, 2019

Operating environment/Installation (Hass.io/Docker/pip/etc.):

ESPHOME Plugin in Home Assistant

ESP (ESP32/ESP8266, Board/Sonoff):

ESP8266 Wemos D1 Mini R2

Affected component:

https://esphome.io/components/sensor/custom.html

Description of problem:

Adding custom sensor not reading values from the sensor

Problem-relevant YAML-configuration entries:

esphome:
  name: meteo
  platform: ESP8266
  board: d1_mini
  
  includes:
    - SI1145.h
  libraries:
    - "Adafruit SI1145 Library"

wifi:
  ssid: "blahblahblah"
  password: "guesswhat"

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: 'whatever'

ota:
  password: 'whatever'

i2c:
  sda: D2
  scl: D1
  scan: True

sensor:
  - platform: wifi_signal
    name: "Meteo WiFi Signal Sensor"
    update_interval: 1s

  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
      oversampling: 16x
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
      oversampling: 16x
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76
    update_interval: 1s
  
  - platform: template
    name: "Absolute Humidity"
    lambda: |-
      const float mw = 18.01534;    // molar mass of water g/mol
      const float r = 8.31447215;   // Universal gas constant J/mol/K
      return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
        (id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
        ((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
    accuracy_decimals: 2
    update_interval: 1s
  
  - platform: template
    name: "Equivalent sea level pressure"
    lambda: |-
      const float STANDARD_ALTITUDE = 260; // in meters, see note
      return id(bme280_pressure).state / powf(1 - ((0.0065 * STANDARD_ALTITUDE) /
        (id(bme280_temperature).state + (0.0065 * STANDARD_ALTITUDE) + 273.15)), 5.257); // in hPa
    update_interval: 1s


  - platform: custom
    lambda: |-
      auto UV_sensor = new SI1145_sensor();
      App.register_component(UV_sensor);
      return {UV_sensor->visible_sensor, UV_sensor->ir_sensor, UV_sensor->uvindex_sensor};

    sensors:
    - name: "Visible Light"
    - name: "IR Light"
    - name: "UV Index"

**Traceback (if applicable):**
<!--
Please copy the traceback here if compilation is failing. If possible, also connect to the ESP over USB and copy its logs into the backticks.
-->

Additional information and things you've tried:

Hi there! I've been struggling a bit trying to add a SI1145 UV sensor to Esphome.
I have a D1 Mini (ESP8266) board with a BME280 sensor working fine. I try to add a SI1145 but as the sensor is not supported out of the box I have followed the described procedure in order to add it as a custom sensor.

Compiling the code runs fine with no errors, and the specified library (Adafruit SI1145) seems to be properly downloaded and used.

Upon reboot of the ESP8266 everything seems good, I get my entities appearing in Home Assistant but the values of the sensor stay at 0. I am almost certain this is due to my dubness probably forgetting something very obvious somewhere in the process (naming convention, conf missing...).

I must add that this exact same setup (wiring, board etc) runs fine with an Arduino code.

My custom sensor file is named /config/esphome/SI1145.h
I have tried the single and multiple sensor modes, without any change in the behaviour ("0" value returned) :

#include "esphome.h"
#include "Adafruit_SI1145.h"

using namespace esphome;

class SI1145_sensor : public PollingComponent {
 public:
  Adafruit_SI1145 uv;
  sensor::Sensor *visible_sensor = new sensor::Sensor();
  sensor::Sensor *ir_sensor = new sensor::Sensor();
  sensor::Sensor *uvindex_sensor = new sensor::Sensor();

  SI1145_sensor() : PollingComponent(1000) { }

  void setup() override {
    uv.begin();
  }

  void update() override {
    
    int visible = uv.readVisible();
    visible_sensor->publish_state(visible);

    int irlight = uv.readIR();
    ir_sensor->publish_state(irlight);

    int uvindex = uv.readUV();
    uvindex_sensor->publish_state(uvindex / 100.0);
  }
};

My device code is meteo.yaml :

esphome:
  name: meteo
  platform: ESP8266
  board: d1_mini
  
  includes:
    - SI1145.h
  libraries:
    - "Adafruit SI1145 Library"

wifi:
  ssid: "blahblahblah"
  password: "guesswhat"

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: 'whatever'

ota:
  password: 'whatever'

i2c:
  sda: D2
  scl: D1
  scan: True

sensor:
  - platform: wifi_signal
    name: "Meteo WiFi Signal Sensor"
    update_interval: 1s

  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
      oversampling: 16x
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
      oversampling: 16x
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76
    update_interval: 1s
  
  - platform: template
    name: "Absolute Humidity"
    lambda: |-
      const float mw = 18.01534;    // molar mass of water g/mol
      const float r = 8.31447215;   // Universal gas constant J/mol/K
      return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
        (id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
        ((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
    accuracy_decimals: 2
    update_interval: 1s
  
  - platform: template
    name: "Equivalent sea level pressure"
    lambda: |-
      const float STANDARD_ALTITUDE = 260; // in meters, see note
      return id(bme280_pressure).state / powf(1 - ((0.0065 * STANDARD_ALTITUDE) /
        (id(bme280_temperature).state + (0.0065 * STANDARD_ALTITUDE) + 273.15)), 5.257); // in hPa
    update_interval: 1s


  - platform: custom
    lambda: |-
      auto UV_sensor = new SI1145_sensor();
      App.register_component(UV_sensor);
      return {UV_sensor->visible_sensor, UV_sensor->ir_sensor, UV_sensor->uvindex_sensor};

    sensors:
    - name: "Visible Light"
    - name: "IR Light"
    - name: "UV Index"

Upon reboot I have this log which seems to indicate that both sensors are recognised (Si1145 is at 0x60 address) :

Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1_mini.html
PLATFORM: Espressif 8266 > WeMos D1 R2 & mini
HARDWARE: ESP8266 80MHz 80KB RAM (4MB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 29 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Adafruit SI1145 Library> 1.0.0
|   |-- <Wire> 1.0
|-- <ESP8266WiFi> 1.0
|-- <ESP8266mDNS>
|   |-- <ESP8266WiFi> 1.0
|-- <ESPAsyncTCP> 1.2.0
|   |-- <ESP8266WiFi> 1.0
|-- <Hash> 1.0
|-- <Wire> 1.0
|-- <esphome-core> 1.12.2
|   |-- <ArduinoJson-esphomelib> 5.13.3
|   |-- <ESP8266WiFi> 1.0
|   |-- <ESP8266mDNS>
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <ESPAsyncTCP> 1.2.0
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <Wire> 1.0
Retrieving maximum program size /data/meteo/.pioenvs/meteo/firmware.elf
Checking size /data/meteo/.pioenvs/meteo/firmware.elf
Memory Usage -> http://bit.ly/pio-memory-usage
DATA:    [====      ]  38.7% (used 31684 bytes from 81920 bytes)
PROGRAM: [===       ]  32.8% (used 342628 bytes from 1044464 bytes)

.../...

[18:02:55][C][i2c:035]: I2C Bus:
[18:02:55][C][i2c:036]:   SDA Pin: GPIO4
[18:02:55][C][i2c:037]:   SCL Pin: GPIO5
[18:02:55][C][i2c:038]:   Frequency: 50000 Hz
[18:02:55][I][i2c:040]: Scanning i2c bus for active devices...
[18:02:55][I][i2c:047]: Found i2c device at address 0x60
[18:02:55][I][i2c:047]: Found i2c device at address 0x76
[18:02:56][C][sensor.template:028]: Template Sensor 'Absolute Humidity'
[18:02:56][C][sensor.template:028]:   Unit of Measurement: ''
[18:02:56][C][sensor.template:028]:   Accuracy Decimals: 2
[18:02:56][C][sensor.template:029]:   Update Interval: 1000 ms
[18:02:56][C][sensor.template:028]: Template Sensor 'Equivalent sea level pressure'
[18:02:56][C][sensor.template:028]:   Unit of Measurement: ''
[18:02:56][C][sensor.template:028]:   Accuracy Decimals: 0
[18:02:56][C][sensor.template:029]:   Update Interval: 1000 ms
[18:02:56][C][logger:142]: Logger:
[18:02:56][C][logger:143]:   Level: DEBUG
[18:02:56][C][logger:144]:   Log Baud Rate: 115200
[18:02:56][C][logger:145]:   Hardware UART: UART0
[18:02:56][C][sensor.bme280:162]: BME280:
[18:02:56][C][sensor.bme280:163]:   Address: 0x76
[18:02:56][C][sensor.bme280:175]:   IIR Filter: OFF
[18:02:56][C][sensor.bme280:176]:   Update Interval: 1000 ms
[18:02:56][C][sensor.bme280:178]:   Temperature 'BME280 Temperature'
[18:02:56][C][sensor.bme280:178]:     Unit of Measurement: '°C'
[18:02:56][C][sensor.bme280:178]:     Accuracy Decimals: 1
[18:02:56][C][sensor.bme280:179]:     Oversampling: 16x
[18:02:56][C][sensor.bme280:180]:   Pressure 'BME280 Pressure'
[18:02:56][C][sensor.bme280:180]:     Unit of Measurement: 'hPa'
[18:02:56][C][sensor.bme280:180]:     Accuracy Decimals: 1
[18:02:56][C][sensor.bme280:180]:     Icon: 'mdi:gauge'
[18:02:56][C][sensor.bme280:181]:     Oversampling: 16x
[18:02:56][C][sensor.bme280:182]:   Humidity 'BME280 Relative Humidity'
[18:02:56][C][sensor.bme280:182]:     Unit of Measurement: '%'
[18:02:56][C][sensor.bme280:182]:     Accuracy Decimals: 1
[18:02:56][C][sensor.bme280:182]:     Icon: 'mdi:water-percent'
[18:02:56][C][sensor.bme280:183]:     Oversampling: 16x
[18:02:56][C][sensor.wifi_signal:027]: WiFi Signal 'Meteo WiFi Signal Sensor'
[18:02:56][C][sensor.wifi_signal:027]:   Unit of Measurement: 'dB'
[18:02:56][C][sensor.wifi_signal:027]:   Accuracy Decimals: 0
[18:02:56][C][sensor.wifi_signal:027]:   Icon: 'mdi:wifi'
[18:02:56][C][api:101]: API Server:
[18:02:56][C][api:102]:   Address: meteo.local:6053
[18:02:56][C][ota:127]: Over-The-Air Updates:
[18:02:56][C][ota:128]:   Address: meteo.local:8266
[18:02:56][C][ota:130]:   Using Password.
[18:02:56][D][sensor.bme280:217]: Got temperature=23.2°C pressure=983.1hPa humidity=54.9%

The custom sensor block never seem to be called upon reboot. In Home assistant I can see my three sensor entries but with 0 value displayed. I have tried many different combinations but none seem to get values from the sensor. I must be doing something completly wrong or may have missed something obvious. Any help would be appreciated. Thanks!

@OttoWinter
Copy link
Member

From a quick look the code looks ok.

Can you try publishing a fixed value like 42 on one of the sensors in the update block? If that works that means the hardware is not wired up correctly or the library does not work.

@Lefuneste83
Copy link
Author

Thanks a lot Otto for your quick reply.

Ok loading variables with fixed values in the update block works. I find the values published in HA so the rest of the code is fine indeed.

Wiring issue is not likely as I can upload the equivalenty Arduino code and it works (same calls to the same library).

I have a very dumb question. The library I am calling "Adafruit_SI1145.h", do I need to put it myself inside some directory (and which one) or does the compiler downloads it directly from some repository ? It could be this stupid from me...

@Lefuneste83
Copy link
Author

Ok Otto I got it working... I modified slightly the custom sensor code to match the one in my Arduino sketch.

I changed the alias fonction declaration to match the one in my IDE code known to work.

From "Adafruit_SI1145 uv;" changed to "Adafruit_SI1145 uv = Adafruit_SI1145();"

Declared my variables before using them

Make a reset() call before begin() in the setup block

#include "esphome.h"
#include "Adafruit_SI1145.h"

using namespace esphome;

class SI1145_sensor : public PollingComponent {
 public:

  Adafruit_SI1145 uv = Adafruit_SI1145();

  sensor::Sensor *visible_sensor = new sensor::Sensor();
  sensor::Sensor *ir_sensor = new sensor::Sensor();
  sensor::Sensor *uvindex_sensor = new sensor::Sensor();

  SI1145_sensor() : PollingComponent(1000) { }

float visible;
float irlight;
float uvindex;

  void setup() override {
    uv.reset();
    uv.begin();
  }

  void update() override {
    visible = uv.readVisible();
    visible_sensor->publish_state(visible);

    irlight = uv.readIR();
    ir_sensor->publish_state(irlight);

    uvindex = uv.readUV();
    uvindex_sensor->publish_state(uvindex / 100.0);
  }
};

@esphome esphome locked and limited conversation to collaborators Jun 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants