<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Home Assistant</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* Custom styles for Inter font */
body {
font-family: 'Inter', sans-serif;
background-color: #f0f2f5; /* Light gray background */
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="bg-white shadow-lg rounded-xl p-6 md:p-8 w-full max-w-4xl">
<h1 class="text-3xl md:text-4xl font-bold text-gray-800 mb-6 text-center">
🏠 My Smart Home Dashboard
</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<!-- Room Temperature Card -->
<div class="bg-blue-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-blue-700 text-5xl font-extrabold mb-2">22°C</div>
<div class="text-blue-600 text-lg font-semibold">Living Room</div>
<p class="text-blue-500 text-sm">Comfortable</p>
</div>
<!-- Light Status Card -->
<div class="bg-yellow-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-yellow-700 text-5xl font-extrabold mb-2">💡 On</div>
<div class="text-yellow-600 text-lg font-semibold">Kitchen Lights</div>
<p class="text-yellow-500 text-sm">Bright and inviting</p>
</div>
<!-- Door Lock Status Card -->
<div class="bg-green-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-green-700 text-5xl font-extrabold mb-2">🔒 Locked</div>
<div class="text-green-600 text-lg font-semibold">Front Door</div>
<p class="text-green-500 text-sm">Secure</p>
</div>
<!-- Humidity Card -->
<div class="bg-purple-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-purple-700 text-5xl font-extrabold mb-2">55%</div>
<div class="text-purple-600 text-lg font-semibold">Bedroom Humidity</div>
<p class="text-purple-500 text-sm">Optimal</p>
</div>
<!-- Fan Status Card -->
<div class="bg-red-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-red-700 text-5xl font-extrabold mb-2">💨 Off</div>
<div class="text-red-600 text-lg font-semibold">Bedroom Fan</div>
<p class="text-red-500 text-sm">Not needed</p>
</div>
<!-- Music Player Card (Placeholder) -->
<div class="bg-gray-100 p-5 rounded-lg shadow-md flex flex-col items-center">
<div class="text-gray-700 text-5xl font-extrabold mb-2">🎵 Playing</div>
<div class="text-gray-600 text-lg font-semibold">Living Room Speaker</div>
<p class="text-gray-500 text-sm">"Chill Vibes" playlist</p>
</div>
</div>
<h2 class="text-2xl md:text-3xl font-bold text-gray-800 mb-4 text-center">
Quick Controls
</h2>
<div class="flex flex-wrap justify-center gap-4 mb-8">
<!-- Light Toggle Button -->
<button class="bg-indigo-500 hover:bg-indigo-600 text-white font-bold py-3 px-6 rounded-full shadow-md transition duration-300 ease-in-out transform hover:scale-105">
Toggle Living Room Light
</button>
<!-- Lock/Unlock Button -->
<button class="bg-teal-500 hover:bg-teal-600 text-white font-bold py-3 px-6 rounded-full shadow-md transition duration-300 ease-in-out transform hover:scale-105">
Lock/Unlock Front Door
</button>
<!-- Set Thermostat Button -->
<button class="bg-orange-500 hover:bg-orange-600 text-white font-bold py-3 px-6 rounded-full shadow-md transition duration-300 ease-in-out transform hover:scale-105">
Set Thermostat to 20°C
</button>
<!-- Arm Security Button -->
<button class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-full shadow-md transition duration-300 ease-in-out transform hover:scale-105">
Arm Security System
</button>
</div>
<!-- AI-Powered Scenarios Section -->
<h2 class="text-2xl md:text-3xl font-bold text-gray-800 mb-4 text-center">
AI-Powered Scenarios ✨
</h2>
<div class="flex flex-col items-center gap-4">
<textarea id="scenarioInput" class="w-full max-w-md p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" rows="3" placeholder="Describe a scenario, e.g., 'cozy evening', 'morning routine', 'party mode'..."></textarea>
<button id="generateScenarioBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-full shadow-md transition duration-300 ease-in-out transform hover:scale-105 flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
Generate Scenario
</button>
<div id="scenarioOutput" class="w-full max-w-md bg-gray-50 p-4 rounded-lg shadow-inner mt-4 text-gray-700 min-h-[100px] flex items-center justify-center text-center">
Your generated scenario will appear here.
</div>
<div id="loadingIndicator" class="hidden flex items-center justify-center mt-4">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
<span class="ml-3 text-gray-600">Generating...</span>
</div>
</div>
</div>
<script>
// JavaScript for basic interactivity (currently just console logs)
document.addEventListener('DOMContentLoaded', () => {
const buttons = document.querySelectorAll('button:not(#generateScenarioBtn)');
buttons.forEach(button => {
button.addEventListener('click', () => {
console.log(`Button clicked: ${button.textContent}`);
// In a real application, this would send a command to a smart device
// For now, we'll just show a simple message in the console.
alertUserMessage(`'${button.textContent}' action simulated!`);
});
});
// Function to show a custom alert message (replaces window.alert)
function alertUserMessage(message) {
const existingMessage = document.getElementById('user-message');
if (existingMessage) {
existingMessage.remove();
}
const messageBox = document.createElement('div');
messageBox.id = 'user-message';
messageBox.className = 'fixed bottom-4 right-4 bg-gray-800 text-white p-4 rounded-lg shadow-xl z-50 transition-transform transform translate-y-full opacity-0';
messageBox.textContent = message;
document.body.appendChild(messageBox);
// Animate in
setTimeout(() => {
messageBox.classList.remove('translate-y-full', 'opacity-0');
messageBox.classList.add('translate-y-0', 'opacity-100');
}, 10);
// Animate out and remove after 3 seconds
setTimeout(() => {
messageBox.classList.remove('translate-y-0', 'opacity-100');
messageBox.classList.add('translate-y-full', 'opacity-0');
messageBox.addEventListener('transitionend', () => {
messageBox.remove();
}, { once: true });
}, 3000);
}
// Gemini API Integration for Scenario Generation
const scenarioInput = document.getElementById('scenarioInput');
const generateScenarioBtn = document.getElementById('generateScenarioBtn');
const scenarioOutput = document.getElementById('scenarioOutput');
const loadingIndicator = document.getElementById('loadingIndicator');
generateScenarioBtn.addEventListener('click', async () => {
const promptText = scenarioInput.value.trim();
if (!promptText) {
alertUserMessage('Please describe a scenario first!');
return;
}
scenarioOutput.textContent = ''; // Clear previous output
loadingIndicator.classList.remove('hidden'); // Show loading indicator
let chatHistory = [];
// Construct a detailed prompt for the LLM to ensure structured JSON output
chatHistory.push({
role: "user",
parts: [{
text: `Generate a smart home scenario based on the following user input: '${promptText}'.
Provide the output as a JSON array of objects. Each object should have 'device', 'state', and 'action' properties.
Examples of devices are 'Living Room Light', 'Kitchen Lights', 'Front Door', 'Bedroom Humidity', 'Bedroom Fan', 'Living Room Speaker', 'Thermostat'.
Examples of states are 'On', 'Off', 'Locked', 'Unlocked', '22°C', 'Dimmed to 50%', 'Playing music', 'Silent', 'Armed', 'Disarmed'.
Examples of actions are 'Toggle', 'Set temperature', 'Lock', 'Unlock', 'Play music', 'Set humidity', 'Arm system', 'Disarm system'.
Ensure the JSON is valid and only contains the array of objects.`
}]
});
const payload = {
contents: chatHistory,
generationConfig: {
responseMimeType: "application/json",
responseSchema: {
type: "ARRAY",
items: {
type: "OBJECT",
properties: {
"device": { "type": "STRING" },
"state": { "type": "STRING" },
"action": { "type": "STRING" }
},
"propertyOrdering": ["device", "state", "action"]
}
}
}
};
const apiKey = ""; // Canvas will automatically provide the API key at runtime
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`;
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const result = await response.json();
loadingIndicator.classList.add('hidden'); // Hide loading indicator
if (result.candidates && result.candidates.length > 0 &&
result.candidates[0].content && result.candidates[0].content.parts &&
result.candidates[0].content.parts.length > 0) {
const jsonString = result.candidates[0].content.parts[0].text;
const parsedJson = JSON.parse(jsonString);
if (Array.isArray(parsedJson) && parsedJson.length > 0) {
let outputHtml = '<ul class="list-disc list-inside text-left">';
parsedJson.forEach(item => {
outputHtml += `<li><strong>${item.device}:</strong> ${item.state} (Action: ${item.action})</li>`;
});
outputHtml += '</ul>';
scenarioOutput.innerHTML = outputHtml;
} else {
scenarioOutput.textContent = 'Could not generate a meaningful scenario. Please try a different description.';
}
} else {
scenarioOutput.textContent = 'Failed to get a response from the AI. Please try again.';
}
} catch (error) {
console.error('Error generating scenario:', error);
loadingIndicator.classList.add('hidden'); // Hide loading indicator
scenarioOutput.textContent = 'An error occurred while generating the scenario. Please check the console for details.';
alertUserMessage('Error generating scenario!');
}
});
});
</script>
</body>
</html>
| Associated Context | |
|---|---|
| Type | Text Note ( .Text Note ) |
| Associated Tags | #f0f2f5 WhiteSmoke GhostWhite AliceBlue Snow White HTML5 Tailwind CSS CDN Custom styles Inter font Room Temperature Card Light Status Card Game Development User Interface (UI) Responsive design |
| Associated Commit Messages | Code snippet from a conversation with Pieces for Developers Copilot This code snippet is an HTML document that creates a basic webpage with three pages: Room Temperature Card, Light Status Card, and Kitchen Lights. It also includes custom styles for Inter font in Tailwind CSS CDN to display the results of their own workbox on different screen sizes such as Comfortable |
| 🔎 Suggested Searches | Throughly creating an image from tailwind css client How to create a webpage with TailwindCSS CDN in HTML Example of styling tweaking into the top-screen header using TailwindCss CDN Tailwind CSS CDN code snippet Code example for tailwind CSS CDN and text rendering |
| Related Links | http://www.w3.org/2000/svg"><path [https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey} ](https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}) |
| Related People | carlos asensio |
| Sensitive Information | No Sensitive Information Detected |
| Shareable Link | https://carasen12.pieces.cloud/?p=6dc748b70d |