Private Cloud via Web3 Visible on Web2 Part 2

ESP32 Code

Follow this section if you’re using an ESP32.

After installing the necessary board add-ons, copy the following code to your Arduino IDE, but don’t upload it yet. You need to make some changes to make it work for you.

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// REPLACE with your Domain name and URL path or IP address with path
const char* serverName = "http://my-ipaddress/esp-post-data.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page. 
// If you change the apiKeyValue value, the PHP file /post-esp-data.php also needs to have the same key 
String apiKeyValue = "tPmAT5Ab3j7F9";

String sensorName = "BME280";
String sensorLocation = "Office";

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;  // I2C
//Adafruit_BME280 bme(BME_CS);  // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);  // software SPI

void setup() {
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  // (you can also pass in a Wire library object like &Wire2)
  bool status = bme.begin(0x76);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring or change I2C address!");
    while (1);
  }
}

void loop() {
  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    WiFiClientSecure *client = new WiFiClientSecure;
    client->setInsecure(); //don't use SSL certificate
    HTTPClient https;
    
    // Your Domain name with URL path or IP address with path
    https.begin(*client, serverName);
    
    // Specify content-type header
    https.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    // Prepare your HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
                          + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
                          + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);
    
    // You can comment the httpRequestData variable above
    // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
    //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = https.POST(httpRequestData);
     
    // If you need an HTTP request with a content type: text/plain
    //https.addHeader("Content-Type", "text/plain");
    //int httpResponseCode = https.POST("Hello, World!");
    
    // If you need an HTTP request with a content type: application/json, use the following:
    //https.addHeader("Content-Type", "application/json");
    //int httpResponseCode = https.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");
    
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    https.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);  
}

Setting your network credentials

You need to modify the following lines with your network credentials: SSID and password. The code is well commented on where you should make the changes.

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Setting your serverName

You also need to type your domain name, so the ESP publishes the readings to your own private server.

const char* serverName = "http://my-ipaddress/esp-post-data.php";

Now, you can upload the code to your board.

Note: As we are not exposing any of this directly to the internet, we can disregard HTTPS; diode will take care of the security for us.

If everything is correct, this is what you should see in your Arduino IDE Serial Monitor:

If you open your domain name in this URL path:

http://my-ipaddress/esp-weather-station.php

You should see the latest 20 readings stored in your database. There are two gauges that show the latest temperature and humidity readings, and a timestamp.

Refresh the web page to see the latest readings:

You can also go to phpMyAdmin to manage the data stored in your SensorData table. You can delete it, edit, etc…

Setting up Diode
In the cli just run the below

curl -Ssf https://diode.io/install.sh | sh

To test that diode installed properly do diode or ./diode config and you should see your client info output like so

./diode config
INFO Diode Client version : v0.13.6-1-g8d855fe-dirty 04 Mar 2024
INFO Checking for updates...
INFO No updates
INFO Client address       : 0xe78aab27d263cc497a20411xxxxxxxxxxxxxxx
INFO Fleet address        : 0x8831c475ab58809f249250xxxxxxxxxxxxxxx
INFO <KEY>                : <VALUE>
INFO fleet                : 0x8831c475ab58809f24925075xxxxxxxxxxxxxxx
INFO last_update_at       : 0x66xxxxxx
INFO lvbh3                : 0x000001b87269ecdb068fe0a75fc89eb583ad8cxxxxxxxxxxxxxxx
INFO lvbn3                : 0x6dxxxxxxxxxxxxxxx
INFO <address>            : 0xe78aab27d263cc497a20411793xxxxxxxxxxxxxxx
INFO private              : <********************************>

Now that we have diode we can take the client address and use it to publish the server we created out to the internet over diode. so lets run ./diode -update=false -dbpath=~/opt/diode/wal1 -debug publish -public my-ipaddress:80:80 (or whatever port you are running)

You will see the output with hexadecimal (client address) like

INFO Diode Client version : v0.13.6-1-g8d855fe-dirty 04 Mar 2024
INFO Client address       : myclient address on diode hexadecimal number
INFO Fleet address        : 0x6000000000000000000000000000000000000000
DEBUG Adding relay#0 [] @ as2.prenet.diode.io:41046
DEBUG Adding relay#0 [] @ eu1.prenet.diode.io:41046
DEBUG Adding relay#0 [] @ us2.prenet.diode.io:41046
DEBUG Adding relay#0 [] @ eu2.prenet.diode.io:41046
DEBUG Adding relay#0 [] @ us1.prenet.diode.io:41046
DEBUG Added relay#0 [0x1350d3b501d6842ed881b59xxxxxxxxxxx] @ as2.prenet.diode.io:41046
INFO Network is validated, last valid block: 7179185 0x00000bb8e1c99c0a4e1b42bd1203e83748b11fdf7a929cbf28023f223bf91ff0
DEBUG Added relay#0 [0xceca2f8cf1983b4cf0c1ba51fd382c2bc37aba58] @ us1.prenet.diode.io:41046
DEBUG Added relay#0 [0x7e4cd38d266902444dc9c8f7c0aa716a32497d0b] @ us2.prenet.diode.io:41046
DEBUG Added relay#0 [0x937c492a77ae90de971986d003ffbc5f8bb2232c] @ eu1.prenet.diode.io:41046
INFO Client name          : myclientname.diode
INFO
INFO HTTP Gateway Enabled : http://myclientaddress.diode.link/
INFO Port      <name>     : <extern>     <mode>    <protocol>     <allowlist>
INFO Port myipaddress:80 :       80      public       any
DEBUG Added relay#0 [0xae699211c62156b8f29ce17be47d2f069a27f2a6] @ eu2.prenet.diode.io:41046

You can then put the URL into the browser, and you will see the sensor database accessible across Web2 secured by Diode via Web3. You can make this private for proxy access only, but that’s beyond the scope of this tutorial.

To assign a more friendly name you can run ./diode bns -register my-preferred-name (note only names with a minimum of 8 characters are supported)
Be patient as it can take up to 5 minutes for the name to register, once complete you can then go to your chosen-name.diode.link and it will appear.

Wrapping Up: A Journey into Private Sensor Data Hosting

In this comprehensive tutorial, you’ve embarked on a fascinating journey, learning how to publish sensor data securely into a local private Raspberry Pi database hosted on your very own server. The best part? No third parties involved, no need for a public IP address, and all of this straight from the comfort of your home broadband. By utilizing a Raspberry Pi, you’ve not only saved at least 20 dollars a month in hosting fees but also gained the ability to access your data from anywhere in the world. :earth_americas:

But wait, there’s more! Here are some exciting next steps:

  1. Customize the Web Interface: Why settle for the mundane? Tweak the appearance of your web page, add your personal touch, and make it uniquely yours.
  2. Expand to a Sensor Farm: Imagine managing multiple sensors seamlessly. Build a full-blown sensor farm, monitor various data points, and take your project to the next level.
  3. Project Collaboration: If you’re keen on turning this into a larger endeavor, consider hiring us on a project basis. We’d love to help you scale up and fine-tune your setup.

And that’s not all! In my upcoming post, we’ll delve into the intricacies of modifying Diode to align with your corporate branding. Plus, we’ll explore transitioning from the Diode development network to your very own production network. Buckle up for an exciting ride as we enhance the Diode network, ensuring quality of service and contributing capacity to a technology revolution. :rocket:

Feel free to reach out if you have any questions or need further assistance. Happy coding! :woman_technologist::man_technologist:

see end result here weather-bm280.diode.link
Youtube https://youtu.be/HjC_El6iecg

2 Likes