Blynk 2.0 - Adding multiple devices to one template

Its a old post and i have read it.
For beginners like me it looks hard as soon as start to read the blog.

My request is:

Showing us a basic sketch,
One device with blynk code
And other with mqtt code.

Just controlling a led over blynk app. Setting up node red is available.

So with this example we can start to implement the same with other sensors n stuff like you do and posted in your blog.

This already seems exiting, at the same time a bit afraid.

Its a request for you post a very basic sketch.
Thank you in advance.

There’s a big difference between Blynk code an an MQTT sketch.
The MQTT sketch needs to connect to WiFi, in the same way that you would if you were using Blynk.config and Blynk.connect.

You then need to think about connection checks and reconnection routines, and to do the same for your MQTT connection.

A cut-down sketch without this wouldn’t mean much, and wouldn’t be the basis for a good sketch running on a device.
In addition you wouldn’t be able to use it without a connection to an an MQTT server, and wouldn’t be able to be used with Blynk without a Node-Red installation.

It’s not a quick fix to migrate to MQTT and Node-Red, but it is a far better solution than a Legacy local server - and needs a similar amount of work and the same fort of hardware.

Pete.

Yeah i am getting your point.

What I know about mqtt is there will be a topic to which the device will subscribe and exchange the message. Correct me if i am wrong.

So if you provide a bare min sketch, we can fill in our node red server address, topics etc. and see how the device talk to the other device with blynk.

Just like an example to get started with.

Not exactly.
You wouldn’t normally subscribe and write to the same topic.

Think of a subscription as being like adding a BLYNK_WRITE callback function. Without it, your device won’t be aware of changes to the corresponding virtual pin. With it, it will be triggered when the virtual pin value changes.
An MQTT subscription is the same. If you subscribe to a topic then the MQTT callback will be triggered when the topic value changes. If you don’t subscribe to it then changes to the topic are ignored by the device.

Publishing to a topic is a bit like using Blynk.virtualWrite. It’s simply a way of writing a value to a topic. You don’t need to be subscribed to the topic, and in fact it’s not something you’d normally do.

Things are a bit messy (certainly as far as I’m concerned) because all data that comes from the callbacks are char variables, and when you publish data it also needs to be a char variable
I don’t like char variables, and don’t really understand them, so I convert them to strings as soon as they arrive, and convert my other variables (integer, float, string etc) to char as part of the publish command.

I don’t have any simple example sketches kicking around, but I’ll take a look at putting something together.

Pete.

Omg this is definitely hard. You are a experienced person, if you are feeling it “messy” think about a novice like me ! :confused:

Eagerly waiting for this moment :star_struck:.

Thank you .

Okay, here’s a sketch hacked together from segments of my regular (much larger) MQTT sketch.

What it does…
The sketch allows the onboard LED of a NodeMCU (pin GPIO2, active LOW) to be turned on/off by an MQTT message on the Test_Device/LED_Command topic.

The NodeMCU sends-back a confirmation of the LED status on the Test_Device/LED_Status topic.

In addition, the NodeMCU publishes it’s RSSI signal strength, Free RAM and Uptime on the Test_Device/RSSI, Test_Device/Free_RAM and Test_Device/Uptime topics once every second.

Here’s the sketch…

#include <ESP8266WiFi.h>
#include <PubSubClient.h>     // https://github.com/knolleary/pubsubclient
#include <SimpleTimer.h>      // Non-blocking timer


// Wi-Fi Credentials...
const char *ssid =                "REDACTED"; 
const char *pass =                "REDACTED";

// MQTT Server Setting variables...
IPAddress mqtt_server_ip          (xxx,xxx,xxx,xxx);  // IP Address for the MQTT Server...
const int mqtt_port =             1883;               // Port for the MQTT Server...
const char *mqtt_username =       "REDACTED";         // MQTT Server username...
const char *mqtt_password =       "REDACTED";         // MQTT Server password...


// Define WiFi, MQTT & timer objects...
WiFiClient My_WiFi_Client;
PubSubClient MQTTclient(My_WiFi_Client);
SimpleTimer timer;

#define LED_Pin 2       // NodeMCU LED Pin = GPIO2 (Active LOW)


void setup()
{
  Serial.begin(74880);
  pinMode(LED_Pin, OUTPUT);
  digitalWrite(LED_Pin, HIGH);  //Turn the onboard LED Off

  MQTTclient.setServer(mqtt_server_ip, mqtt_port);
  MQTTclient.setCallback(MQTTcallback);           // This function is called automatically whenever a message arrives on a subscribed topic
  
  Connect_to_WiFi();
  Connect_to_MQTT_and_Subscribe();

  timer.setInterval(1000L, Send_Data);          // Timer to send the RSSI, free memory and uptime data to the MQTT server 
  timer.setInterval(30000L, Check_Connections); // Timer to check that we're connected to MQTT
}


void loop()
{
  timer.run();
  MQTTclient.loop();
}


