Awesome! LoRa Soil sensor

@kaimo123 Can you please tell what it was that finally made it work? I have the exact same hardware as you have and I can see the OMG is working with mosquito in HA but I can’t get any reading from the Lora Soil Moisture Sensor V3. Please help me !

The original Makerfab firmware does not send data using JSON. OMG could still send this non-JSON data to HA, but it would be difficult to parse.

What most people are using is found in this thread, topic #23 from thebang2. He took the Makerfab firmware and modified it to send the LoRa data using JSON format. OMG gets this JSON formatted data from the soil sensor and marks it as a “message”, and adds some stuff and then formats it all in JSON. So HA gets an MQTT payload in JSON format and inside this is a “message” which itself is JSON formatted. The trick in HA is to configure the mqtt sensor to extract the “message” from the JSON formatted payload, and then tell HA that the value of “message” is itself JSON (using from_json) and now HA can parse the individual parameters (node_id, hum, temp, adc, bat) inside the “message”.

2 Likes

@wmaker gave advice on how to change LORA settings.
The final arduino code that worked for me:

#include <SPI.h>
#include <Wire.h>
#include <RadioLib.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include "I2C_AHT10.h"
//#include <LoRa.h>
#include <ArduinoJson.h>

#define NODENAME "LORA_KUSLAPUU_1"
String node_id = String("ID") + "ID846758";

//Set sleep time, when value is 1 almost sleep 20s,when value is 450, almost 1 hour.
//#define SLEEP_CYCLE 450
#define SLEEP_CYCLE 38    //5 Minutit

//Lora set
//Set Lora frequency
// #define FREQUENCY 434.0
#define FREQUENCY 868.0
//#define FREQUENCY 915.0

#define BANDWIDTH 125.0
#define SPREADING_FACTOR 7 
#define CODING_RATE 5 
#define OUTPUT_POWER 10
#define PREAMBLE_LEN 8
#define GAIN 0
#define SX127X_SYNC_WORD 0x12 

//328p
#define DIO0 2
#define DIO1 6

#define LORA_RST 4
#define LORA_CS 10

#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_SCK 13

//pin set
#define VOLTAGE_PIN A3
#define PWM_OUT_PIN 9
#define SENSOR_POWER_PIN 5
#define ADC_PIN A2

#define DEBUG_OUT_ENABLE 1

SX1276 radio = new Module(LORA_CS, DIO0, LORA_RST, DIO1);
AHT10 humiditySensor;

String jsonoutput = "";  // string for json transfer
bool readSensorStatus = false;
int sensorValue = 0; // variable to store the value coming from the sensor
int batValue = 0;    // the voltage of battery
int count = 0;
int ADC_O_1;           // ADC Output First 8 bits
int ADC_O_2;           // ADC Output Next 2 bits
int16_t packetnum = 0; // packet counter, we increment per xmission
float temperature = 0.0;
float humidity = 0.0;

