I am stuck with something similar. I managed to get the events of today in a calendar and “hand it over to ESPHome”.
I than wanted to print them on my epaper.
The dates are in calendar_scheduled_events
and this code
int maxdates = atoi(id(calendar_scheduled_events).state.c_str());
for (int i = 0; i < maxdates; i++) {
it.printf(50 + (i * 5), 302 + (i * 40), id(font_medium_bold), TextAlign::TOP_LEFT, "%3.2f TEST", i);
}
prints as many lines as I have events on this day. (Just to see if it could work)
But I have absolutely zero idea on how to print the events, like I see them in HomeAssistant like this
I was hoping do to something like
int maxdates = atoi(id(calendar_scheduled_events).state.c_str());
for (int i = 0; i < maxdates; i++) {
it.printf(50 + (i * 5), 302 + (i * 40), id(font_medium_bold), TextAlign::TOP_LEFT, "%3.2f TEST", id(calendar_scheduled_events[i]).state.c_str());
}
but this obviously does not work.
text_sensor:
# get the calendar data over to ESP
- platform: homeassistant
id: calendar_scheduled_events
entity_id: sensor.calendar_scheduled_events
on_value:
then:
- lambda: 'id(data_updated) = true;'
- lambda: |-
ESP_LOGI("main", "Scheduled Events: %s", id(calendar_scheduled_events).state.c_str());
id(data_updated) = true;
Yours is actually a different question although trying to achieve the same result. What is the value in the text sensor? You’ll most likely have to read off the data and then manipulate it.
I’ve been searching for the answer for a long time and frankly Hellis81’s answer right off the bat demoralised me because it basically confirmed all I’ve been finding so far.
So I’ve taken his advice but kept to my guns a little. It would have been great to be able to send an array/list or even json (which was my first attempt but the json lib is not within the scope of the lambda in display).
Here’s what I’ve done
#define the global var to be updated
globals:
- id: globalupcomingevents
type: std::string
restore_value: yes
#expose the service on the device
api:
#... other stuff goes here
services:
- service: send_upcomingevents
variables:
thelist: string
then:
- globals.set:
id: globalupcomingevents
value: !lambda 'return thelist;'
display:
- platform: waveshare_epaper
#... other stuff goes here
lambda: |-
//... other stuff goes here
/*
I then format the string with the relevant data in
node-red (much easier) and send it to the device
by calling the service.
The string is formatted as:
"yesterday|bday| |Person A;tomorrow|gevt|18:00|Dinner with Wife;"
which will mean
1. yesterday, birthday of person A
2. tomorrow @ 6pm, dinner with wife (generic event, for icons)
*/
//... other stuff goes here
char * upcomingevents = const_cast<char*>(id(globalupcomingevents).c_str());
const char eventline_delim[] = ";";
const char eventdetails_delim[] = "|";
char * eventline_ptr = NULL;
char * eventdetails_ptr = NULL;
char * evtline = strtok_r(upcomingevents, eventline_delim, &eventline_ptr);
while (evtline != NULL)
{
ESP_LOGD("custom", "Event Line: %s", evtline); //the entire line
char * evtdetails = strtok_r(evtline, eventdetails_delim, &eventdetails_ptr);
while (evtdetails != NULL) {
ESP_LOGD("custom", "Event Details: %s", evtdetails); //one event, with details coming piece by piece
evtdetails = strtok_r(NULL, eventdetails_delim, &eventdetails_ptr);
}
evtline = strtok_r(NULL, eventline_delim, &eventline_ptr);
}
ESP_LOGD("custom", "The original global variable now is: %s", id(globalupcomingevents).c_str());
You’ll see an entire event line being printed in the logs first then you’ll see the details. I’m going to add a few more local variables to organise it and then print it out line by line (track the day header etc); but the data is all there now.
I only have to make sure the wife doesn’t put the | or ; symbol in her descriptions
Hi @fusionstream ,
I assume the data in the textstring has all the data that is shown in the screenshot. But I have no idea on how to test, what data it really contains. This is exactly my problem. If I for debugging purtposes I need to know which data structure is there, I would know how to do it on tzhe epaper, but as I have zero idea what the ESP32 is getting (Except the correct amount of data transferred), I habe no idea on how to debug it.
I am searching for a function that I have in perl like use Data::Dump qw(dump); where I simply throw in any variable, and it dumbs it in a readable way to wherever I want it.
This would help me a lot, as I than would not quess if everything is there, but know it is or it isn’t and could tweak my configuration.yaml
I’m using node red to get calendar events from HA and then formatting it all there, then sending it to the device by calling it’s service.
If the service you expose to HA specifies a string, then you will be receiving a string. HA will not allow you to send anything else (will show an error).
Since you’re receiving a string you can actually just log what you’re getting:
api:
#... other stuff goes here
services:
- service: send_upcomingevents
variables:
thelist: string
then:
- globals.set:
id: globalupcomingevents
value: !lambda 'return thelist;'
#- lambda: |-
# ESP_LOGD("custom", "The value received is: %s", thelist.c_str());
#- lambda: |-
# ESP_LOGD("custom", "The value received is: %s", id(globalupcomingevents).c_str());
See the last 2 commented blocks.
The first logs the received string (you specified a string so you get a string); The second logs the value of the global variable that I set with the string I got.
It is helpful to remember that because it’s not possible to send arrays/lists, we send strings. We then format the string in a way that we can then later parse and “tokenise”.
HI,
I am coming from this project, and stripped it down to something I could understand
I am still not sure, if I do the things “just right, as they are expected”, or in the way they “just work”. Debuggin ESP is the hardest, as I could nod find a way to do it, except prints…
the HA part is pretty streght forward and works. I also assume that I have all data in the ESP, but I still have no clue on how to get it. At least I can dynamically show how MANY appointments I have on this day
Hi @fusionstream ,
many many thanks for this, I check it out. But I do want to understand, how I can manipulate the data best (I guess in the HA), as I want to make “room occupation sign” for some of our office rooms. An need to clear out some data. (If a room is blcoked from
8:00-9:00 and from 9:00-10:00 I would love to show blocked from 8:00-10:00, and I think I am more flexible in HA as memory is not the limit there.
As for your conditionals, you could do it esphome with a conditional there, a normal c++ if/else in a lambda, or you could simply display a string (BLOCKED/AVAILABLE) which is defined from HA or from node-red.