void Connect_to_WiFi()
{
  WiFi.begin(ssid, pass);

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

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}


void Connect_to_MQTT_and_Subscribe()
{
  Serial.println("Connecting to MQTT...  ");
  // We'll connect with a Retained Last Will (LWT) that updates the 'Test_Device/Status' topic with "Dead" when the device goes offline...
  // Attempt to connect...

  MQTTclient.connect("My_Test_Device", mqtt_username, mqtt_password, "Test_Device/Status",0, 1, "Dead");
  {
    // We get here when the connection attempt was successful... 
     MQTTclient.publish("Test_Device/Status","Alive",true); // Update the LWT status to Alive
    Serial.println(F("MQTT Connected"));

    // then we subscribe to the watched topics
    MQTTclient.subscribe("Test_Device/LED_Command");   // Watch the Test_Device/LED_Command topic for incoming MQTT messages
    // Add other watched topics in here...
  }
}


void Check_Connections() // Called with a timer
{
  if(WiFi.status() != WL_CONNECTED)
  {
    Connect_to_WiFi(); 
  }  
   
  if (!MQTTclient.connected())
  {
    Connect_to_MQTT_and_Subscribe();
  }
}


void Send_Data() // Called with a timer
{
  MQTTclient.publish("Test_Device/RSSI",String(WiFi.RSSI()).c_str(),true);                        // Publish RSSI
  MQTTclient.publish("Test_Device/Free_RAM",String(ESP.getFreeHeap()).c_str(),true);              // Device Free RAM
  MQTTclient.publish("Test_Device/Uptime",String(millis()/1000).c_str(),true);                    // Uptime in seconds  
}

void MQTTcallback(char* topic, byte* payload, unsigned int length) // Triggerd whne a message arrives on a subscribed topic
{
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] [");
  for (unsigned int i=0;i<length;i++)
  {
    Serial.print((char)payload[i]);
  }
  Serial.println(F("]"));    
  
  String msg_topic = String((char *)topic);
  String msg_payload = String((char *)payload);
  msg_payload.remove(length); // Trim any unwanted characters off the end of the string
  // We now have two string variables, 'msg_topic' and 'msg_payload' that we can use in 'if' statements below... 


  // This example shows how to turn a device on and off with a "1" of "0" command on the 'Test_Device/LED_Command' topic 
  // Confirmation is echoed-back to Node-Red on the 'Test_Device/LED_Status' topic
  if (msg_topic=="Test_Device/LED_Command")
  {
    SwitchDevice(msg_payload);
  }

  // Handle messages from other topics in here,
  // just like we did with the 'Test_Device/LED_Command' topic above.
  // DON'T FORGET to subscribe to the topic in `Connect_to_MQTT_and_Subscribe()`
}


void SwitchDevice(String power_command) // Called from the MQTT callback
{
  if (power_command=="0") // If this was a power off ("0") instruction then turn the LED off (HIGH)
  {  
    digitalWrite(LED_Pin, HIGH);
    MQTTclient.publish("Test_Device/LED_Status","0"); // Feedback confirmation to Node-Red that device is now off
    return;
  }

  if (power_command=="1") // If this was a power on ("1") instruction then turn the LED On (LOW)
  {
    digitalWrite(LED_Pin, LOW);
    MQTTclient.publish("Test_Device/LED_Status","1"); // Feedback confirmation to Node-Red that device is now on
    return;
  }  
}


Note that the first field in the MQTTclient.connect command (“My_Test_Device”) is the MQTT Client ID. This MUST be unique for every client device that connects to your MQTT server

MQTTclient.connect("My_Test_Device", mqtt_username, mqtt_password, "Test_Device/Status",0, 1, "Dead");

The example uses blocking WiFi and MQTT connection commands, but my regular sketch uses non-blocking versions which will put the device into “offline mode” so that physical switches can be used to control devices if WiFi or the MQTT connections havent been established after a set number of attempts.
The example checks the connection status every 30 seconds and re-connects to either WiFi or MQTT if necessary.

As I said earlier, PubSub client uses character variables. The example sketch converts the incoming messages (the subscribed messages which trigger the MQTTcallback function) into strings, so that they can easily be used in if statements.
I’ve left the incoming commands on the Test_Device/LED_Command topic as strings, and used these to turn the LED on and off. This isn’t how I’d normally choose to do things - I’d convert the strings into integers or Boolean variables - but strings can be useful when passing commands that are going to be displayed on LCD or Nextion displays, so I skipped the conversion of the string to an integer in the example.

When publishing data, the values are converted to strings then to char variables using commands like this:
String(millis()/1000).c_str()

A bit messy, but it works!

If the value is already a string then it can be converted to a char variable using:
my_string_variable.c_str()

You can test the functionality using just an MQTT sever (could be a free cloud service) and the MQTT Explorer program.

The MQTT Explorer output looks like this:

image

and if you use MQTT Explorer to publish a “1” to the Test_Device/LED_Command topic you get this:

