Explore 10 real-world IoT products through an interactive interface. Search, filter, compare, and learn from successful products and failures. Click any product card to see detailed architecture diagrams, lessons learned, and comprehensive analysis.
Show code
d3 =require("d3@7")// Error handling: Load product data with validationrawData =FileAttachment("data/products/products-10-complete.json").json().catch(err => {console.error('Failed to load product data:', err);return { products: [],error:'Failed to load product data. Please refresh the page.' }; })// Data validation helpervalidateProduct = (product) => {if (!product ||typeof product !=='object') returnfalse;const required = ['id','name','category','summary','overview','hardware','connectivity'];return required.every(field => product[field]);}// Validated product data with error stateproductsData = {if (rawData.error) {return { products: [],error: rawData.error }; }if (!rawData.products||!Array.isArray(rawData.products)) {return { products: [],error:'Invalid data format' }; }const validProducts = rawData.products.filter(validateProduct);if (validProducts.length===0) {return { products: [],error:'No valid products found' }; }return { products: validProducts,error:null };}// XSS Protection: Sanitize text for safe HTML insertionsanitize = (str) => {if (typeof str !=='string') return'';return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');}// XSS Protection: Validate and sanitize product IDssafeId = (id) => {if (typeof id !=='string') return'';// Only allow alphanumeric characters and hyphensconst safe = id.replace(/[^a-zA-Z0-9-]/g,'');return safe.substring(0,100);}// Get valid product IDs for validationvalidProductIds =newSet(productsData.products.map(p => p.id))// State managementmutable selectedProductId =nullmutable panelOpen =falsemutable activeTab ="overview"mutable dataError = productsData.errormutable isLoading =false// Search inputviewof searchTerm = Inputs.text({placeholder:"🔍 Search products by name, category, or technology...",width:"100%"})// Category filterviewof selectedCategory = Inputs.select( ["All Categories","Proximity & Positioning","Wearables","Communication Devices","Smart Home","Maker Platforms","Environmental Monitoring","Healthcare"], {label:"Category Filter:",value:"All Categories" })// Filter products based on search and categoryfilteredProducts = {const searchLower = (searchTerm ||"").toLowerCase();return productsData.products.filter(p => {// Text searchif (searchTerm) {const matchesName = p.name.toLowerCase().includes(searchLower);const matchesCategory = p.category.toLowerCase().includes(searchLower);const matchesTags = p.tags.some(tag => tag.toLowerCase().includes(searchLower));const matchesSummary = p.summary.oneLine.toLowerCase().includes(searchLower);if (!(matchesName || matchesCategory || matchesTags || matchesSummary)) {returnfalse; } }// Category filterif (selectedCategory !=="All Categories"&& p.category!== selectedCategory) {returnfalse; }returntrue; });}// Define global functions for onclick handlers with validation (must be before HTML rendering)globalFunctionsSetup = {// Store valid IDs in window for validationwindow._validProductIds=newSet();window.selectProduct=function(productId) {// XSS Protection: Validate product ID formatif (!window.isValidProductId||!window.isValidProductId(productId)) {console.warn('Invalid product ID format:', productId);return; }// Validate against actual product listif (!window._validProductIds.has(productId)) {console.warn('Product ID not found:', productId);return; }window.dispatchEvent(newCustomEvent('selectProduct', { detail: productId })); };window.closePanel=function() {window.dispatchEvent(newCustomEvent('closePanel')); };window.setActiveTab=function(tab) {// XSS Protection: Validate tab IDconst validTabs = ['overview','architecture','security','privacy','business'];if (!validTabs.includes(tab)) {console.warn('Invalid tab:', tab);return; }window.dispatchEvent(newCustomEvent('setActiveTab', { detail: tab })); };returnnull;// Return null to prevent 'undefined' output}// Update valid product IDs in window for validationvalidIdsUpdate = { validProductIds.forEach(id =>window._validProductIds.add(id));returnnull;// Return null to prevent 'undefined' output}// Error display and product counterrorDisplayHtml = {if (dataError) {returnhtml` <div role="alert" style="margin: 2rem 0; padding: 1.5rem; background: #fee2e2; border: 2px solid #ef4444; border-radius: 8px; color: #991b1b;"> <strong>⚠️ Error:</strong> ${sanitize(dataError)} <button onclick="location.reload()" style="margin-left: 1rem; padding: 0.5rem 1rem; background: #ef4444; color: white; border: none; border-radius: 4px; cursor: pointer;"> Reload Page </button> </div> `; }returnhtml` <div aria-live="polite" style="margin: 1rem 0; color: #7F8C8D; font-size: 0.95rem;"> Showing <strong>${filteredProducts.length}</strong> of <strong>${productsData.products.length}</strong> products${filteredProducts.length===0&& searchTerm ?html`<br><em>No products match your search. Try different keywords.</em>`:''} </div> `;}html`${errorDisplayHtml}`
Show code
loadingStateHtml = {// Show loading state only if we're actually loading and have no data yet// In practice, data loads very quickly from FileAttachment, so this is mostly for UX polishif (isLoading && productsData.products.length===0) {returnhtml` <div class="loading-container" role="status" aria-live="polite" aria-label="Loading products"> <div class="loading-spinner"></div> <div class="loading-text">Loading IoT products...</div> </div> <div class="product-grid">${Array(6).fill(0).map(() =>html` <div class="skeleton skeleton-card" aria-hidden="true"></div> `)} </div> `; }returnhtml``;}html`${loadingStateHtml}`
Interactive Exploration: 1. Search: Try “BLE”, “GPS”, “cellular”, “battery”, “solar”, or “defunct” 2. Filter by Category: See products grouped by use case 3. Product Cards: Hover for lift animation, click for details 4. Detail Panel: Comprehensive overview + architecture diagrams 5. Architecture Diagrams: Mermaid diagrams showing complete system design
What You’ll Learn: - ✅ Technology Trade-offs: Battery life vs features, range vs power, simplicity vs flexibility - ✅ Design Patterns: BLE broadcast, cellular cloud-centric, V2H energy management - ✅ Success & Failure: Museum-recognized design (Good Night Lamp) vs vaporware (Angel Blocks) - ✅ Real Data: Actual battery life (3 years), range (70m), costs ($30-40/beacon) - ✅ Business Models: Hardware-only, subscription, platform, demonstration
12.5 🚀 Features & Roadmap
Available Now: - ✅ 5-Tab Analysis: Overview, Architecture, Security, Privacy, and Business analysis for each product - ✅ Interactive Search: Search by name, category, technology, or tags - ✅ Category Filtering: Filter by product category - ✅ Mermaid Diagrams: Interactive architecture diagrams with IEEE color scheme - ✅ Keyboard Navigation: Full accessibility with arrow keys, Enter, Escape - ✅ Mobile Responsive: Optimized for all screen sizes
Coming Soon: - 🔜 Comparison Mode: Select 2-4 products for side-by-side analysis - 🔜 Timeline View: See IoT product evolution from 2005-2025 - 🔜 Pattern Explorer: Automatically identify common design patterns - 🔜 Technology Stack View: Group products by primary connectivity - 🔜 Export Features: Download comparisons as CSV/PDF
Try the Explorer: 1. Search for “defunct” to see failed products and learn from their failures 2. Search for “cellular” to compare 3 different cellular IoT approaches 3. Filter by “Smart Home” to see 4 products in this category 4. Click any product → Security or Privacy tabs for detailed analysis 5. Click Business tab to see pricing, competitors, and real deployments
12.6 Summary
The IoT Product Explorer turns product case studies into a searchable, comparable dataset:
Real products, real constraints: Compare connectivity, power, and architecture decisions across 10 devices
Multi-lens analysis: Review each product through Architecture, Security, Privacy, and Business tabs
Learn from outcomes: Contrast successful products with legacy/defunct designs to spot failure patterns
Direct chapter integration: Jump from a product to its full written analysis for deeper study
12.7 Knowledge Check
NoteAuto-Gradable Quick Check
The primary purpose of the IoT Product Explorer is to:
This hub helps you explore real products and then connect architecture, networking, security, privacy, and business decisions back to the chapters.
Which set of tabs reflects the five-lens analysis available for each product?
Each product includes a structured view spanning technical architecture plus security, privacy, and business context.
If you open a product detail panel and want to close it quickly using the keyboard, you should press:
The app supports keyboard accessibility; Escape closes the detail panel.
The “Read Complete Analysis” button is intended to:
Use the explorer for discovery and comparison, then open the full chapter analysis when you want the complete narrative and deeper reasoning.
12.8 What’s Next
Pick one product and follow “Read Complete Analysis” to study the full case study chapter
Use the Knowledge Map to discover prerequisite chapters related to a product’s connectivity, sensing, and security choices