Saturday, November 28, 2020

Creating a file with no extension in Windows

 For an index to all my stories click this text

This is just a short tip for those of you who are installing the Raspberry operating system on a PC.

I am using several Raspberry Pi's in my home for different purposes. Here is my list of Raspberries that are used in my home at this moment:
- Pi 3 as a Media player
- Pi 2 as a Printer server
- Pi 3B with Octoprint for controlling my 3D printer
- Domoticz for my home automation
- Pi Zero as Internet Radio

So all in all a bunch and I am adding more. My next one is going to be a NAS as I still have some old drives lying around.

To install a new Rapsberry I download the latest Raspbian from the Raspberry website and put it on an SD card with Etcher. Nothing special until now.

SSH

The Raspberry has the capability to work headless. This means that you do not need a monitor, keyboard and mouse. You can run the Raspberry over SSH with a terminal program on your PC. I use Putty for that.



Above you can see how such a session works.

In raspi-config you can activate SSH but how are you going to start raspi-config if your Raspberry-Pi starts headless. Well you can activate SSH by putting an empty file with the name ssh in the boot folder of the SSD card.

So after writing the SD card with Etcher on my PC I open the SD card and write a file with the name SSH on it.

But there is a small problem. You need to make that empty file yourself. The file may not have an extension. And that is a bit of a problem in Windows. I struggled some time with how to do that, so here is the trick.

Open the SD directory and right-click the mouse.



Now you can make a new file. But wait, each of the options will make a file with an extension. If you make a new text file for instance the name will be ssh.txt and that is not what we want. We want NO extension.

If you make the file ssh.txt you can ask the info for it but can not remove the extension. And when there is an extension it will not activate SSH in the Raspberry.

How to make an empty file without an extension.

This is the way to do it.



Open notepad on your PC
Now you have an empty document.

Chose Save As.



Put the name of the file in as follows:

"ssh"

So put quotes around the filename. As type choose ALL and not text. And then save it into the SD's 



Now the empty file will be saved and without an extension, just like we needed.

It took me a while to find this trick. So I hope it is usefull for you to.

Till next time

Luc Volders

Friday, November 13, 2020

Sending data from ESP8266 to Domoticz part III

For a complete index to all my stories click this text

This is the third installment about using the ESP8266 as a means for sending data to Domoticz.
The first story showed how to switch a light on and off by sending commands from the ESP8266 to Domoticz. Re-read that story here: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz.html
The second story showed you how to connect a Dallas DS18B20 thermometer to an ESP8266 and send the data to Domoticz. Re-read that story here: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz-part.html

This last story (for now) shows you how to build a web-page in the ESP8266 that incorporates two buttons to send commands to Domoticz setting a light ON or OFF and displays the temperature of the Dallas DS18B20 on the webpage and automatically sends the temperature to Domoticz every 5 minutes. So this story combines both previous stories and presents the data on a nice web-page.

Setup

For combining the functions of the previous stories I presume that you have read those stories and setup the hardware on the breadboard and setup a thermometer in Domoticz like shown in those stories. If not please read them first.
Part 1: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz.html
Part 2: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz-part.html

The Software

Likewise in the previous stories the software is written in the Arduino IDE.  

The Libraries used for the Dallas DS18B20 are:
OneWire.h
DallasTemperature.h


I used a special library for building the webpage and that is:
ESP8266WebServer.h

You can find this webserver Library here:
https://github.com/esp8266/ESPWebServer

Or install it with the Arduino library manager.

The program



// Adapted by Luc Volders
// Webserver with 2 buttons
// to send command to Domoticz to
// to put a lamp on and off
// the we3bpage is refreshed every 15 seconds
// to display the up to date temperature
// and write Dallas temp on screen
// page will send temp to Domoticz every 5 Minutes

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>

ESP8266WebServer Webserver(80);

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is connected to GPIO 2 (D4) on the Wemos D1 mini
#define dallasiopin 2

