Displaying custom panel with html content inside homeassistant?

Good day everyone. I’m a homebrewer that have a fermentation chamber controlled by an esp8266 running a software called brewpiless. It has a nifty ui and everything, but it also has a page the will show what is currently being displayed on the lcd on the controller.

If i do a wget --http-user=USERNAME --http-password=PASSWORD http://IP/lcd i will get a gzipped html file in return, which when unzipped looks like ->

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BrewPi reporting for duty!</title>
<meta name="apple-mobile-web-app-title" content="BrewPiLite">
<meta name="apple-mobile-web-app-capable" content="yes">
<script type="text/javascript" src="bwf.js"></script>
</head>
<style>.lcddisplay{width:280px;height:90px;float:left;margin:5px;background:#000;background:-moz-linear-gradient(top,#000000 2%,#2b2b2b 11%,#212121 54%,#212121 92%,#000000 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(2%,#000000),color-stop(11%,#2b2b2b),color-stop(54%,#212121),color-stop(92%,#212121),color-stop(100%,#000000));background:-webkit-linear-gradient(top,#000000 2%,#2b2b2b 11%,#212121 54%,#212121 92%,#000000 100%);background:-o-linear-gradient(top,#000000 2%,#2b2b2b 11%,#212121 54%,#212121 92%,#000000 100%);background:-ms-linear-gradient(top,#000000 2%,#2b2b2b 11%,#212121 54%,#212121 92%,#000000 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#000000',endColorstr='#000000',GradientType=0);background:linear-gradient(top,#000000 2%,#2b2b2b 11%,#212121 54%,#212121 92%,#000000 100%);-webkit-box-shadow:inset 1px 1px 5px #333;-moz-box-shadow:inset 1px 1px 5px #333;box-shadow:inset 1px 1px 5px #333;border:2px solid #333;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.lcddisplay .lcd-text{float:left;margin:5px 16px}.lcd-line{float:left;clear:left;font-size:16px;font-weight:normal;font-style:normal;font-family:"Courier New",Courier,monospace;color:#ff0;white-space:pre}.dropdown{position:absolute;left:2px;top:2px;display:inline-block}.dropdown-content{display:none;position:absolute;background-color:#f9f9f9;min-width:160px;overflow:auto;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2)}.dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block;border:1px solid}.dropdown a:hover{background-color:#f1f1f1}.show{display:block}</style>
<script>/*<![CDATA[*/function setLcdText(a,b){var d=document.getElementById(a);d.innerHTML=b}function communicationError(){setLcdText("lcd-line-0","Failed to");setLcdText("lcd-line-1","connect to");setLcdText("lcd-line-2","Server");setLcdText("lcd-line-3","")}function controllerError(){setLcdText("lcd-line-0","Controller not");setLcdText("lcd-line-1","updating data");setLcdText("lcd-line-2","...");setLcdText("lcd-line-3","")}function init(){document.getElementById("lcd").onclick=function(){document.getElementById("myDropdown").classList.toggle("show");event.stopPropagation()};var b=true;BWF.init({onconnect:function(){BWF.send("l");setInterval(function(){if(!b)controllerError();BWF.send("l");b=false},5000)},error:function(e){console.log("error");communicationError()},handlers:{L:function(a){b=true;for(var i=0;i<4;i++)setLcdText("lcd-line-"+i,a[i])}}})}window.onclick=function(a){var b=document.getElementsByClassName("dropdown-content");var i;for(i=0;i<b.length;i++){var c=b[i];if(c.classList.contains('show')){c.classList.remove('show')}}}/*]]>*/</script>
<body onload=init()>
<div id="lcd" class="lcddisplay"><span class="lcd-text">
<span class="lcd-line" id="lcd-line-0">Live LCD waiting</span>
<span class="lcd-line" id="lcd-line-1">for update from</span>
<span class="lcd-line" id="lcd-line-2">script...</span>
<span class="lcd-line" id="lcd-line-3"></span></p><p>
</div>
<div class="dropdown">
<div id="myDropdown" class="dropdown-content">
<a href="/">Main Page</a>
<a href="/log">Data Log</a>
<a href="/setup.htm">Device Setup</a>
<a href="/config">System Config</a>
<a href="/gdc">Gravity Sensor</a>
</div>
</body>
</html>

It would be nice to be able to get that into homeassistant, tried using panel iframe, with no result (browser says: Only secure origins are allowed) which i guess is something that could be worked around somehow…

I would however prefer to have the lcd display in the ‘normal’ ui along other cards.

Is this possible?

I’ve had to do something similar to this before and I did it by creating a bash script and calling it every so often from Home Assistant. What’s nice is this also works if you are using Hassio. I don’t know how familiar you are with bash scripts but I threw one together and added some comments.

I’m sure there is another way that may be easier but you make do with the terminal commands you know and not the ones you don’t.

#!/usr/bin/env bash

# Homeassistant info to use the API
hass_pass="homeassistant password"
hass_url="homeassistant url"

# Get file however you normally do. 
wget http-user=USERNAME --http-password=PASSWORD http://IP/lcd

# Just using test.html.gz as a placeholder

# See if file exists, if so then unzip
[[ -f "$(pwd)/test.html.gz" ]] && gzip -d "$(pwd)/test.html.gz"

# See if unzipped file exists, if so not then exit, if it does exist then save to html variable
[[ ! -f "$(pwd)/test.html" ]] && exit || html=$(cat "$(pwd)/test.html")

# Array of id tags you would like to get the value of
sensors=("lcd-line-0" "lcd-line-1" "lcd-line-2" "lcd-line-3")

# Iterate over the array of sensors and send Home Assistant a post to create a sensor.lcd_._sensor with the value of that sensor, in this case it would be sensor.lcd_0_sensor to sensor.lcd_3_sensor
for each in "${!sensors[@]}"; do
# Since your html file has each sensor on a line of its own it finds the line and the sed strips all html formatting from it leaving only the value
  readout=$(cat test.html | grep "${sensors[$each]}" | sed -n '/^$/!{s/<[^>]*>//g;p;}')
# Take the value and using the Home Assistant RESTful API use curl to POST to information where you can then add it to any way you would a normal sensor
  curl -s -X POST -H "Content-Type: application/json" -H "x-ha-access: $hass_pass" -d '{"state":"'$readout'"}' "$hass_url/api/states/sensor.lcd_$readout_sensor" > /dev/null
done

Let me know if you have any questions.

1 Like

Aha!

I was unaware of the Rest API… With that I should be fine :slight_smile:

Thanks a bunch! I’ll be bashing away !

Andreas