Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Home Assistant/MySensors quirks

Home Assistant/MySensors quirks

Scheduled Pinned Locked Moved Development
1 Posts 1 Posters 12 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • OldSurferDudeO Offline
    OldSurferDudeO Offline
    OldSurferDude
    wrote on last edited by
    #1

    I just deployed my Remote Solar (with battery) Moisture Sensor. Once I got all of the subtilties nailed down, two lines of code, read and send, bloomed into over 300 lines!

    There were three Home Assistant (HA) related gotchas.

    Gotcha 1. getting data from HA.

    If you have everything coded right, HA will know about your Arduino, but you have to send a datum for each sensor (child_ids) to get HA to know about the sensors. I do this in setup

    But for reasons beyond my understanding, HA won't send anything other than binary. To get around this I send text. That is, the MyMessage is of type V_TEXT and the presentation() is S_INFO

    #define CHILD_ID_SAMPLE_INTERVAL 0
    MyMessage msgSampleInterval(CHILD_ID_SAMPLE_INTERVAL, V_TEXT);
    volatile unsigned long SamplePeriod = 20000; // ms to sleep between sensor reads
    volatile bool SamplePeriodReceived = false;
    
    void presentation(){
      present(CHILD_ID_SAMPLE_INTERVAL,S_INFO,varName); // sensor 0
      wait(REGISTERING_VARIABLES_WAIT);
    }  
    
    void setup(){
      send(msgSampleInterval.set(SamplePeriod));
        wait(MESSAGE_WAIT);
    }
    void loop(){
    
      // read data
      // send data
    
      if (SamplePeriodReceived) {
        SamplePeriodReceived = false;
        // do something with datum that came from HA
      }
      smartSleep(SamplePeriod);
    }
    void receive(const MyMessage &message){
        switch( message.getSensor() ) {
          case CHILD_ID_SAMPLE_INTERVAL:
            // MQTT topic: mysensors-in/177/0/0/0/47
            SamplePeriod = message.getLong();
            SamplePeriodReceived = true;
            break;
    }
    
    

    What's going on?

    • Basic MyMessage, but of type V_TEXT
    • The two variables need to volatile because they can be changed at any time by the background process receive(). This variable must be kept up-to-date.
    • present() is of type S_INFO (see below for varname)
    • Send an initial value in setup() so that HA knows about the variable
    • In loop(), check periodically to see if a datum came in. This is done because you want to keep the receive() routine as short as possible. Also, no sends and no print statements, no long loops, etc. in receive(). Anything you can do in loop(), do it in loop().

    The data is sent from HA as text. Doesn't matter, the message.getTYPE(); will convert it for you.

    Gotcha 2. I use an MQTT gateway. I have a wait() after every send(). I'm not sure why; my guess is that if you send to fast, the data gets overrun. For sending messages, I use 300mSec. For presentation is use 4000 mSec!!!!

    Gotch 3. Beauteous! I got it all working. Time to turn MY_DEBUG off. To ensure it is off:

      #ifdef MY_DEBUG
        #undef MY_DEBUG
      #endif
    

    It stopped working and, because MY_DEBUG was off, I couldn't figure out why. I put it back in, worked fine. It dawned on me that those debug statements took time. I added 200mSec, yes, a full half second! (Lieutenant Commander Data: 0.68 seconds sir. For an android, that is nearly an eternity.)

    Do not use delay(), that stops all processing. wait() will allow the background process to function, such as receiving data. The syntax for wait() is bool wait(unsigned long ms, uint8_t cmd, uint8_t msgtype); which will wait for the first condition to be true, but I am unable to find the cmd or msgtype. To wait for those would be much more elegant.

    • below varname

    varname This is the name that HA uses in automations, scripts, etc. The problem comes when you have two Arduinos that run the same code. HA appends an arbitrary number to the end of the variable name. This leaves you to root around HA to find out what that was. I programatically append the node number to my varname. varname must be of type string (an array of characters the byte after the last character set to 0) as opposed to type String. Using type String is not advised as it is very easy to add to the String so much that it wipes out memory beyond its bounds. A real bugger to debug, especially if it occurs in receive().

    • HA script to change interval period to 4001 mSec (assumes varname is "int177"
    sequence:
      - target:
          entity_id: text.int177
        data:
          value: "4001"
        action: text.set_value
    alias: moisture sensor 177 Sample Period 4001 HA
    mode: single
    description: Send text to change sample period to 4001
    
    1 Reply Last reply
    0
    Reply
    • Reply as topic
    Log in to reply
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes


    14

    Online

    11.7k

    Users

    11.2k

    Topics

    113.1k

    Posts


    Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
    • Login

    • Don't have an account? Register

    • Login or register to search.
    • First post
      Last post
    0
    • MySensors
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular