# Code Examples Complete working examples demonstrating common patterns for building TelemetryOS applications with settings and render views. # Code Examples Complete working examples demonstrating common patterns. ## Weather Widget A complete weather application with settings and display. ### Project Structure ``` weather-widget/ ├── src/ │ ├── views/ │ │ ├── Settings.tsx │ │ └── Render.tsx │ ├── App.tsx │ └── index.tsx ├── telemetry.config.json └── package.json ``` ### Configuration **telemetry.config.json:** ```json { "name": "weather-widget", "version": "1.0.0", "displayName": "Weather Widget", "description": "Display weather forecasts for configured cities", "mountPoints": { "render": "/render", "settings": "/settings" }, "devServer": { "runCommand": "vite --port 3000", "url": "http://localhost:3000" } } ``` ### Settings View **src/views/Settings.tsx:** ```typescript import { useEffect, useState } from 'react'; import { configure, store } from '@telemetryos/sdk'; configure('weather-widget'); interface WeatherConfig { city: string; units: 'F' | 'C'; refreshInterval: number; } export function Settings() { const [config, setConfig] = useState({ city: '', units: 'F', refreshInterval: 300000 // 5 minutes }); const [saving, setSaving] = useState(false); useEffect(() => { // Load existing configuration store().instance.get('config').then(saved => { if (saved) setConfig(saved); }); }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setSaving(true); try { await store().instance.set('config', config); alert('Settings saved successfully!'); } catch (error) { alert('Failed to save settings'); console.error(error); } finally { setSaving(false); } }; return (

Weather Settings

setConfig({ ...config, city: e.target.value })} placeholder="Enter city name" required />
setConfig({ ...config, refreshInterval: parseInt(e.target.value) * 1000 })} min={60} />
); } ``` ### Render View **src/views/Render.tsx:** ```typescript import { useEffect, useState } from 'react'; import { configure, store, proxy } from '@telemetryos/sdk'; configure('weather-widget'); interface WeatherConfig { city: string; units: 'F' | 'C'; refreshInterval: number; } interface WeatherData { temp: number; condition: string; humidity: number; windSpeed: number; } export function Render() { const [config, setConfig] = useState(null); const [weather, setWeather] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { // Subscribe to configuration changes const handler = (newConfig: WeatherConfig) => { setConfig(newConfig); if (newConfig?.city) { fetchWeather(newConfig); } }; store().instance.subscribe('config', handler); // Load initial configuration store().instance.get('config').then(saved => { setLoading(false); if (saved) { setConfig(saved); fetchWeather(saved); } }); return () => { store().instance.unsubscribe('config', handler); }; }, []); useEffect(() => { if (!config) return; const interval = setInterval(() => { fetchWeather(config); }, config.refreshInterval); return () => clearInterval(interval); }, [config]); const fetchWeather = async (cfg: WeatherConfig) => { try { setError(null); const apiKey = 'your-api-key'; const units = cfg.units === 'F' ? 'imperial' : 'metric'; const url = `https://api.openweathermap.org/data/2.5/weather?q=${cfg.city}&units=${units}&appid=${apiKey}`; const response = await proxy().fetch(url); if (!response.ok) { throw new Error('Weather fetch failed'); } const data = await response.json(); setWeather({ temp: Math.round(data.main.temp), condition: data.weather[0].main, humidity: data.main.humidity, windSpeed: Math.round(data.wind.speed) }); } catch (err) { setError('Failed to fetch weather data'); console.error(err); } }; if (loading) { return
Loading...
; } if (!config || !config.city) { return (

Please configure a city in settings

); } if (error) { return (

{error}

); } if (!weather) { return
Fetching weather...
; } return (

{config.city}

{weather.temp}°{config.units}
{weather.condition}
Humidity: {weather.humidity}%
Wind: {weather.windSpeed} {config.units === 'F' ? 'mph' : 'km/h'}
); } ``` ## Media Gallery Display images from TelemetryOS media library. ```typescript import { useEffect, useState } from 'react'; import { configure, media, store } from '@telemetryos/sdk'; import type { MediaContent } from '@telemetryos/sdk'; configure('media-gallery'); export function MediaGallery() { const [images, setImages] = useState([]); const [currentIndex, setCurrentIndex] = useState(0); const [duration, setDuration] = useState(5000); useEffect(() => { // Load configuration store().instance.get<{ tag: string; duration: number }>('config').then(config => { if (config) { setDuration(config.duration); loadMedia(config.tag); } }); }, []); useEffect(() => { if (images.length === 0) return; const timer = setInterval(() => { setCurrentIndex((prev) => (prev + 1) % images.length); }, duration); return () => clearInterval(timer); }, [images, duration]); const loadMedia = async (tag: string) => { try { const items = await media().getAllByTag(tag); const imageItems = items.filter(item => item.contentType.startsWith('image/') ); setImages(imageItems); } catch (error) { console.error('Failed to load media:', error); } }; if (images.length === 0) { return
No images found
; } const current = images[currentIndex]; return (
{current.name}
{current.name}
); } ``` ## Interactive Dashboard Dashboard that embeds multiple widgets. ```typescript import { useEffect, useState } from 'react'; import { configure, applications } from '@telemetryos/sdk'; import type { Application } from '@telemetryos/sdk'; configure('dashboard-app'); export function Dashboard() { const [widgets, setWidgets] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { loadWidgets(); }, []); const loadWidgets = async () => { try { // Find all dashboard widgets const apps = await applications().getAllByMountPoint('dashboard-widget'); // Prepare dependencies const widgetNames = apps.map(w => w.name); const deps = await applications().setDependencies(widgetNames); // Only use ready widgets const readyWidgets = apps.filter(w => deps.ready.includes(w.name)); setWidgets(readyWidgets); } catch (error) { console.error('Failed to load widgets:', error); } finally { setLoading(false); } }; if (loading) { return
Loading dashboard...
; } if (widgets.length === 0) { return
No widgets available
; } return (
{widgets.map(widget => (