bool AHT_init()
{
  bool ret = false;
  Wire.begin();
  if (humiditySensor.begin() == false)
  {
#if DEBUG_OUT_ENABLE
    Serial.println("AHT10 not detected. Please check wiring. Freezing.");
#endif
  }

  if (humiditySensor.available() == true)
  {
    temperature = humiditySensor.getTemperature();
    humidity = humiditySensor.getHumidity();
    ret = true;
  }
  if (isnan(humidity) || isnan(temperature))
  {
#if DEBUG_OUT_ENABLE
    Serial.println(F("Failed to read from AHT sensor!"));
#endif
  }
  return ret;
}
void Lora_init()
{
  int state = radio.begin(FREQUENCY, BANDWIDTH, SPREADING_FACTOR, CODING_RATE, SX127X_SYNC_WORD, OUTPUT_POWER, PREAMBLE_LEN, GAIN);
  Serial.println(state);
  if (state == ERR_NONE)
  {
#if DEBUG_OUT_ENABLE
    Serial.println(F("success!"));
#endif
  }
  else
  {
#if DEBUG_OUT_ENABLE
    Serial.print(F("failed, code "));
    Serial.println(state);
#endif
    // while (true)
    //     ;
  }
}
void setup()
{
#if DEBUG_OUT_ENABLE
  Serial.begin(115200);
  Serial.println("Soil start.");
  Serial.print(FREQUENCY);
  Serial.println(" Mhz");

#endif
  delay(100);

  // set up Timer 1
  pinMode(PWM_OUT_PIN, OUTPUT);

  TCCR1A = bit(COM1A0);            // toggle OC1A on Compare Match
  TCCR1B = bit(WGM12) | bit(CS10); // CTC, scale to clock
  OCR1A = 1;

  pinMode(LORA_RST, OUTPUT);
  digitalWrite(LORA_RST, HIGH);
  delay(100);

  pinMode(SENSOR_POWER_PIN, OUTPUT);
  digitalWrite(SENSOR_POWER_PIN, HIGH); //Sensor power on
  delay(100);

  Lora_init();

  Wire.begin();
  if (humiditySensor.begin() == false)
  {

#if DEBUG_OUT_ENABLE
    Serial.println("AHT10 not detected. Please check wiring. Freezing.");
#endif
  }
#if DEBUG_OUT_ENABLE
  else
    Serial.println("AHT10 acknowledged.");
#endif

  do_some_work();
  //setup over
#if DEBUG_OUT_ENABLE
  Serial.println("[Set]Sleep Mode Set");
#endif
  low_power_set();
}

void loop()
{
  wdt_disable();

  if (count > SLEEP_CYCLE) //(7+1) x 8S  450
  {
#if DEBUG_OUT_ENABLE
    //code start
    Serial.println("Code start>>");
#endif

    do_some_work();
    all_pins_low();

#if DEBUG_OUT_ENABLE
    //code end
    Serial.println("Code end<<");
#endif
    //count init
    count = 0;
  }

  low_power_set();
}

ISR(WDT_vect)
{
#if DEBUG_OUT_ENABLE
  Serial.print("[Watch dog]");
  Serial.println(count);
#endif
  delay(100);
  count++;
  //wdt_reset();
  wdt_disable(); // disable watchdog
}

//Set low power mode and into sleep
void low_power_set()
{
  all_pins_low();
  delay(10);
  // disable ADC
  ADCSRA = 0;

  sleep_enable();
  watchdog_init();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  delay(10);
  noInterrupts();
  sleep_enable();

  // turn off brown-out enable in software
  MCUCR = bit(BODS) | bit(BODSE);
  MCUCR = bit(BODS);
  interrupts();

  sleep_cpu();
  sleep_disable();
}

//Enable watch dog
void watchdog_init()
{
  // clear various "reset" flags
  MCUSR = 0;
  // allow changes, disable reset
  WDTCSR = bit(WDCE) | bit(WDE);
  WDTCSR = bit(WDIE) | bit(WDP3) | bit(WDP0); // set WDIE, and 8 seconds delay
  wdt_reset();                                // pat the dog
}