// Setup a oneWire instance
OneWire oneWire(dallasiopin);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Replace with your network credentials
const char* ssid = "XXXXXXXXXXXXXXXX";
//const char* password = "password";
const char* password = "PASSWORD";

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;
HTTPClient http;

String HTMLpage = "";

unsigned long previousMillis = 0;
// Change interval for your own purposes
// 1000 (MS) * 60 (seconds) * 5 (minutes)
const long interval = 1000 * 60 * 5; 

void setup(void)
{

  sensors.begin();

  buildpage();

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  Webserver.on("/", [](){
    buildpage();
    Webserver.send(200, "text/html", HTMLpage);
  });
  Webserver.on("/lampON", []()
  {
    buildpage();
    Webserver.send(200, "text/html", HTMLpage+"<center><p style = 'color:green;'>LED is ON</p></center>");
    //digitalWrite(LED, HIGH);
        String url = "/json.htm?type=command&param=switchlight&idx=";
        url += String(3);
        url += "&switchcmd=On";
          http.begin(host,port,url);
          int httpCode = http.GET();
          if (httpCode) 
          {
            if (httpCode == 200) 
            {
               String payload = http.getString();
               Serial.println("Domoticz response "); 
               Serial.println(payload);
            }
           }     
    delay(1000);
  }
  );

  
  Webserver.on("/lampOFF", []()
  {
    buildpage();
    Webserver.send(200, "text/html", HTMLpage+"<center><p style = 'color:red;'>LED is OFF</p></center>");
    //digitalWrite(LED, LOW);
    String url = "/json.htm?type=command&param=switchlight&idx=";
    url += String(3);
    url += "&switchcmd=Off";
             http.begin(host,port,url);
          int httpCode = http.GET();
          if (httpCode) 
          {
            if (httpCode == 200) 
            {
               String payload = http.getString();
               Serial.println("Domoticz response "); 
               Serial.println(payload);
            }
           } 
              Serial.println("closing connection");
  http.end();
    delay(1000); 
  }
  );
  
  Webserver.begin();
  Serial.println("HTTP Webserver started");
}
 
void loop(void)
{
  Webserver.handleClient();
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= interval) 
    {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
    senddomo();
    } 
}

void buildpage()
{
   // sensors.begin();
  Serial.println("Requesting temperatures for webpage...");
  sensors.requestTemperatures();
  
  HTMLpage = "";
  HTMLpage += "<body bgcolor=PowderBlue>";
  HTMLpage += "<META HTTP-EQUIV='refresh' CONTENT='15'>";
  HTMLpage += "<center><h1 style = 'color:red;'>Luc's Domoticz Control</h1>" ;
  HTMLpage += "<br>" ;
  HTMLpage += "<center><h1 style = 'color:black;'>Temperature : ";
  HTMLpage += (sensors.getTempCByIndex(0));
  HTMLpage += "</h1><br>" ;
  HTMLpage += "<p><h1>Lamp : </h1>";
  HTMLpage += "<a href=\'lampON\'><button style = 'background-color:green; font-size: 1.2em;'>ON</button></a>";
  HTMLpage += "&nbsp;&nbsp;&nbsp;" ;

  HTMLpage += "<a href=\' lampOFF\'><button  style = 'background-color:red; font-size: 1.2em;'>OFF</button>";
  HTMLpage += "</a></p></center>" ;
}

