I would like a better way to do this too (without having to create a sensor), but here is what I did (you seem to be close):
Created a sensor that gets is data from a text file, then get the state (data) from the sensor using a markdown card. The sensor and markdown seem to keep the same format, at least the multi-line
I decided to make a ‘History of Events’, as in the Majordomo smart home platform. But I also ran into the problem described above ‘only works if the number of characters is below 255’.
Ideas appeared:
Use attributes (since they seem to be not limited by the number of characters in the value of sensor). But I don’t know how to give the sensor across platform: command_line an attribute. It is also not clear how to change the attribute inside the finished sensor (attribute_templates?).
Use card of webpage, storing data in html in www, wrapping data in html code for nice line wrapping, etc. But what the fuck … this card works through the ass and just does not update at all …
Is it possible to somehow refresh the page, by some service or in another way? Since events are generated by automation / scripts, we can add something that will trigger a page refresh (loading data from a file) …
I’ve had the exact same problem. The card does not update because of web caching that HomeAssistant is doing. The only solution that I have come up with is running my own webserver where I can tell it not to do caching, and then point the webpage card to that link.
That’s quite a pain though for a simple thing, I’m still looking for a better solution.
It is also an option. But I didn’t go that far, I added an update button to the html file, ignoring the cache, it works on a double click … I think you can also make an automatic update using a script.
We insert this into your html file (you can insert it, stupidly, in a line, or better put it into the ‘<body…’):
The caching occurs in the content card in the lovelace dashboard… which is understandable but super annoying. A yaml option to toggle this behavior on and off would be awesome.
The Workaround:
The way to bypass content caching is to use a dynamic query string and load content. Here’s how I do it for a few of my applications, and it works like a charm (almost the EXACT use case the OP is after).
Store your log content in a file in the WWW directory. HTML, text, whatever. For argument’s sake, let’s call it “log.txt” (warning, this data is accessible without authentication, beware…).
Use a different HTML file in WWW (let’s call it log.html) as your ‘webpage card’ embedded in the dashboard, with a javascript call in it to HTTP GET the log.txt and document.write() it out. The TRICK is to use a dynamic query string within the javascript GET call loading the other content. The query string is always different, so it bypasses the cache every time.
<html>
<head>
<title>TEST</title>
<script>
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
}
</script>
</head>
<body>
Log Text: <script>document.write(httpGet("/local/log.txt?" + Date.now()));</script>
</body>
</html>
i’m so happy i checked this and grateful that the forum has people that are reluctant and don’t give up.
I haven’t tried it yet, but the post and follow up just give me hope. Thanks again
Thanks for this tip! I have one question: My file contains line breaks. How do I read the file, so that it displays the line breaks? Right now it shows everything in one line.
Di you mean the text on a new line? Then you need to save the data to your file as for html, that is, add < p></ p> (need to remove the space before ‘p’) every time for new line: <p>Here is my text.</p>
really sorry, but how do we use the webpage card on a local file… could you please show me?
only use the card for external addresses, and they merely show the link, so this usage is new to me
I am using the html in www/html/daylight_settings.html, and content is is looking for in in /config/logging/filed_daylight_settings.txt.
upon loading I can see the Initial text string, but also see the HA icon we see when Ha is loading. After that, nothing is showing except for an empty card and my own menu shortcut bar, which I dont understand why that is showing at all…
I managed to show the file by using the /local/filed_daylight_settings.txt and /local/ for the paths only. Can we not change those paths at all? seems a bit strange if that were the case.
I am using this html script that works fine but since the file is having a lot of lines, does somebody know how to display directly the bottom of the file in the Web page card?
That will avoid to move the vertical scroll bar to the bottom to read the last input.
I once made top-down and bottom-up navigation buttons using ready-made JS and CSS libraries, but since I am not a programmer and have little experience, I could not bring it to mind. Over time, demolished and sunk into oblivion…
Here is the solution I use for text file, convert the file into an html format using the following shell script (this shell script is adding a first line which is refreshing the link every 5 seconds !):
#
# program to convert a file into an html format
#
/config/private_shell_scripts/text2html.awk $1 > $2
sed -i '1i<meta http-equiv="refresh" content="5">' $2
You can call this script into another shell to convert for example the output logfile into a html page. Here is an example:
I wanted to display text file content (actually, a selected set of recent lines from a log file) and couldn’t find an easy way to do this - and the accepted solution here didn’t do what I needed. I ended up using an http component. Posting here in case someone else finds it useful. See this github gist:
<html>
<meta http-equiv="refresh" content="60" />
<head>
<title>Log File</title>
<script>
// Read the logfile
// - Returns up to "NumberOfEntries" lines
// - Entries are returned in order determined by "Direction" parameter
function GetTextfileLines(FileUrl, NumberOfEntries, Direction) {
let xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", FileUrl, false );
xmlHttp.send( null );
let Lines = xmlHttp.responseText.split("\n");
let LineCount = Lines.length;
let LastLineIdx = LineCount -2; // Last entry is displayed first. The last line of the file is blank, so subtract 2 to get last line index
let FirstLineIdx = Math.max(2, LineCount-NumberOfEntries-1); // ...count backwards but stop before the header lines
let FileString = "";
// let FileString = "<table><tr><th>Date</th><th>Event</th></tr>"; // Table with Header Row
if (Direction > 0) {
for (let i = FirstLineIdx; i <= LastLineIdx; i++) {
FileString += Lines[i];
}
} else {
for (let i = LastLineIdx; i >= FirstLineIdx; i--) {
FileString += Lines[i];
}
}
return FileString;
}
</script>
</head>
<body>
<script>
// Read up to 10 most recent lines from the file
document.write(GetTextfileLines("bluetooth_devices.txt", 14, 1));
</script>
</body>
</html>