void do_some_work()
{

  digitalWrite(SENSOR_POWER_PIN, HIGH); // Sensor/RF95 power on
  digitalWrite(LORA_RST, HIGH);
  delay(5);
  pinMode(PWM_OUT_PIN, OUTPUT);    //digitalWrite(PWM_OUT_PIN, LOW);
  TCCR1A = bit(COM1A0);            // toggle OC1A on Compare Match
  TCCR1B = bit(WGM12) | bit(CS10); // CTC, scale to clock
  OCR1A = 1;                       // compare A register value (5000 * clock speed / 1024).When OCR1A == 1, PWM is 2MHz

  Lora_init();
  delay(50);

  //ADC2  AVCC as reference voltage
  ADMUX = _BV(REFS0) | _BV(MUX1);

  //ADC2  internal 1.1V as ADC reference voltage
  //ADMUX = _BV(REFS1) |_BV(REFS0) | _BV(MUX1);

  // 8  分频
  ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0);
  delay(50);
  for (int i = 0; i < 3; i++)
  {
    //start ADC conversion
    ADCSRA |= (1 << ADSC);

    delay(10);

    if ((ADCSRA & 0x40) == 0)
    {
      ADC_O_1 = ADCL;
      ADC_O_2 = ADCH;

      sensorValue = (ADC_O_2 << 8) + ADC_O_1;
      ADCSRA |= 0x40;

      //Mod for value from in 0 to 100
      // 1000 = Air dry, 500 ultrawet
      sensorValue = (sensorValue - 500) / 5;
      // End



#if DEBUG_OUT_ENABLE
      Serial.print("ADC:");
      Serial.println(sensorValue);
#endif

      if (readSensorStatus == false)
        readSensorStatus = AHT_init();
    }
    ADCSRA |= (1 << ADIF); //reset as required
    delay(50);
  }

  //ADC3  internal 1.1V as ADC reference voltage
  ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX1) | _BV(MUX0);

  delay(50);
  for (int i = 0; i < 3; i++)
  {
    //start ADC conversion
    ADCSRA |= (1 << ADSC);

    delay(10);

    if ((ADCSRA & 0x40) == 0)
    {
      ADC_O_1 = ADCL;
      ADC_O_2 = ADCH;

      batValue = (ADC_O_2 << 8) + ADC_O_1;
      ADCSRA |= 0x40;
      


#if DEBUG_OUT_ENABLE
      Serial.print("BAT:");
      Serial.println(batValue);
      float bat = (float)batValue * 3.3;
      bat = bat / 1024.0;
      Serial.print(bat);
      Serial.println("V");
#endif
    }
    ADCSRA |= (1 << ADIF); //reset as required
    delay(50);
  }
  send_lora();
  delay(1000);
  radio.sleep();

  packetnum++;
  readSensorStatus = false;
  digitalWrite(SENSOR_POWER_PIN, LOW); // Sensor/RF95 power off
  delay(100);
}

void all_pins_low()
{
  pinMode(PWM_OUT_PIN, INPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A5, INPUT_PULLUP);

  delay(50);
}

void send_lora()
{

  // Create json object for transfer
  DynamicJsonDocument root(256);
  root["node_id"] = node_id;
  root["hum"] = (String)humidity;
  root["temp"] = (String)temperature;
  root["adc"] = (String)sensorValue;
  root["bat"] = (String)batValue;

  serializeJson(root, jsonoutput);
#if DEBUG_OUT_ENABLE
  serializeJson(root, Serial);
#endif
  radio.transmit(jsonoutput);
jsonoutput = "";
}

Thanks !!
I will order a USB to serial adapter then, to be able to change the firmware on the “Lora Soil Moisture Sensor” :slight_smile:
To be continue…

This ADC change is really quite big.
Maybe the arduino code could be changed a bit. So that it takes this change into account?

1 Like

Now it works!!
Well, kind of… I get the json string in HA MQTT broker so that is great news!!
But my “dry” value in air is 70 (water 1)
Is this only to accept and make a template to adjust the sensor?
Thanks for the support @kaimo123 :ok_hand:

One way is to modify the Arduino code like @wmaker did

Yes that’s true, but it don’t change the fact that in dry air it only reeds 70, not 100.
My battery is 944 so that should not make that big of a different from if it was 1100, do you think?

1 Like

I spent some time taking more measurements of the MakerFab soil moisture sensor.

One of the results of these measurements is that I have come up with a “Correction Factor” to adjust for ADC2 changes as battery level changes.

But before I get into the measurements, just as a reference, here are the MakerFab recommended range of values for the soil measuring ADC2 (I myself added the “Moisture %” column):
image

Below are the measurements I made from two different MakerFab devices.

