Here a post of a side project of mine. I’m working on my audio system. and i have a camera showing the current record playing. Because not always something is playing i have a blank screen.
I decided to make a random quote on it.
quote sensor
sensor:
- platform: rest
name: "Daily quote"
unique_id: "rest_001"
resource: https://zenquotes.io/api/random
value_template: '{{ value_json.q }}'
scan_interval: 3600
json_attributes:
- q
- a
php image generating code.
<?php
$homeAssistantUrl = 'http://192.168.1.1:8123'; // Replace with your Home Assistant URL
$token = '12345678';
$imageCacheFolder = 'image_cache';
function imagettfstroketext(&$image, $size, $angle, $x, $y, &$textcolor, &$strokecolor, $fontfile, $text, $px) {
for($c1 = ($x-abs($px)); $c1 <= ($x+abs($px)); $c1++)
for($c2 = ($y-abs($px)); $c2 <= ($y+abs($px)); $c2++)
$bg = imagettftext($image, $size, $angle, $c1, $c2, $strokecolor, $fontfile, $text);
return imagettftext($image, $size, $angle, $x, $y, $textcolor, $fontfile, $text);
}
function genTextToImage($imagePath, $text) {
$image = imagecreatefromjpeg($imagePath); // Assuming the image is in JPEG format
// Get the dimensions of the original image
$originalWidth = imagesx($image);
$originalHeight = imagesy($image);
// Calculate the maximum dimension (either width or height)
$maxDimension = max($originalWidth, $originalHeight);
// Create a new square canvas with the maximum dimension
$newImage = imagecreatetruecolor($maxDimension, $maxDimension);
// Fill the canvas with a black background
$blackColor = imagecolorallocate($newImage, 0, 0, 0);
imagefill($newImage, 0, 0, $blackColor);
// Calculate the position to paste the original image onto the canvas
$x = ($maxDimension - $originalWidth) / 2;
$y = ($maxDimension - $originalHeight) / 2;
// Paste the original image onto the canvas
imagecopy($newImage, $image, $x, $y, 0, 0, $originalWidth, $originalHeight);
$font = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'; // Replace with the path to a TrueType font file
$textColor = imagecolorallocate($image, 255, 255, 255); // White color
$stroke_color = imagecolorallocate($image, 0, 0, 0);
// Get the dimensions of the image
$imageWidth = imagesx($newImage);
$imageHeight = imagesy($newImage);
$fontSize = $imageWidth / 30;
// Calculate the position for the text (20% from the bottom)
$textHeight = count(explode("\n", $text)) * 20;
// Break the text into lines to fit the image width
$textLines = explode("\n", wordwrap($text, 35, "\n"));
$textY = $imageHeight - ((count($textLines)- 1) * $fontSize + ((count($textLines)-2) * $fontSize * 1.55));
#$textY = ($imageHeight * 0.20);
foreach ($textLines as $line) {
// imagettftext($newImage, $fontSize, 0, 10, $textY, $textColor, $font, $line);
imagettfstroketext($newImage,$fontSize,0, 10, $textY, $textColor,$stroke_color, $font, $line,2);
$textY += ($fontSize * 1.55) ; // Adjust the Y position for the next line
}
return $newImage;
}
// Fetch the quote from Home Assistant
$quoteUrl = $homeAssistantUrl . '/api/states/sensor.daily_quote';
$quoteHeader = array(
'Authorization: Bearer ' . $token,
);
$quoteResponse = file_get_contents($quoteUrl, false, stream_context_create(['http' => ['header' => $quoteHeader]]));
if ($quoteResponse) {
$quoteData = json_decode($quoteResponse, true);
$quote = $quoteData['attributes']['q'] . "\n- " . $quoteData['attributes']['a'];
$finalImagePath = $imageCacheFolder . '/final/' . preg_replace('/[\/:*?"<>| \n]/ ', '',$quote) . '.jpg';
if (!file_exists( $finalImagePath )) {
// Specify the Wikipedia API URL for Dutch Wikipedia
$url = 'https://en.wikipedia.org/w/api.php';
// Retrieve data from Wikipedia
$title = str_replace(' ', '_', $quoteData['attributes']['a']); // No lowercase conversion
if (!file_exists($imageCacheFolder)) {
mkdir($imageCacheFolder, 0755, true); // Create the image_cache folder if it doesn't exist
}
$outputImage = $imageCacheFolder . '/' . $title . '.jpg'; // Output image path
// Check if the image already exists in the cache
if (!file_exists($outputImage)) {
$searchUrl = 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&srsearch='.$title;
$searchOptions = array(
CURLOPT_URL => $searchUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('User-Agent:DaftBot/0.1 (Daft dutch quote generator)'),
);
$ch = curl_init();
curl_setopt_array($ch, $searchOptions);
$searchResponse = curl_exec($ch);
$searchData = json_decode($searchResponse, true);
if (isset($searchData['query']['search'][0]['title'])) {
$wikititle = $searchData['query']['search'][0]['title'];
} else {
$wikititle = false;
}
// If not, download the image using cURL
if ($wikititle ) {
$imageDownloadUrl = 'https://en.wikipedia.org/w/api.php?action=query&format=json&titles=' . str_replace(' ', '_',$wikititle ). '&prop=pageimages&piprop=original&pilicense=any';
} else {
$imageDownloadUrl = 'https://en.wikipedia.org/w/api.php?action=query&format=json&titles=' . $title . '&prop=pageimages&piprop=original&pilicense=any';
}
$imageDownloadOptions = array(
CURLOPT_URL => $imageDownloadUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('User-Agent:DaftBot/0.1 (Daft dutch quote generator)'),
);
$ch = curl_init();
curl_setopt_array($ch, $imageDownloadOptions);
$imageResponse = curl_exec($ch);
if ($imageResponse !== false) {
$imageData = json_decode($imageResponse, true);
$page_id = key($imageData['query']['pages']);
$page = $imageData['query']['pages'][$page_id];
if (isset($page['original'])) {
$image_url = $page['original']['source'];
#die( $image_url);
// Save the image to the cache
$chImage = curl_init();
$outputImageFile = fopen($outputImage, 'w');
curl_setopt($chImage, CURLOPT_URL, $image_url);
curl_setopt($chImage, CURLOPT_FILE, $outputImageFile);
curl_setopt($chImage, CURLOPT_HTTPHEADER, array('User-Agent:DaftBot/0.1 (Daft dutch quote generator)'));
curl_exec($chImage);
fclose($outputImageFile);
curl_close($chImage);
} else {
# die("no image1");
}
} else {
# die("no image2");
}
curl_close($ch);
}
// gen the image
if (!file_exists($outputImage)) {
$random = imagecreatefromjpeg('https://random.imagecdn.app/800/800');
imagejpeg($random,$outputImage);
}
$finalImage = genTextToImage($outputImage, $quote);
header('Content-Type: image/jpeg');
imagejpeg($finalImage,$finalImagePath);
imagejpeg($finalImage);
} else {
header('Content-Type: image/jpeg');
imagejpeg(imagecreatefromjpeg($finalImagePath));
}
}
?>
make the url dynamic on a changing url. that you can check the only update on url update checkbox.
- platform: template
sensors:
qoute_image:
friendly_name: "qoute image"
value_template: >
http://192.168.5.1/local/quote_image.jpg.php?foo={{ state_attr('sensor.daily_quote','a')|replace(' ','_') }}