image

By setting the Retain flag to True, the value is held on the MQTT server, so when the device reboots or re-connects it reads the value and actions it - like an automatic Blynk.sync function.

The serial output looks like this…

Connecting to WiFi.......
Connected, IP address: REDACTED
Connecting to MQTT...  
MQTT Connected
Message arrived [Test_Device/LED_Command] [1] << Picks-up the stored ON command
Message arrived [Test_Device/LED_Command] [0] << An OFF command sent via MQTT Explorer

A simple Node-Red flow would look like this:

image

In this part of the above flow, the on/off commands from the Blynk switch widget on pin V1 come in to Node-Red, and are published to the MQTT Test_Device/LED_Command topic, which the device is subscribed to…
image


When the device receives that command it turns the physical LED on the board On, and publishes a confirmation Node-Red on the Test_Device/LED_Status topic.

When this confirmation arrives in Node-Red it’s sent to the LED widget on pin V2 like this…
image

The other three parts of the Node-Red flow just do the same thing with the RSSI, RAM and Uptime values that the device publishes, sending them out to Blynk widgets on V3, V4 and V5…

image

I made a quick dashboard in the Blynk app, with the switch and LED on V1 and V2, the RAM, Uptime and RSSI as Gauge, Labelled Value and Superchart widgets on pins V4, V5 and V3…


.


If I wanted to use Node-Red to push other data to the same Blynk dashboard I’d just do the same thing, and that data could come from a totally different device, or some other external source.

Pete.

4 Likes

Here it comes !! The most awaited trick…. Blynk + MQTT.

I will try this out.
I will install node red on my pi tomorrow.
Excited!!

This is truly an undesired limitation. Hopefully, this will be reintroduced asap, still in 2022.

Actually, this does not make any sense to me when along with enhancing the platform, the Blynk 2.0 platform also introduced many self-conflicting features along with reduced ease of use.

To me, Blynk 1.0 was very much straight forward and easy to understand and use like multiple sensors data in a single unified page rather than device tiles.
The concept of device tiles of Blynk 2.0 looks not up to the mark for certain use cases. As many of the users raises their concerns for the on this forum.

***Why Conflicting? ***

Let’s talk about the Template feature. Say I have 3 similar device and all the devices are publishing the RSSI through a same virtual port V56. The firmware for each of the devices are same and I can group them in a single template. This was absolutely possible with Blynk 1.0 without template. But with Blynk 2.0, since the data streams are global and attached to a single template, I cannot do the same. In that case I have put each of the devices in a separate template and the very purpose of using template gone wasted. Then my question is what the advantages do I have with template? In this particular user case, nothing. In addition to global stream if you also allow us to refer some local stream associated with each sensor only like before then it would be great.

My Concerns

Since I am getting a feel of too many braking changes from Blynk 2.0 platform, specially at the UI front. Do you have by any chance any roadmap to meet user expectation and bring back the really useful features from Blynk 1.0? Believe me Dark Theme is not a high priority item to be addressed. These features are merely Ornamentary, nice to have.

2 Likes

Yeah, I agree. For example, I have a lot of ESP8266 with temperature sensors. I want to see them on one page. Not in separate templates. I’ve used Blynk for years, after the New Year I’m saying goodbye to Blynk and will be using some third party devices like Aqara where I can see exactly what I need - all sensors on one page. Simple :man_shrugging:t3:

2 Likes

I use automations to share multiple devices stream to one device , it’s like the old bridge widget from blynk 1.0

Excuse me sir, what do you mean by the old bridge?

As it was mentioned by @Blynk_Coeur, it is possible to do with automations:

  • You create a single device “Group”
  • You create an automation that forwards data from device 1 to “Group” device
  • You create an automation that forwards data from device 2 to “Group” device
  • Now you have a single view that shows data from 2 other devices

Yes, it’s still workaround, and it is not that easy as it was in 1.0, but that’s possible. By the way, this feature in our todo list. So one day :slight_smile:

3 Likes

@Dmitriy I want to implement this functionality. Can you tell me when it will be released?

@arslan43711 automations are already available. You can build this setup today

1 Like

I don’t know this is a good practice, but let me explain what i did to add multiple device to the same template.

For example:
I have 3 device with one virtual switch on each.

I used the same template id, device name and auth token. Bit different virtual pins.

Device 1= V1
Device 2= V2
Device 3= V3

And this worked like it should. I did not find any connection drops or random devices being kicked out.

Automation is having a limit of 5 for free plan. So may be free plan users must use it wisely.

The steps i followed were code based. So we are saving automation(limit) for something much complex projects.

Correct me if i am wrong.

That should work fine, but it’s not the best approach. There are more efficient ways, such as automation, HttpClient, or Node-RED.

The limitation is applied to the template, not to the whole plan.

1 Like

No, it’s not, and you shouldn’t be recommending this approach to others.

You should read this…

Pete.

1 Like

When can we expect the feature to be in use?