Some explanation:

  • I used a variable PSU to power the device, and I used several different settings ranging from 3.3V to 2.02V (which is the operating range of the device).
  • The “Bat” column is the ADC3 measurement of the battery voltage divider that has been converted to a level relative to 3.3V. In other words it reflects the actual supply voltage.
    The “Bat” here is battery_level which is nearly a copy-n-paste from MakerFab’s debug code:
    // create battery_level instead of raw ADC value   
      float battery_level = (float)batValue * 3.3;
      battery_level = battery_level / 1024.0;
  • Soil Moisture: The readings in gray are the ADC raw values, and those in black are the ADC2 values converted to have a range of 0% (very dry) to 100% (very wet).
  • Air measurements: This is with the soil probe surrounded by air. As I have had an unusual amount of rain lately with cooler temperatures, this device as well as other sensors nearby are measuring around 50-55% Relative Humidity in the air.
  • Soil/Dry: This is potting soil that has been laying around unused with little to no water. (I didn’t do this test for the second device)
  • Soil/Wet: This is the same potting soil that has had water added with the water to soil volume being around 40%. Note: To test the second device, I pulled out the first device out of the soil, and put the second device in the same slit that the first device had occupied in the soil and noticed the second device read dryer conditions. I then moved the second device’s probe in a new place in the same soil, and then found the readings were then very similar to the first device’s. Conclusion - when you insert one of these devices into the soil, make sure there are no air gaps between the probe and the soil.
  • Water: no soil, just water.

Some things to point out:

  • The dry air readings are no where near the upper end of the ADC2 which is 1023. My thought is that the PWM feeding the soil sensor circuit will peak at a voltage that is a little below the supply voltage, plus there is another diode voltage drop in the filter that feeds the ADC2, so I don’t think the upper end of ADC2’s 1023 reading will every be reached, even in bone dry air.
  • The ADC2 readings decrease a fair bit as the battery voltage drops. The drop is not exactly linear, as the ADC2 output appears to change less so at the higher supply voltages but changes more so at the lower voltages. I’ll explain below a correction factor that I came up with to help minimize this problem.
  • Water readings: one would expect the ADC2 measurements to reach the expected lower limit of 500. I was only able to reach this when the supply voltage was near 2.0V.

Correction Factor:
The first thing I decided was to correct the ADC2 readings relative to 2.0V as 2.0V is about the only voltage that hits one end of the ADC2 limits as explained above. What I decided to do next was to use a conservative linear correction of 45 (its a bit of a judgement call). So my ADC2 corrected value is:

    // Moisture ADC value decreases as battery_level decreases, so make a rough adjustment
#define BATT_ADJUST_FACTOR 45  
    sensorValue = sensorValue -((battery_level - 2.0)*BATT_ADJUST_FACTOR);
    if (sensorValue < 500)
        sensorValue = 500;

Afterwards, I repeated a couple of these tests as a sanity check and here are the results:
image

3 Likes

This looks GREAT !!
Will try it out soon, but one question, is it ok to put it in just before //Create json object for transfer (at the end) ?

// Thanks

wow @wmaker you are awesome!!!

Here is the code that I use, so you can use it as a reference.

It’s working great !!
Tested with 3,1V & 2,6V and they gave the same adc :grinning:
Thanks a lot :ok_hand:

I thought I would share how I make a MakerFab Soil Sensor look like a Device in Home Assistant.









I use a script that I run at HA startup time. This script will publish faux HA MQTT discovery messages with device information for each entity the sensor has. Be aware that HA MQTT Discovery is rather tricky, so I suggest reading up on it, and use my script only as a reference/example.

The script shown below is for a couple of devices, but MOST LIKELY YOU WILL NEED TO MODIFY IT.
The reason is that the MQTT configuration postings in this thread that most are using, use OMG “as is” and thus use the same topic for all LoRa devices: home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT, whereas I have modified OMG to provide a “per device” MQTT topic by adding the node-id at the end of the topic: home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280 (See here if interested).

Most likely, you will also want to modify the script to tailor the entities and attributes to your liking and to match what the LoRa message your device is sending. For example, I have a battery_level (estimated battery voltage) which I get from the sensor (you may be using instead the raw ADC level), and I have made battery_level an attribute of the “soil moisture” entity (you may be using instead an entity to indicate “dryness”), and I also have a battery device class as an entity to estimate the battery percentage based on 3.3V (100%) to 2.0V (0%) range.