void senddomo()
{
  Serial.print("temperature is ");
  Serial.println((sensors.getTempCByIndex(0)));

  Serial.println("Requesting temperatures for domoticz ...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // After retrieving the temperature, we can print it.
  Serial.print("Temperature is: ");
  int TEMP = (sensors.getTempCByIndex(0));
  Serial.println(TEMP);
  // Here is the Json format that Domoticz expects
  // /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP
  String url = "/json.htm?type=command&param=udevice&idx=";
         url += String(5297);
         url += "&nvalue=0&svalue="; 
         url += String(TEMP);

  Serial.print("Connecting to ");
  Serial.println(host);
  Serial.print("Requesting URL: ");
  Serial.println(url);
  http.begin(host,port,url);
  int httpCode = http.GET();
    if (httpCode) 
    {
      if (httpCode == 200) 
      {
        String payload = http.getString();
        Serial.println("Domoticz response "); 
        Serial.println(payload);
      }
    }
   
  Serial.println("closing connection");
  http.end();
}


Most of the program is self explanatory. Nevertheless I will highlight some parts for those of you who want to modify it.

ESP8266WebServer Webserver(80);

This line makes sure that the webserver is started on port 80. This is the standard port for web servers in your router.

// Replace with your network credentials
const char* ssid = "XXXXXXXXXXXXXXXX";
//const char* password = "password";
const char* password = "PASSWORD";

Like always replace these values with the name of your router and the password.

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;

Same as above. Replace these values with the IP number from your Domoticz system. The port 8080 is the standard port on which Domoticz broadcasts its webpage.

const long interval = 1000 * 60 * 5;

The variable interval defines how often the temperature value is send to Domoticz. In this case 1000 * 60 = 1 minute * 5 makes every 5 minutes. adapt that to your own needs. Replace for example the 5 with 30 if you want the ESP to send the temperature every 30 minutes to Domoticz.

  Webserver.on("/", [](){
    buildpage();
    Webserver.send(200, "text/html", HTMLpage);
  });

This piece of code refreshes the webpage when you use the refresh button in tour browser or just access the webpage for the first time.

Webserver.on("/lampON", []()

The code that follows after this statement is the code that is executed when you push the ON button on the webpage. It also displays the text LED is ON in the color green on the screen. This is also the part where the button ON part is send to Domoticz

Webserver.on("/lampOFF", []()

Same as above but now the part that is executed when you press the OFF button. It puts the text LED is OFF in red on the screen and sends the OFF information to Domoticz.

void loop(void)
{
  Webserver.handleClient();
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= interval)
    {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  
    senddomo();
    }
}

In the loop the webserver looks if any button is pressed and if that is the case it starts the ON or OFF rourine as described above. Next there is a test wether the time passed in miliseonds is larger as the defined interval variable. If that is the case the senddomo() routine is called which sends the actual temperature to Domoticz.

void buildpage()

This is the routine where the actual webpage is build.

HTMLpage += "<META HTTP-EQUIV='refresh' CONTENT='15'>";

This particular line makes sure that the webpages auto refreshes every 15 seconds to give you  the current temperature. Adjust it to your own liking.
The rest of the lines just build the webpage with the temperature and the buttons.

void senddomo()

This routine retrieves the current temperature from the Dallas DS18B20 and sends it to Domoticz. This routine is called evry X seconds where X is defined by the variable interval as discussed above.

Now open the serial monitor of your Arduino IDE and look at which IP adress the ESP8266 is located.




Put the IP adress in your browser and you will see the above webpage.



And here is ann example of the Domoticz log.

This completes this series. You now have all the tools to control Domoticz switches and send data to Domoticz using an ESP8266. Adapt this to your own needs.

Till next time
Have fun

Luc Volders

Friday, November 6, 2020

Sending data from ESP to Domoticz part II

For an index to all my stories click this text

In the first part of this series I showed you how to switch your lights on and off by having an ESP 8266 sending commands to Domoticz. You can re-read that story here: http://lucstechblog.blogspot.com/2020/01/sending-data-from-esp-to-domoticz.html

In this part I am going to show you how to build a thermometer with an ESP8266 and have it send it's data to Domoticz. Naturally the thermometer can be used as an example to send any information you like to Domoticz and display it on the Dashboard.

Domoticz part

First step is to build a Virtual sensor in Domoticz. This is a sensor that is not physically connected to Domoticz. So start with opening your web-browser and open your Domoticz dashboard.




Go to the settings tab in Domoticz and choose hardware.



Fill in the name, I choose Virtual 2 as I already have another ESP running as a thermometer. Feel free to use a meaningfull name for yourself.
As type select Dummy, and choose add.




As you can see in the list Virtual 2 has been added. This device has been given an IDX which is not important for us now.



Now on the line with Virtual 2 click on the blue button that mentions: Create virtual sensors. A small screen opens in which you can give your sensor a name and you can select a type from the drop-down list. Choose a meaningfull name and as type choose temperature.

Briefly a popup screen appears mentioning that a new sensor has been created which is visible in the devices menu.


In the devices menu you will find your new designed thermometer. In my particular case it has IDX 5223. This is important as you will need this jnumber in the ESP8266 program later on.


Now move over to the Temperature tab and there your new thermometer is visible. The temperature is set at 0 degrees Celsius as no data has been received yet.

ESP8266 part

Building a thermometer with an ESP8266 is actually quite easy. You will only need an ESP8266,  a Dallas DS18B20 thermometer chip and a 4k7 pull up resistor.
You can find a detailed description on how to build one here: http://lucstechblog.blogspot.com/2017/11/oh-no-not-another-wifi-thermometer.html

This time we are going to do things differently. I am going to use an ESP8266 and the software will be in Arduino IDE (C++) and NOT in ESPBasic.


As you can see the breadboard setup is very straightforward. As mentioned just an ESP8266 (Wemos Mini D1 clone), a DS18B20 and a 4k7 pull-up resistor attached to D4 (GPIO 2).

Testing The DS18B20

Before we will send data to Domoticz we have to make sure that the Dallas DS18B20 works like it should.

This is one of the most usefull things I learned during all my years as tinkerer. Do everything step by step. This makes searching for errors much easier. If we directly started with software that send data to Domoticz, and it did not work we could not be sure wether the hardware of the software was the faulty part. So lets do this step by step.



// Test program for Dallas DS18B20
// Adapted by Luc Volders

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is connected to GPIO 2 (D4) on the Wemos D1 mini
#define dallasiopin 2

// Setup a oneWire instance
OneWire oneWire(dallasiopin);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);


void setup()
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature Demo");

  // Start the library
  sensors.begin();
}


