Skip to main content
Glama
index.html9.94 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>IoT Light Bulb Simulator</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; text-align: center; background-color: #f5f5f5; } .container { background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } h1 { color: #333; } .light-bulb { width: 100px; height: 150px; margin: 30px auto; position: relative; } .bulb { width: 80px; height: 80px; background-color: #eee; border-radius: 50%; margin: 0 auto; position: relative; transition: all 0.3s ease; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } .bulb.on { box-shadow: 0 0 30px; } .base { width: 30px; height: 20px; background-color: #555; margin: 0 auto; border-radius: 3px; } .controls { margin-top: 40px; display: flex; flex-direction: column; align-items: center; gap: 20px; } .toggle-btn { background-color: #4CAF50; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } .toggle-btn:hover { background-color: #45a049; } .slider-container { width: 100%; max-width: 300px; } .slider { width: 100%; height: 25px; background: #d3d3d3; outline: none; -webkit-appearance: none; border-radius: 10px; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 25px; height: 25px; background: #4CAF50; cursor: pointer; border-radius: 50%; } .slider::-moz-range-thumb { width: 25px; height: 25px; background: #4CAF50; cursor: pointer; border-radius: 50%; } .color-picker { margin-top: 10px; } .status { margin-top: 20px; padding: 10px; background-color: #f0f0f0; border-radius: 4px; font-family: monospace; text-align: left; max-height: 200px; overflow-y: auto; } .mqtt-info { margin-top: 20px; background-color: #e8f4f8; padding: 10px; border-radius: 4px; font-size: 0.9em; text-align: left; } </style> </head> <body> <div class="container"> <h1>IoT Light Bulb Simulator</h1> <p>Device ID: <strong id="device-id">{{ device_state.device_id }}</strong></p> <div class="light-bulb"> <div id="bulb" class="bulb {% if device_state.properties.power %}on{% endif %}" style="background-color: {% if device_state.properties.power %}{{ device_state.properties.color }}{% else %}#eee{% endif %}; opacity: {% if device_state.properties.power %}{{ device_state.properties.brightness/100 }}{% else %}1{% endif %};"> </div> <div class="base"></div> </div> <div class="controls"> <button id="toggle-btn" class="toggle-btn"> {% if device_state.properties.power %}Turn Off{% else %}Turn On{% endif %} </button> <div class="slider-container"> <label for="brightness">Brightness: <span id="brightness-value">{{ device_state.properties.brightness }}</span>%</label> <input type="range" min="1" max="100" value="{{ device_state.properties.brightness }}" class="slider" id="brightness"> </div> <div class="color-picker"> <label for="color">Color:</label> <input type="color" id="color" value="{{ device_state.properties.color }}"> </div> </div> <div class="status"> <h3>Device State:</h3> <pre id="state-display">{{ device_state | tojson(indent=2) }}</pre> </div> <div class="mqtt-info"> <h3>MQTT Information:</h3> <p><strong>Broker:</strong> {{ device_state.mqtt_broker if device_state.mqtt_broker else 'localhost' }}:{{ device_state.mqtt_port if device_state.mqtt_port else '1883' }}</p> <p><strong>Command Topic:</strong> devices/{{ device_state.device_id }}/command</p> <p><strong>State Topic:</strong> devices/{{ device_state.device_id }}/state</p> <p><strong>State Request Topic:</strong> devices/{{ device_state.device_id }}/state/request</p> </div> </div> <script> // Elements const bulb = document.getElementById('bulb'); const toggleBtn = document.getElementById('toggle-btn'); const brightnessSlider = document.getElementById('brightness'); const brightnessValue = document.getElementById('brightness-value'); const colorPicker = document.getElementById('color'); const stateDisplay = document.getElementById('state-display'); // Current state let deviceState = {{ device_state | tojson }}; // Update UI based on state function updateUI() { // Update bulb appearance if (deviceState.properties.power) { bulb.classList.add('on'); bulb.style.backgroundColor = deviceState.properties.color; bulb.style.opacity = deviceState.properties.brightness / 100; toggleBtn.textContent = 'Turn Off'; } else { bulb.classList.remove('on'); bulb.style.backgroundColor = '#eee'; bulb.style.opacity = 1; toggleBtn.textContent = 'Turn On'; } // Update controls brightnessSlider.value = deviceState.properties.brightness; brightnessValue.textContent = deviceState.properties.brightness; colorPicker.value = deviceState.properties.color; // Update state display stateDisplay.textContent = JSON.stringify(deviceState, null, 2); } // Toggle light toggleBtn.addEventListener('click', async () => { try { const response = await fetch('/api/toggle', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const data = await response.json(); if (data.success) { deviceState.properties.power = data.power; updateUI(); } } catch (error) { console.error('Error toggling light:', error); } }); // Set brightness brightnessSlider.addEventListener('input', () => { brightnessValue.textContent = brightnessSlider.value; if (deviceState.properties.power) { bulb.style.opacity = brightnessSlider.value / 100; } }); brightnessSlider.addEventListener('change', async () => { try { const response = await fetch('/api/brightness', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ brightness: parseInt(brightnessSlider.value) }) }); const data = await response.json(); if (data.success) { deviceState.properties.brightness = data.brightness; updateUI(); } } catch (error) { console.error('Error setting brightness:', error); } }); // Set color colorPicker.addEventListener('change', async () => { try { const response = await fetch('/api/color', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ color: colorPicker.value }) }); const data = await response.json(); if (data.success) { deviceState.properties.color = data.color; updateUI(); } } catch (error) { console.error('Error setting color:', error); } }); // Periodically refresh state from server setInterval(async () => { try { const response = await fetch('/api/state'); const data = await response.json(); deviceState = data; updateUI(); } catch (error) { console.error('Error fetching state:', error); } }, 2000); </script> </body> </html>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jordy33/iot_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server