LoRa Soil sensor help

Hi folks,
I found these LoRa soil sensors and they’re exactly what i’ve been looking for for!
I’ve almost gotten the code sorted to where I can use the data, however i’m not sure how to format the code so that OMG can parse it and display it as a sensor.
I don’t know much about code at all, in-fact i’m surprised i’ve managed to cobble together the code below from examples.

Could anyone please help me get these to send the collected sensor data in such a way that it can be displayed as values of a probe?

Right now i receive something that looks like this in the home assistant front end:

{“Name”:“Soil2”,“Temperature”:23.43979,“Humidity”:46.63372,“Capacitance”:“887”}

It is seen as a string of text, as opposed to usable (data I can put in a graph), Ideally i’d like to have many of these devices, so any help getting this code to work better with OMG would be greatly appreciated.
Happy to buy a unit for a developer!

Thanks in advance!

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

#define NODENAME "Soil2"

#define DIO0 2
#define DIO1 6
#define DIO2 7
#define DIO5 8

#define LORA_RST 4
#define LORA_CS 10

#define SS      10   // GPIO18 -- SX1278's CS
#define RST     4   // GPIO14 -- SX1278's RESET
#define DI0     2   // GPIO26 -- SX1278's IRQ(Interrupt Request)
#define BAND  915E6

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

#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_SCK 13
//#define SPI_SS 10

int ledPin = 13;
int shu = 0;
int sensorPin = A2; // select the input pin for the potentiometer
int sensorPowerCtrlPin = 5;

int sensorValue = 0;     // variable to store the value coming from the sensor
int16_t packetnum = 0;   // packet counter, we increment per xmission
float temperature = 0.0; //
float humidity = 0.0;
String errcode = "";


// SX1278 radio = new Module(LORA_CS, DIO0, LORA_RST, DIO1, SPI, SPISettings());
AHT10 humiditySensor;



// function called to publish the temperature and the humidity
void publishData(float p_humidity) {
  // create a JSON object
  // doc : https://github.com/bblanchon/ArduinoJson/wiki/API%20Reference
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  // INFO: the data must be converted into a string; a problem occurs when using floats...
  root["temperature"] = (String)temperature;
  root["humidity"] = (String)p_humidity;
  root.prettyPrintTo(Serial);
  Serial.println("");
}

ISR(WDT_vect)
{
    Serial.print("[Watch dog]");
    Serial.println(shu);
    delay(100);
    shu++;
    wdt_reset();
}

void setup()
{
    wdt_disable();
    pinMode(ledPin, OUTPUT);
    Serial.begin(115200);
    Serial.println("[Start]");
    delay(100);
    SPI.begin();

    //setup start
    Serial.println("[Setup]");
    delay(100);

    // initialize SX1278 with default settings
    Serial.println(String("Sensor name is :") + String(NODENAME));
    Serial.print(F("Initializing ... "));
    SPI.begin();
    LoRa.setPins(SS,RST,DI0);
    if (!LoRa.begin(868E6)) {
      Serial.println("Starting LoRa failed!");
      while (1);
    }
//    else
//    {
//        Serial.print(Success!));
//        Serial.println("LoRa ok");
//        while (0)
//            ;
//    }
    LoRa.sleep();

    //AHT10
    pinMode(sensorPowerCtrlPin, OUTPUT);
    digitalWrite(sensorPowerCtrlPin, HIGH); //Sensor power on

    Wire.begin();
    if (humiditySensor.begin() == false)
    {
        Serial.println("AHT10 not detected. Please check wiring. Freezing.");
    }
    else
        Serial.println("AHT10 acknowledged.");

    read_sensor();
    //setup over

    low_power_set();
}

void loop()
{
    wdt_disable();

    if (shu > 7) //(7+1) x 8S
    {
        //code start
        Serial.println("Code start*************************************");

        read_sensor();
        //code end
        Serial.println("Code end*************************************");

        //count init
        shu = 0;
    }

    watchdog_init();
    delay(10);
    sleep_cpu();
}

//Set low power mode and into sleep
void low_power_set()
{
    Serial.println("[Set]Sleep Mode Set");
    delay(100);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    watchdog_init();
    delay(10);
    sleep_cpu();
}

//Enable watch dog
void watchdog_init()
{
    MCUSR &= ~(1 << WDRF);
    WDTCSR |= (1 << WDCE) | (1 << WDE);

    //WDTCSR = 1 << WDP1 | 1 << WDP2; //1S
    WDTCSR = 1 << WDP0 | 1 << WDP3; //8S

    WDTCSR |= _BV(WDIE); //not rst, inter interrutp
    wdt_reset();
}