void loop()
{ 
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // When we got the temperatures, we can print it here.
  // Use the temperature from the first sensor only.
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));  
  delay (2000);
}


A quick look at the program.

First two libraries are loaded: OneWire and DallasTemperature. The first one takes care of the communication between the ESP and the DS18B20 over the one wire. The second library reads  and interprets the received data.

We define that the OneWire library is connected to dallasiopin which is IO pin 2 (D4)

In the setup we open the Serialport so we can see what happens, and start the DallasTemperature library with the attached command sensors.begin()

In the loop the actual reading from the sensor is done.

sensors.requestTemperatures();

This is the line that gets the temperature from one (or more attached) sensor(s).

Serial.println(sensors.getTempCByIndex(0));

And this line prints the temperature fetched from sensor (0) in Celsius.

You can alter this line in:

Serial.println(sensors.getTempFByIndex(0));

to get the temperature in Fahrenheit.

Compile and upload the code with the Arduino IDE and open the Serial Monitor.



This is what you will see as the temperature in your case will undoubtedly be different. As you can see it is rather cold in my mancave.

As the test is successfull we can now be sure that the hardware is working ok.

Domoticz API

To send data to Domoticz we have to use the API. So let's visit the Domoticz documentation again. In the previous story I showed you where to find it. Here is the link again:
https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's

Scroll a bit down the list and in the index you can see that Chapter 7 part 7.1 gives you details about using a temperature sensor. So move to that part:
https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's#Temperature

Here we can see that the API for uploading temperature to Domoticz is as follows:

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP

IDX is the number of your device in Domoticz
TEMP is the temperature.

We have to incorporate this in our program.

We will use the same program as in the previous story but make alterations for the Dallas DS18B20 and the different API call.


// Program to send Temperature data from a
// Dallas DS18B20 with an ESP8266 to Domoticz
// adapted by Luc Volders

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into GPIO 2 (D4) on the Wemos D1 mini
#define dallasiopin 2

// Setup a oneWire instance
OneWire oneWire(dallasiopin);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// WiFi settings
#define wifi_ssid "XXXXXXXXXXXXX"
#define wifi_password "YYYYYYYYYYY"

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;

