This is my test code. Not optimized, just testing. I have just started to play with arduino (got my first ever this month) so I can't say I know what I am doing. Made som changes in the code below, not tested yet. It compiles, guess that's good.
I have commented out stuff related to line1 because that is always showing the time and date, in code, from GW/controller. Enable if you want to control all 4 lines from Domoticz.
Update display by using the domoticz api:
json.htm?type=command¶m=udevice&idx=XXXX&nvalue=0&svalue=Banana
Replace XXXX with the IDX for each of the 3 lines. You'll see it when adding the 3 text devices in Domoticz. Then use the Event-system in Domoticz to add Lua-script to update the display as example in this thread.
//Credits: https://forum.mysensors.org/topic/1957/lcd-clock-and-text-sensor-node-with-new-v_text
//Soft signing.
//#define MY_SIGNING_SOFT
//#define MY_SIGNING_REQUEST_SIGNATURES
//#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
#define MY_RADIO_NRF24
#define MY_REPEATER_FEATURE
#define MY_DEBUG
#include <TimeLib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <MySensors.h>
//char lastLCD1[21] = "Line1"; //Line 1 always showing current time
char lastLCD2[21] = "Line2";
char lastLCD3[21] = "Line3";
char lastLCD4[21] = "Line4";
//20 whitespace characters used to clear your LCD line before printing to it.
//Change to fit your LCD. Don't forget to change number of chars in the writeScreen function if needed.
String LINE_BLANK = " ";
boolean timeReceived = false ;
unsigned long lastUpdate = 0, lastRequest = 0, lastDisplay = 0;
//const byte LCD1_CHILD = 1; // Child ID for LCD line 1
const byte LCD2_CHILD = 2; // Child ID for LCD line 2
const byte LCD3_CHILD = 3; // Child ID for LCD line 3
const byte LCD4_CHILD = 4; // Child ID for LCD line 4
MyMessage textMsg(0, V_TEXT);
// Initialize display. Google the correct settings for your display.
// The follwoing setting should work for the recommended display in the MySensors "shop".
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void before() {
Wire.begin(); // I2C.
lcd.begin(20, 4); // LCD with 20 chars, 4 lines.
lcd.setBacklight(HIGH); // Make sure backlight is on.
writeScreen(0, "Waiting for GW..."); // Print initial text before contact with GW.
}
void setup(void)
{
Serial.begin(115200); // Start serial.
requestTime(); // Request time from controller.
}
void presentation() {
sendSketchInfo("Domoticz LCD", "1.0"); // Send the sketch version information to the gateway and Controller
//present(LCD1_CHILD, S_INFO, "LCD_line1");
//wait(500);
present(LCD2_CHILD, S_INFO, "LCD_line2");
wait(500);
present(LCD3_CHILD, S_INFO, "LCD_line3");
wait(500);
present(LCD4_CHILD, S_INFO, "LCD_line4");
wait(500);
//send(textMsg.setSensor(LCD1_CHILD).set("-")); // initialize the V_TEXT at controller for sensor to none (trick for Domoticz)
send(textMsg.setSensor(LCD2_CHILD).set("-"));
send(textMsg.setSensor(LCD3_CHILD).set("-"));
send(textMsg.setSensor(LCD4_CHILD).set("-"));
}
void loop() {
// timer for loop delays
unsigned long now = millis();
// If no time has been received yet, request it every 10 second from controller
// When time has been received, request update every hour
if ((!timeReceived && (now - lastRequest > 10 * 1000)) ||
(now - lastRequest > 3600000UL)) { // request update from GW every hour to keep in sync
// Request time from controller.
Serial.println("Requesting time...");
timeReceived = false;
requestTime();
lastRequest = now;
}
// Update sensors every 5 seconds
if (now - lastDisplay > 5000) {
lastDisplay = now;
//request(LCD1_CHILD, V_TEXT, 0); // request new values from controller
request(LCD2_CHILD, V_TEXT, 0); // request new values from controller
request(LCD3_CHILD, V_TEXT, 0); // request new values from controller
request(LCD4_CHILD, V_TEXT, 0); // request new values from controller
}
// Update LCD time every second
if (now - lastUpdate > 1000) {
LCD_time();
lastUpdate = now;
}
}
// This is called when a message is received
void receive(const MyMessage &message) {
if (message.type == V_TEXT) { // Text messages only
Serial.print("Message: "); Serial.print(message.sensor); Serial.print(", Message: "); Serial.println(message.getString()); // Write some debug info
//if (message.sensor == LCD1_CHILD) {
// writeScreen(0, message.data);
//}
// Don't forget to change "if" to "else if" when controlling all 4 lines:
if (message.sensor == LCD2_CHILD) {
writeScreen(1, message.data);
}
else if (message.sensor == LCD3_CHILD) {
writeScreen(2, message.data);
}
else if (message.sensor == LCD4_CHILD) {
writeScreen(3, message.data);
}
}
}
void receiveTime(unsigned long ts) {
setTime(ts);
timeReceived = true;
}
void LCD_time(void) {
lcd.setCursor(0, 0);
if (timeReceived) {
lcd.print(year());
lcd.print("-");
printDigits(month());
lcd.print("-");
printDigits(day());
lcd.print(" ");
printDigits(hour());
lcd.print(":");
printDigits(minute());
} else {
writeScreen(0, "Waiting for time...");
}
}
void printDigits(int digits) {
//add leading 0 if digit = 0-9
if (digits < 10)
lcd.print('0');
lcd.print(digits);
}
void writeScreen(int line, String text)
{
// Remove anything over 20 char in text.
if (text.length() > 19)
{
text.remove(20);
}
// Clear the line
lcd.setCursor(0, line);
lcd.print(LINE_BLANK);
// Set Line
lcd.setCursor(0, line);
lcd.print(text);
}