Anyway, here is the script:

alias: Create Sensors via MQTT Discovery
sequence:
  - alias: MakerFab Soil Sensor ID010280
    service: mqtt.publish
    data:
      topic: homeassistant/sensor/13944282/config
      payload: |
        {                                    
          "name": "ID10280 Soil Moisture",
          "unique_id": "13944282",
          "device_class": "moisture",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['adc'] }}"{% endraw %},
          "json_attributes_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280",
          "json_attributes_template": {% raw %}"{{ {'battery_level':(value_json.message |from_json)['bat'] } |to_json }}"{% endraw %},
          "device": {
              "identifiers":["ID010280"],
              "name":"Soil Sensor ID010280",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13944283/config
      payload: |
        {                                    
          "name": "ID10280 Temperature",
          "unique_id": "13944283",
          "device_class": "temperature",
          "unit_of_measurement": "°C",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['temp'] | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010280"],
              "name":"Soil Sensor ID010280",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13944284/config
      payload: |
        {                                    
          "name": "ID10280 Humidity",
          "unique_id": "13944284",
          "device_class": "humidity",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['hum'] | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010280"],
              "name":"Soil Sensor ID010280",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13944285/config
      payload: |
        {                                    
          "name": "ID10280 Battery",
          "unique_id": "13944285",
          "device_class": "battery",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010280",
          "value_template": {% raw %}"{{ ((((value_json['message'] | from_json)['bat'])-2.0)*100/1.3) | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010280"],
              "name":"Soil Sensor ID010280",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - alias: MakerFab Soil Sensor ID010281
    service: mqtt.publish
    data:
      topic: homeassistant/sensor/13955282/config
      payload: |
        {                                    
          "name": "ID10281 Soil Moisture",
          "unique_id": "13955282",
          "device_class": "moisture",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010281",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['adc'] }}"{% endraw %},
          "json_attributes_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010281",
          "json_attributes_template": {% raw %}"{{ {'battery_level':(value_json.message |from_json)['bat'] } |to_json }}"{% endraw %},
          "device": {
              "identifiers":["ID010281"],
              "name":"Soil Sensor ID010281",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13955283/config
      payload: |
        {                                    
          "name": "ID10281 Temperature",
          "unique_id": "13955283",
          "device_class": "temperature",
          "unit_of_measurement": "°C",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010281",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['temp'] | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010281"],
              "name":"Soil Sensor ID010281",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13955284/config
      payload: |
        {                                    
          "name": "ID10281 Humidity",
          "unique_id": "13955284",
          "device_class": "humidity",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010281",
          "value_template": {% raw %}"{{ (value_json['message'] | from_json)['hum'] | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010281"],
              "name":"Soil Sensor ID010281",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false
  - service: mqtt.publish
    data:
      topic: homeassistant/sensor/13955285/config
      payload: |
        {                                    
          "name": "ID10281 Battery",
          "unique_id": "13955285",
          "device_class": "battery",
          "unit_of_measurement": "%",
          "state_topic": "home/OpenMQTTGateway_ESP32_LORA/LORAtoMQTT/ID010281",
          "value_template": {% raw %}"{{ ((((value_json['message'] | from_json)['bat'])-2.0)*100/1.3) | round(1) }}"{% endraw %},
          "device": {
              "identifiers":["ID010281"],
              "name":"Soil Sensor ID010281",
              "hw_version":"V3",
              "model":"LoRa Soil Moisture Sensor",
              "manufacturer":"Maker Fabs",
              "sw_version":"v0.1",
              "via_device":"Open MQTT Gateway"
          }
        }
      retain: false

Finally, once you run the script, check the logs for errors and if there are not any, you should see the device show up in HA (with unknown states). Using the developer’s tool, I also publish a faux MQTT message to simulate the LoRa message that HA will receive:

{"rssi":-88,"snr":9.5,"pferror":11735,"packetSize":76,"message":"{\"node_id\":\"ID010280\",\"hum\":54.26719,\"temp\":24.77186,\"adc\":68,\"bat\":3.18375}"}

Again, you may need to modify this to match your device’s actual output.

Enjoy :slight_smile:

I’m planning to do some work around LORA in the following weeks. Are there any features that you would like to see guys in OpenMQTTGateway?

2 Likes

Hi,
Here is a feature that may be worth considering:

A few months ago I made some modifications to my OMG using the “Value as a Topic” feature, and did it specifically for these types of LoRa Sensors. In short, if “Value as a Topic” is enabled, and the gateway is a LoRa G/W, it will attempt to parse the LoRa message using JSON and looks for “node_id” and if present, it will add the node_id’s value to the MQTT topic.
A couple of reasons for this:

  1. I prefer to have a per device MQTT topic which this feature would provide.
  2. For the Soil Sensors in this thread, the LoRa “message” has its payload JSON encoded. In Home Assistant, templates are used to decode the JSON encoded “message” and most people use the generic LoRa MQTT topic which is a shared topic for all LoRa Sensors.
    Somewhere in my neighborhood is another LoRa sensor that sends “messages” in binary. When HA gets this using the generic LoRa MQTT topic, it gets passed to the Template which tries to JSON decode the "message but it can’t so it throws a Log error. By using the “Value as a Topic” feature it, creates a per device MQTT topic that the Template can use. The offending LoRa sensor continues to use the generic MQTT topic and so the binary message does not get passed to the Template and thus avoiding the Log error.

Most of the changes I made are here:

The “Value as a Topic” was kept as a configurable item, so it can be turned on or off.

Best Regards.

2 Likes

For some reason I can’t seem to be able to upload a new version to the sensor.
Upload fails with:

Sketch uses 24050 bytes (78%) of program storage space. Maximum is 30720 bytes.
Global variables use 1074 bytes (52%) of dynamic memory, leaving 974 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problem uploading to board.  See https://support.arduino.cc/hc/en-us/sections/360003198300 for suggestions.

I’m sure the cable can be used to transfer data (I’ve used it to upload new version of openmqttgateway).
I’m not sure yet of the CP2104 module but it seems it can at least power the soil sensor (when I plug it in, the device starts sending data via LoRa)

Would anyone have an idea of what I could test?

EDIT: I’ve ordered a different USB-UART device that I should receive soon to be able to at least discard the “wrong tool” hypothesis.
EDIT2: the other ubs-uart device has the same issue, although resp bytes seems different when I press the “reset” button during the procedure. I assume the bootloader is not the one Arduino IDE expects (based on this help but clearly I’m not sure of anything)

Hello @1technophile ,

unless I’m mistaken OMG forward the LoRa message to Home Assistant as a sensor. It would be great if it could leverage mqtt discovery from HA to create devices in HA instead (for now OMG creates a device for itself only but not for the sensor it relays).

For instance, in the case of the soil sensor discussed in this thread, assuming I have two of them:

  • OMG would still create a device for itself (the gateway)
  • it would create one device per instance of the Soil sensor
  • each of those device would expose a few entities (humidity, temperature and moisture)

This would allow for everyone to immediately get values instead of having to tinker with template sensor to extract each value.
It also allows to deal easily with the fact that an OMG gateway can relay several devices.

I see two ways to implement this:

  • directly in OMG: it would need to know how to parse messages from some LoRa devices and how to expose them in HA. It would benefit from a conventional way to send messages but can also deal with custom format.
  • as a Home Assistant integration that would listen to the MQTT messages, treat them and publish devices to HA via MQTT discovery.

The second method could be maintained by somebody else than yourself easily, while the first is likely quite involved in OMG codebase.

What do you think?

Hello,

I think that is a great idea, and OMG is already doing this for BLE or RTL_433 devices, it should not be a big deal to add it for LORA devices.
The question is more about how to identify precisely the device from the LORA packet to trigger an appropriate discovery message.
We need also a unique_id that could be the node_id.

1 Like

I’ve prototyped a HA integration yesterday to validate the idea. But of course it would even better to have it in OMG directly.