HTTPClient http;

void setup() 
{
  Serial.begin(115200);
  setup_wifi();   

  // Start up the library
  sensors.begin();
}

void settemp()
{
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // Get the temperature from the first sensor only.
  Serial.print("Temperature for the device 1 (index 0) is: ");
  int TEMP = (sensors.getTempCByIndex(0));
  Serial.println(TEMP);
  // Here is the Json format that Domoticz expects
  // /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP
  String url = "/json.htm?type=command&param=udevice&idx=";
  url += String(5223);
  url += "&nvalue=0&svalue="; 
  url += String(TEMP);

  sendToDomoticz(url);
}  

void loop() 
{
  settemp();
  delay (300000);
}

//Connect to wifi
void setup_wifi() 
{
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connection Established");
  Serial.print("IP Adress : ");
  Serial.print(WiFi.localIP());
}


void sendToDomoticz(String url)
{
  Serial.print("Connecting to ");
  Serial.println(host);
  Serial.print("Requesting URL: ");
  Serial.println(url);
  http.begin(host,port,url);
  int httpCode = http.GET();
    if (httpCode) 
    {
      if (httpCode == 200) 
      {
        String payload = http.getString();
        Serial.println("Domoticz response "); 
        Serial.println(payload);
      }
    }
  Serial.println("closing connection");
  http.end();
}


As you can see this software is adapted from the software we used in the previous story. A close examination of the most important parts will help you adapt it for your own purposes.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

The program starts with importing the necessary libraries. After that the DallasTemperature and OneWire setup is done as described above in our test program.

// WiFi settings
#define wifi_ssid "XXXXXXXXXXXXX"
#define wifi_password "YYYYYYYYYYY"

// HTTP Domoticz settings
const char* host = "192.168.1.66";
const int   port = 8080;

Here you have to fill in your own credentials and IP number of your Domoticz system.

Move over to the setup part.

sensors.begin();

This command starts the reading of the DS18B20 sensor

setup_wifi();

This calls our Wifi setup routine. In that routine a connection is established with your router and the program displays the IP number of the ESP in the serial monitor. Then automatically the void loop() is called.
In the loop the settemp() routine is called every 5 minutes. This is achieved by the delay(300000). Five minutes is 5 x 60 (seconds) x 1000 (milis) = 300000. This value is ok for testing purposes. Sending temperature every 5 minutes is a totall overkill for Domoticz. So adapt this to your own needs. Every half hour would be more appropriate. Therefore change the delay value to 30 * 60 *1000 = 18000000

In the settemp() routine all the elements of the API call are assembled in the variable url. In the documentation we saw that the API call was as follows:

/json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=TEMP

So this is build step by step into the variable url.

String url = "/json.htm?type=command&param=udevice&idx=";

Here the first part of the call is put into the variable.

url += String(5223);

This line adds the IDX. Replace this with your own IDX.

url += "&nvalue=0&svalue=";
url += String(TEMP);

These lines add the last part of the API call. TEMP is a figure and converted to a string with STRING(TEMP) The value TEMP is the temperature collected by this statement:

int TEMP = (sensors.getTempCByIndex(0));

That's all.

Again compile and upload the code with the Arduino IDE and open the Serial Monitor. In the serial monitor you can see, just as with our teswt program,

Back to Domoticz

First wrap your fingers around the DS18B20 and make sure this makes the temperature go up.

Now open Domoticz in your webbrowser and go to the temperature tab. There you will see something similar to this:


As you can see the ESP8266 indeed send the temperature from the DS18B20 straight to Domoticz. The icecube has been replaced with the actual value.

This story and the previous one showed you how to control light switches through Domoticz with an ESP8266 and send a sensor value to Domoticz.

Next time we are going to expand the program to build a webpage that contains buttons for switching the light switches and displays the temperature that is send to Domoticz.

For now you will have enough documentation to control switches and send all kinds of data from various sensors to Domoticz. Just adapt the program to using the right API call which can be found in the Domoticz documentation.

Till next time
have fun

Luc Volders