void read_sensor()
{
    digitalWrite(sensorPowerCtrlPin, HIGH); //Sensor power on
    for (int i = 0; i < 3; i++)
    {
        sensorValue = analogRead(sensorPin);
        delay(200);
        if (humiditySensor.available() == true)
        {
            temperature = humiditySensor.getTemperature();
            humidity = humiditySensor.getHumidity();
        }
        if (isnan(humidity) || isnan(temperature))
        {
            Serial.println(F("Failed to read from AHT sensor!"));
        }
    }
    digitalWrite(sensorPowerCtrlPin, LOW); //Sensor power on

    String lora_msg = "#" + (String)packetnum +" NAME:" + (String)NODENAME + " H:" + (String)humidity + "% T:" + (String)temperature + " C" + " ADC:" + (String)sensorValue;

StaticJsonBuffer<200> jsonBuffer;

JsonObject& root = jsonBuffer.createObject();
root["Name"] = NODENAME;
root["Temperature"] = temperature;
root["Humidity"] = humidity;
root["Capacitance"] = (String)sensorValue;

//JsonArray& data = root.createNestedArray("data");
//data.add(temperature);  // 6 is the number of decimals to print
//data.add(humidity);   // if not specified, 2 digits are printed

//root.printTo(Serial);
//root.printTo(LoRa);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
    
    Serial.println(lora_msg);
    packetnum++;
    LoRa.beginPacket();
//    LoRa.print("test");
    root.printTo(LoRa);
    LoRa.endPacket();
//    radio.transmit(lora_msg);
    delay(1000);
    LoRa.sleep();
}

Hello,

If you see this on the mqtt broket you have done the biggest part !

Now you can create one or several sensors into your configuration.yaml following this :

You will have to tweak it so as to use the same keys as your json message and the appropriate topic

Awesome!
What would use as the State_topic? Is that something I would define on the sensor? or would that come from OMG?

Thanks!

The one that OMG publish the LORA payload to, you should be able to catch it easily with mqtt explorer or the docs

Got it!
How can I find out how to format the json properly?
Right now it still shows up as a string of text… even with the added yaml configuration.
I’ve added an “id” as it seems this is required?

{“Name”:“Soil2”,“Temperature”:19.8597,“Humidity”:52.11935,“Capacitance”:“881”,“id”:“LoRaADC”}

Any pointers would help.
Thanks!

Here’s what i tried for my yaml:

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1"
  unit_of_measurement: '%'
  value_template: '{{ value_json["adc"] }}'
  expire_after: 21600 # 6 hours
#  rssi: -33
#  snr: 9.75

modified my message to get this:

{“id”:“LoRaADC”,“name”:“Soil_1”,“model”:“LSMS092D”,“tempc”:22.35603,“hum”:44.68327,“adc”:880}

Edit:
This didn’t work… will try again later…

I used this:

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1"
  unit_of_measurement: '%'
  value_template: >-
    {% set lorasoil_json = 
    {"id":"LoRaADC","name":"Soil_1","model":"LSMS092D","tempc":22.96829,"hum":43.0563,"adc":884}
    %}
    {{ lorasoil_json.adc }} {{ lorasoil_json.unit }}

Now is there a way to group all sensors under one device?
Or do I have to repeat this for each sensor and group them in HA?

Thanks!

So i’ve tried this as well and still no luck…

Any pointers? Anything would be greatly appreciated…

Thanks

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1_ADC"
  unit_of_measurement: 'µS/cm'
  value_template: '{{ value_json.adc.value"] }}'
  expire_after: 21600 # 6 hours

So i’ve now tried this:

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1_ADC"
  unit_of_measurement: 'µS/cm'
  value_template: '{{ value_json.adc }}'
  expire_after: 21600 # 6 hours
#  rssi: -33
#  snr: 9.75

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1_Temp"
  unit_of_measurement: 'C'
  value_template: '{{ value_json.tempc }}'
  expire_after: 21600 # 6 hours

- platform: mqtt
  state_topic: 'home/OMG_01/LORAtoMQTT' # MQTT topic, check MQTT messages; replace AA... with id (BLE MAC) of your device
  name: "Soil_1_Hum"
  unit_of_measurement: '%'
  value_template: '{{ value_json.hum }}'
  expire_after: 21600 # 6 hours

my json looks like this on the gatewayLORA sensor in home assistant:

{“id”:“LoRaADC”,“name”:“Soil_1”,“model”:“LSMS092D”,“tempc”:22.62135,“hum”:39.14318,“adc”:879}

and i’m getting this message:

Logger: homeassistant.helpers.template
Source: helpers/template.py:1335
First occurred: 10:04:18 PM (6 occurrences)
Last logged: 10:05:25 PM

Template variable warning: ‘dict object’ has no attribute ‘adc’ when rendering ‘{{ value_json.adc }}’
Template variable warning: ‘dict object’ has no attribute ‘tempc’ when rendering ‘{{ value_json.tempc }}’
Template variable warning: ‘dict object’ has no attribute ‘hum’ when rendering ‘{{ value_json.hum }}’

Amy ideas?

Thanks

Here it is:
Thanks!

1 Like