137 IoT Use Case Builder
Design Complete IoT Solutions
137.1 Interactive Use Case Builder
This interactive tool helps you design IoT solutions by selecting components based on your chosen industry domain. Build your architecture, view component relationships, and generate requirements automatically.
NoteHow to Use This Tool
- Select a domain from the dropdown to see domain-specific components
- Choose sensors and actuators using the checkboxes
- Select connectivity and cloud options for your deployment
- View the architecture diagram that updates in real-time
- Review auto-generated requirements for power, bandwidth, latency, and security
- Check the cost estimate based on your selections
- Export your design as a text summary
Show code
{
// ============================================
// IoT Use Case Builder
// Interactive Design Tool
// ============================================
const d3 = await require("d3@7");
// IEEE Color palette
const colors = {
navy: "#2C3E50",
teal: "#16A085",
orange: "#E67E22",
gray: "#7F8C8D",
lightGray: "#ECF0F1",
white: "#FFFFFF",
green: "#27AE60",
red: "#E74C3C",
darkGray: "#34495E",
purple: "#8E44AD",
blue: "#3498DB"
};
// Domain configurations with components
const domains = {
"Smart Home": {
icon: "🏠",
color: colors.teal,
sensors: [
{ id: "temp", name: "Temperature Sensor", cost: 15, power: 0.5, bandwidth: 0.1 },
{ id: "humidity", name: "Humidity Sensor", cost: 12, power: 0.3, bandwidth: 0.1 },
{ id: "motion", name: "Motion Detector", cost: 25, power: 1.0, bandwidth: 0.5 },
{ id: "door", name: "Door/Window Sensor", cost: 18, power: 0.2, bandwidth: 0.2 },
{ id: "camera", name: "Smart Camera", cost: 120, power: 5.0, bandwidth: 50 },
{ id: "smoke", name: "Smoke Detector", cost: 35, power: 0.5, bandwidth: 0.3 }
],
actuators: [
{ id: "light", name: "Smart Light", cost: 25, power: 8.0 },
{ id: "thermostat", name: "Smart Thermostat", cost: 150, power: 2.0 },
{ id: "lock", name: "Smart Lock", cost: 180, power: 1.5 },
{ id: "blinds", name: "Motorized Blinds", cost: 200, power: 15.0 }
],
connectivity: ["Wi-Fi", "Zigbee", "Z-Wave", "Bluetooth"],
cloudServices: ["AWS IoT", "Google Cloud IoT", "Home Assistant"],
securityLevel: "Medium",
latencyReq: "100-500ms"
},
"Healthcare": {
icon: "🏥",
color: colors.red,
sensors: [
{ id: "heartrate", name: "Heart Rate Monitor", cost: 45, power: 2.0, bandwidth: 1.0 },
{ id: "bp", name: "Blood Pressure Sensor", cost: 65, power: 3.0, bandwidth: 0.5 },
{ id: "spo2", name: "SpO2 Sensor", cost: 35, power: 1.5, bandwidth: 0.3 },
{ id: "glucose", name: "Glucose Monitor", cost: 80, power: 2.0, bandwidth: 0.5 },
{ id: "ecg", name: "ECG Sensor", cost: 150, power: 5.0, bandwidth: 10 },
{ id: "fall", name: "Fall Detection", cost: 55, power: 2.5, bandwidth: 1.0 }
],
actuators: [
{ id: "alert", name: "Alert System", cost: 30, power: 1.0 },
{ id: "pump", name: "Medication Pump", cost: 500, power: 10.0 },
{ id: "bed", name: "Smart Bed Actuator", cost: 350, power: 20.0 },
{ id: "call", name: "Nurse Call Button", cost: 45, power: 0.5 }
],
connectivity: ["Bluetooth LE", "Wi-Fi", "LTE-M", "NB-IoT"],
cloudServices: ["AWS HealthLake", "Azure Health Data", "Google Health API"],
securityLevel: "Critical",
latencyReq: "10-50ms"
},
"Agriculture": {
icon: "🌾",
color: colors.green,
sensors: [
{ id: "soil", name: "Soil Moisture Sensor", cost: 20, power: 0.3, bandwidth: 0.1 },
{ id: "weather", name: "Weather Station", cost: 150, power: 3.0, bandwidth: 2.0 },
{ id: "ndvi", name: "NDVI Camera", cost: 400, power: 8.0, bandwidth: 20 },
{ id: "ph", name: "Soil pH Sensor", cost: 45, power: 0.5, bandwidth: 0.1 },
{ id: "livestock", name: "Livestock Tracker", cost: 80, power: 2.0, bandwidth: 1.0 },
{ id: "pest", name: "Pest Detection", cost: 120, power: 3.0, bandwidth: 5.0 }
],
actuators: [
{ id: "irrigation", name: "Irrigation Valve", cost: 75, power: 5.0 },
{ id: "fertigation", name: "Fertigation System", cost: 250, power: 8.0 },
{ id: "greenhouse", name: "Greenhouse Control", cost: 180, power: 15.0 },
{ id: "drone", name: "Sprayer Drone", cost: 2000, power: 500.0 }
],
connectivity: ["LoRaWAN", "NB-IoT", "Sigfox", "Satellite"],
cloudServices: ["AWS IoT Greengrass", "Azure FarmBeats", "IBM Watson Agriculture"],
securityLevel: "Low",
latencyReq: "1-60 seconds"
},
"Industrial": {
icon: "🏭",
color: colors.orange,
sensors: [
{ id: "vibration", name: "Vibration Sensor", cost: 85, power: 2.0, bandwidth: 5.0 },
{ id: "thermal", name: "Thermal Camera", cost: 500, power: 10.0, bandwidth: 30 },
{ id: "pressure", name: "Pressure Sensor", cost: 60, power: 1.0, bandwidth: 0.5 },
{ id: "flow", name: "Flow Meter", cost: 120, power: 2.0, bandwidth: 1.0 },
{ id: "current", name: "Current Sensor", cost: 45, power: 1.0, bandwidth: 0.5 },
{ id: "gas", name: "Gas Detector", cost: 150, power: 3.0, bandwidth: 1.0 }
],
actuators: [
{ id: "valve", name: "Industrial Valve", cost: 200, power: 20.0 },
{ id: "motor", name: "Motor Controller", cost: 350, power: 50.0 },
{ id: "conveyor", name: "Conveyor Control", cost: 500, power: 100.0 },
{ id: "robot", name: "Robot Controller", cost: 1500, power: 200.0 }
],
connectivity: ["Industrial Ethernet", "5G", "Wi-Fi 6", "TSN"],
cloudServices: ["AWS IoT SiteWise", "Azure IoT Hub", "Siemens MindSphere"],
securityLevel: "High",
latencyReq: "1-10ms"
},
"Smart City": {
icon: "🏙️",
color: colors.purple,
sensors: [
{ id: "traffic", name: "Traffic Camera", cost: 800, power: 15.0, bandwidth: 100 },
{ id: "parking", name: "Parking Sensor", cost: 45, power: 0.5, bandwidth: 0.2 },
{ id: "air", name: "Air Quality Sensor", cost: 200, power: 2.0, bandwidth: 1.0 },
{ id: "noise", name: "Noise Level Sensor", cost: 80, power: 1.0, bandwidth: 0.5 },
{ id: "waste", name: "Waste Bin Sensor", cost: 50, power: 0.5, bandwidth: 0.2 },
{ id: "flood", name: "Flood Sensor", cost: 65, power: 0.5, bandwidth: 0.3 }
],
actuators: [
{ id: "streetlight", name: "Smart Street Light", cost: 150, power: 50.0 },
{ id: "signal", name: "Traffic Signal", cost: 500, power: 30.0 },
{ id: "gate", name: "Parking Gate", cost: 250, power: 20.0 },
{ id: "display", name: "Info Display", cost: 800, power: 100.0 }
],
connectivity: ["LoRaWAN", "NB-IoT", "5G", "Fiber"],
cloudServices: ["AWS IoT Core", "Azure Digital Twins", "Google Cloud IoT"],
securityLevel: "High",
latencyReq: "50-200ms"
},
"Retail": {
icon: "🛒",
color: colors.blue,
sensors: [
{ id: "beacon", name: "BLE Beacon", cost: 25, power: 0.1, bandwidth: 0.1 },
{ id: "rfid", name: "RFID Reader", cost: 500, power: 5.0, bandwidth: 2.0 },
{ id: "footfall", name: "Footfall Counter", cost: 150, power: 3.0, bandwidth: 1.0 },
{ id: "shelf", name: "Smart Shelf Sensor", cost: 80, power: 1.0, bandwidth: 0.5 },
{ id: "checkout", name: "Smart Checkout Camera", cost: 400, power: 8.0, bandwidth: 50 },
{ id: "fridge", name: "Refrigeration Sensor", cost: 60, power: 1.0, bandwidth: 0.3 }
],
actuators: [
{ id: "display", name: "Digital Signage", cost: 300, power: 80.0 },
{ id: "ess", name: "Electronic Shelf Label", cost: 15, power: 0.01 },
{ id: "kiosk", name: "Self-Service Kiosk", cost: 1500, power: 150.0 },
{ id: "security", name: "Security Gate", cost: 600, power: 25.0 }
],
connectivity: ["Wi-Fi", "Bluetooth", "LoRaWAN", "5G"],
cloudServices: ["AWS Retail", "Azure Retail", "Google Cloud Retail"],
securityLevel: "Medium",
latencyReq: "50-100ms"
},
"Logistics": {
icon: "📦",
color: colors.darkGray,
sensors: [
{ id: "gps", name: "GPS Tracker", cost: 80, power: 3.0, bandwidth: 1.0 },
{ id: "shock", name: "Shock/Tilt Sensor", cost: 35, power: 0.5, bandwidth: 0.2 },
{ id: "temp", name: "Temperature Logger", cost: 40, power: 0.5, bandwidth: 0.2 },
{ id: "humidity", name: "Humidity Logger", cost: 35, power: 0.3, bandwidth: 0.1 },
{ id: "tamper", name: "Tamper Sensor", cost: 45, power: 0.5, bandwidth: 0.3 },
{ id: "weight", name: "Load Cell", cost: 120, power: 2.0, bandwidth: 0.5 }
],
actuators: [
{ id: "lock", name: "Smart Container Lock", cost: 200, power: 2.0 },
{ id: "dock", name: "Dock Door Control", cost: 350, power: 30.0 },
{ id: "agv", name: "AGV Controller", cost: 800, power: 100.0 },
{ id: "sorter", name: "Package Sorter", cost: 2000, power: 200.0 }
],
connectivity: ["LTE-M", "NB-IoT", "Satellite", "Wi-Fi"],
cloudServices: ["AWS IoT Fleet", "Azure IoT", "SAP Leonardo"],
securityLevel: "High",
latencyReq: "100ms-5s"
}
};
// State management
let selectedDomain = "Smart Home";
let selectedSensors = new Set();
let selectedActuators = new Set();
let selectedConnectivity = "";
let selectedCloud = "";
// Create main container
const container = d3.create("div")
.style("font-family", "system-ui, -apple-system, sans-serif")
.style("max-width", "1000px")
.style("margin", "0 auto");
// Header
const header = container.append("div")
.style("text-align", "center")
.style("margin-bottom", "20px");
header.append("div")
.style("font-size", "24px")
.style("font-weight", "bold")
.style("color", colors.navy)
.text("IoT Use Case Builder");
header.append("div")
.style("font-size", "14px")
.style("color", colors.gray)
.style("margin-top", "5px")
.text("Design your IoT solution by selecting components for your industry");
// Domain selector
const domainSection = container.append("div")
.style("margin-bottom", "20px")
.style("padding", "15px")
.style("background", colors.lightGray)
.style("border-radius", "12px");
domainSection.append("label")
.style("font-weight", "bold")
.style("color", colors.navy)
.style("margin-right", "15px")
.text("Select Domain:");
const domainSelect = domainSection.append("select")
.style("padding", "10px 20px")
.style("font-size", "16px")
.style("border-radius", "8px")
.style("border", `2px solid ${colors.navy}`)
.style("cursor", "pointer")
.on("change", function() {
selectedDomain = this.value;
selectedSensors.clear();
selectedActuators.clear();
selectedConnectivity = "";
selectedCloud = "";
updateUI();
});
Object.keys(domains).forEach(domain => {
domainSelect.append("option")
.attr("value", domain)
.text(`${domains[domain].icon} ${domain}`);
});
// Main content grid
const mainGrid = container.append("div")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "20px");
// Left column - Component selection
const leftColumn = mainGrid.append("div");
// Sensors section
const sensorsSection = leftColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.teal}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
sensorsSection.append("div")
.style("font-weight", "bold")
.style("color", colors.teal)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("📡 Sensors");
const sensorsGrid = sensorsSection.append("div")
.attr("id", "sensors-grid")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "8px");
// Actuators section
const actuatorsSection = leftColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.orange}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
actuatorsSection.append("div")
.style("font-weight", "bold")
.style("color", colors.orange)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("⚡ Actuators");
const actuatorsGrid = actuatorsSection.append("div")
.attr("id", "actuators-grid")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "8px");
// Connectivity section
const connectivitySection = leftColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.navy}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
connectivitySection.append("div")
.style("font-weight", "bold")
.style("color", colors.navy)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("📶 Connectivity");
const connectivityGrid = connectivitySection.append("div")
.attr("id", "connectivity-grid")
.style("display", "flex")
.style("flex-wrap", "wrap")
.style("gap", "8px");
// Cloud section
const cloudSection = leftColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.purple}`)
.style("border-radius", "12px")
.style("padding", "15px");
cloudSection.append("div")
.style("font-weight", "bold")
.style("color", colors.purple)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("☁️ Cloud Services");
const cloudGrid = cloudSection.append("div")
.attr("id", "cloud-grid")
.style("display", "flex")
.style("flex-wrap", "wrap")
.style("gap", "8px");
// Right column - Architecture and outputs
const rightColumn = mainGrid.append("div");
// Architecture diagram
const archSection = rightColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.navy}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
archSection.append("div")
.style("font-weight", "bold")
.style("color", colors.navy)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("🏗️ Architecture Diagram");
const archSvgContainer = archSection.append("div")
.attr("id", "arch-diagram");
// Requirements section
const reqSection = rightColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.green}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
reqSection.append("div")
.style("font-weight", "bold")
.style("color", colors.green)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("📋 Auto-Generated Requirements");
const reqContent = reqSection.append("div")
.attr("id", "requirements-content");
// Cost estimate section
const costSection = rightColumn.append("div")
.style("background", colors.white)
.style("border", `2px solid ${colors.orange}`)
.style("border-radius", "12px")
.style("padding", "15px")
.style("margin-bottom", "15px");
costSection.append("div")
.style("font-weight", "bold")
.style("color", colors.orange)
.style("margin-bottom", "10px")
.style("font-size", "16px")
.text("💰 Cost Estimate");
const costContent = costSection.append("div")
.attr("id", "cost-content");
// Export button
const exportSection = rightColumn.append("div")
.style("text-align", "center");
const exportBtn = exportSection.append("button")
.style("padding", "12px 30px")
.style("font-size", "16px")
.style("font-weight", "bold")
.style("background", colors.navy)
.style("color", colors.white)
.style("border", "none")
.style("border-radius", "8px")
.style("cursor", "pointer")
.text("📥 Export Summary")
.on("click", exportSummary)
.on("mouseenter", function() {
d3.select(this).style("background", colors.teal);
})
.on("mouseleave", function() {
d3.select(this).style("background", colors.navy);
});
// Export output area
const exportArea = exportSection.append("textarea")
.attr("id", "export-area")
.style("display", "none")
.style("width", "100%")
.style("height", "200px")
.style("margin-top", "15px")
.style("padding", "10px")
.style("font-family", "monospace")
.style("font-size", "12px")
.style("border", `2px solid ${colors.lightGray}`)
.style("border-radius", "8px")
.style("resize", "vertical");
// Update UI function
function updateUI() {
const domain = domains[selectedDomain];
// Update sensors grid
const sensorsGridEl = container.select("#sensors-grid");
sensorsGridEl.html("");
domain.sensors.forEach(sensor => {
const label = sensorsGridEl.append("label")
.style("display", "flex")
.style("align-items", "center")
.style("gap", "8px")
.style("padding", "8px")
.style("background", selectedSensors.has(sensor.id) ? `${colors.teal}22` : colors.lightGray)
.style("border-radius", "6px")
.style("cursor", "pointer")
.style("font-size", "12px")
.style("border", selectedSensors.has(sensor.id) ? `2px solid ${colors.teal}` : "2px solid transparent")
.on("mouseenter", function() {
d3.select(this).style("background", `${colors.teal}33`);
})
.on("mouseleave", function() {
d3.select(this).style("background", selectedSensors.has(sensor.id) ? `${colors.teal}22` : colors.lightGray);
});
label.append("input")
.attr("type", "checkbox")
.property("checked", selectedSensors.has(sensor.id))
.on("change", function() {
if (this.checked) {
selectedSensors.add(sensor.id);
} else {
selectedSensors.delete(sensor.id);
}
updateUI();
});
label.append("span")
.text(sensor.name);
});
// Update actuators grid
const actuatorsGridEl = container.select("#actuators-grid");
actuatorsGridEl.html("");
domain.actuators.forEach(actuator => {
const label = actuatorsGridEl.append("label")
.style("display", "flex")
.style("align-items", "center")
.style("gap", "8px")
.style("padding", "8px")
.style("background", selectedActuators.has(actuator.id) ? `${colors.orange}22` : colors.lightGray)
.style("border-radius", "6px")
.style("cursor", "pointer")
.style("font-size", "12px")
.style("border", selectedActuators.has(actuator.id) ? `2px solid ${colors.orange}` : "2px solid transparent")
.on("mouseenter", function() {
d3.select(this).style("background", `${colors.orange}33`);
})
.on("mouseleave", function() {
d3.select(this).style("background", selectedActuators.has(actuator.id) ? `${colors.orange}22` : colors.lightGray);
});
label.append("input")
.attr("type", "checkbox")
.property("checked", selectedActuators.has(actuator.id))
.on("change", function() {
if (this.checked) {
selectedActuators.add(actuator.id);
} else {
selectedActuators.delete(actuator.id);
}
updateUI();
});
label.append("span")
.text(actuator.name);
});
// Update connectivity options
const connectivityGridEl = container.select("#connectivity-grid");
connectivityGridEl.html("");
domain.connectivity.forEach(conn => {
connectivityGridEl.append("button")
.style("padding", "8px 15px")
.style("font-size", "12px")
.style("background", selectedConnectivity === conn ? colors.navy : colors.lightGray)
.style("color", selectedConnectivity === conn ? colors.white : colors.navy)
.style("border", `2px solid ${colors.navy}`)
.style("border-radius", "20px")
.style("cursor", "pointer")
.text(conn)
.on("click", function() {
selectedConnectivity = conn;
updateUI();
});
});
// Update cloud options
const cloudGridEl = container.select("#cloud-grid");
cloudGridEl.html("");
domain.cloudServices.forEach(cloud => {
cloudGridEl.append("button")
.style("padding", "8px 15px")
.style("font-size", "12px")
.style("background", selectedCloud === cloud ? colors.purple : colors.lightGray)
.style("color", selectedCloud === cloud ? colors.white : colors.purple)
.style("border", `2px solid ${colors.purple}`)
.style("border-radius", "20px")
.style("cursor", "pointer")
.text(cloud)
.on("click", function() {
selectedCloud = cloud;
updateUI();
});
});
// Update architecture diagram
updateArchitectureDiagram();
// Update requirements
updateRequirements();
// Update cost estimate
updateCostEstimate();
}
// Architecture diagram
function updateArchitectureDiagram() {
const domain = domains[selectedDomain];
const archContainer = container.select("#arch-diagram");
archContainer.html("");
const svgWidth = 400;
const svgHeight = 300;
const svg = archContainer.append("svg")
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`)
.attr("width", "100%")
.style("background", `linear-gradient(180deg, ${colors.lightGray}44 0%, ${colors.white} 100%)`)
.style("border-radius", "8px");
// Cloud layer
if (selectedCloud) {
svg.append("ellipse")
.attr("cx", svgWidth / 2)
.attr("cy", 45)
.attr("rx", 70)
.attr("ry", 30)
.attr("fill", `${colors.purple}33`)
.attr("stroke", colors.purple)
.attr("stroke-width", 2);
svg.append("text")
.attr("x", svgWidth / 2)
.attr("y", 48)
.attr("text-anchor", "middle")
.attr("font-size", "11px")
.attr("font-weight", "bold")
.attr("fill", colors.purple)
.text(selectedCloud.split(" ")[0]);
}
// Connectivity layer
if (selectedConnectivity) {
svg.append("rect")
.attr("x", svgWidth / 2 - 50)
.attr("y", 100)
.attr("width", 100)
.attr("height", 35)
.attr("rx", 6)
.attr("fill", `${colors.navy}22`)
.attr("stroke", colors.navy)
.attr("stroke-width", 2);
svg.append("text")
.attr("x", svgWidth / 2)
.attr("y", 122)
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-weight", "bold")
.attr("fill", colors.navy)
.text(selectedConnectivity);
// Connection to cloud
if (selectedCloud) {
svg.append("line")
.attr("x1", svgWidth / 2)
.attr("y1", 75)
.attr("x2", svgWidth / 2)
.attr("y2", 100)
.attr("stroke", colors.gray)
.attr("stroke-width", 2)
.attr("stroke-dasharray", "4,4");
}
}
// Sensors layer
const selectedSensorsList = domain.sensors.filter(s => selectedSensors.has(s.id));
const sensorCount = selectedSensorsList.length;
const sensorStartX = svgWidth / 2 - (sensorCount * 30) / 2;
selectedSensorsList.forEach((sensor, i) => {
const x = sensorStartX + i * 35 + 15;
svg.append("rect")
.attr("x", x - 15)
.attr("y", 180)
.attr("width", 30)
.attr("height", 30)
.attr("rx", 4)
.attr("fill", `${colors.teal}33`)
.attr("stroke", colors.teal)
.attr("stroke-width", 2);
svg.append("text")
.attr("x", x)
.attr("y", 199)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("📡");
// Connection to gateway
if (selectedConnectivity) {
svg.append("line")
.attr("x1", x)
.attr("y1", 180)
.attr("x2", svgWidth / 2)
.attr("y2", 135)
.attr("stroke", colors.teal)
.attr("stroke-width", 1)
.attr("opacity", 0.5);
}
});
// Actuators layer
const selectedActuatorsList = domain.actuators.filter(a => selectedActuators.has(a.id));
const actuatorCount = selectedActuatorsList.length;
const actuatorStartX = svgWidth / 2 - (actuatorCount * 30) / 2;
selectedActuatorsList.forEach((actuator, i) => {
const x = actuatorStartX + i * 35 + 15;
svg.append("rect")
.attr("x", x - 15)
.attr("y", 250)
.attr("width", 30)
.attr("height", 30)
.attr("rx", 4)
.attr("fill", `${colors.orange}33`)
.attr("stroke", colors.orange)
.attr("stroke-width", 2);
svg.append("text")
.attr("x", x)
.attr("y", 269)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.text("⚡");
// Connection to gateway
if (selectedConnectivity) {
svg.append("line")
.attr("x1", x)
.attr("y1", 250)
.attr("x2", svgWidth / 2)
.attr("y2", 135)
.attr("stroke", colors.orange)
.attr("stroke-width", 1)
.attr("opacity", 0.5);
}
});
// Labels
if (sensorCount > 0) {
svg.append("text")
.attr("x", 30)
.attr("y", 195)
.attr("font-size", "10px")
.attr("fill", colors.teal)
.attr("font-weight", "bold")
.text(`${sensorCount} Sensors`);
}
if (actuatorCount > 0) {
svg.append("text")
.attr("x", 30)
.attr("y", 265)
.attr("font-size", "10px")
.attr("fill", colors.orange)
.attr("font-weight", "bold")
.text(`${actuatorCount} Actuators`);
}
// Empty state
if (sensorCount === 0 && actuatorCount === 0 && !selectedConnectivity && !selectedCloud) {
svg.append("text")
.attr("x", svgWidth / 2)
.attr("y", svgHeight / 2)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", colors.gray)
.text("Select components to build architecture");
}
}
// Requirements calculation
function updateRequirements() {
const domain = domains[selectedDomain];
const reqContainer = container.select("#requirements-content");
reqContainer.html("");
const selectedSensorsList = domain.sensors.filter(s => selectedSensors.has(s.id));
const selectedActuatorsList = domain.actuators.filter(a => selectedActuators.has(a.id));
// Calculate totals
let totalPower = 0;
let totalBandwidth = 0;
selectedSensorsList.forEach(s => {
totalPower += s.power;
totalBandwidth += s.bandwidth;
});
selectedActuatorsList.forEach(a => {
totalPower += a.power;
});
// Power requirement
const powerReq = reqContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px")
.style("background", colors.lightGray)
.style("border-radius", "6px")
.style("margin-bottom", "8px");
powerReq.append("span")
.style("font-weight", "bold")
.style("color", colors.navy)
.text("⚡ Power Budget:");
powerReq.append("span")
.style("color", totalPower > 100 ? colors.red : colors.green)
.style("font-weight", "bold")
.text(`${totalPower.toFixed(1)} W`);
// Bandwidth requirement
const bwReq = reqContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px")
.style("background", colors.lightGray)
.style("border-radius", "6px")
.style("margin-bottom", "8px");
bwReq.append("span")
.style("font-weight", "bold")
.style("color", colors.navy)
.text("📶 Bandwidth:");
bwReq.append("span")
.style("color", colors.teal)
.style("font-weight", "bold")
.text(`${totalBandwidth.toFixed(1)} KB/s`);
// Latency requirement
const latReq = reqContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px")
.style("background", colors.lightGray)
.style("border-radius", "6px")
.style("margin-bottom", "8px");
latReq.append("span")
.style("font-weight", "bold")
.style("color", colors.navy)
.text("⏱️ Latency:");
latReq.append("span")
.style("color", colors.orange)
.style("font-weight", "bold")
.text(domain.latencyReq);
// Security level
const secReq = reqContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px")
.style("background", colors.lightGray)
.style("border-radius", "6px");
secReq.append("span")
.style("font-weight", "bold")
.style("color", colors.navy)
.text("🔒 Security Level:");
const secColor = domain.securityLevel === "Critical" ? colors.red :
domain.securityLevel === "High" ? colors.orange :
domain.securityLevel === "Medium" ? colors.teal : colors.green;
secReq.append("span")
.style("color", secColor)
.style("font-weight", "bold")
.text(domain.securityLevel);
}
// Cost estimation
function updateCostEstimate() {
const domain = domains[selectedDomain];
const costContainer = container.select("#cost-content");
costContainer.html("");
const selectedSensorsList = domain.sensors.filter(s => selectedSensors.has(s.id));
const selectedActuatorsList = domain.actuators.filter(a => selectedActuators.has(a.id));
let sensorCost = 0;
let actuatorCost = 0;
selectedSensorsList.forEach(s => sensorCost += s.cost);
selectedActuatorsList.forEach(a => actuatorCost += a.cost);
// Gateway/connectivity cost estimate
const connectivityCost = selectedConnectivity ? 150 : 0;
// Cloud cost estimate (monthly)
const cloudMonthlyCost = selectedCloud ? 50 : 0;
const totalHardware = sensorCost + actuatorCost + connectivityCost;
// Sensors cost
costContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "6px 0")
.style("border-bottom", `1px solid ${colors.lightGray}`)
.html(`<span style="color:${colors.teal}">📡 Sensors (${selectedSensorsList.length}):</span><span style="font-weight:bold">$${sensorCost}</span>`);
// Actuators cost
costContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "6px 0")
.style("border-bottom", `1px solid ${colors.lightGray}`)
.html(`<span style="color:${colors.orange}">⚡ Actuators (${selectedActuatorsList.length}):</span><span style="font-weight:bold">$${actuatorCost}</span>`);
// Connectivity cost
costContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "6px 0")
.style("border-bottom", `1px solid ${colors.lightGray}`)
.html(`<span style="color:${colors.navy}">📶 Gateway/Hub:</span><span style="font-weight:bold">$${connectivityCost}</span>`);
// Total hardware
costContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px 0")
.style("margin-top", "5px")
.style("border-top", `2px solid ${colors.navy}`)
.html(`<span style="font-weight:bold;color:${colors.navy}">Hardware Total:</span><span style="font-weight:bold;font-size:18px;color:${colors.green}">$${totalHardware}</span>`);
// Cloud monthly
if (cloudMonthlyCost > 0) {
costContainer.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("padding", "8px 0")
.style("margin-top", "10px")
.style("background", `${colors.purple}11`)
.style("border-radius", "6px")
.style("padding", "10px")
.html(`<span style="color:${colors.purple}">☁️ Cloud (monthly est.):</span><span style="font-weight:bold;color:${colors.purple}">~$${cloudMonthlyCost}/mo</span>`);
}
}
// Export summary
function exportSummary() {
const domain = domains[selectedDomain];
const selectedSensorsList = domain.sensors.filter(s => selectedSensors.has(s.id));
const selectedActuatorsList = domain.actuators.filter(a => selectedActuators.has(a.id));
let totalPower = 0;
let totalBandwidth = 0;
let totalCost = 0;
selectedSensorsList.forEach(s => {
totalPower += s.power;
totalBandwidth += s.bandwidth;
totalCost += s.cost;
});
selectedActuatorsList.forEach(a => {
totalPower += a.power;
totalCost += a.cost;
});
if (selectedConnectivity) totalCost += 150;
const summary = `
╔══════════════════════════════════════════════════════════════╗
║ IoT USE CASE SUMMARY ║
╠══════════════════════════════════════════════════════════════╣
║ Domain: ${selectedDomain.padEnd(50)}║
║ Generated: ${new Date().toLocaleDateString().padEnd(47)}║
╠══════════════════════════════════════════════════════════════╣
║ COMPONENTS ║
╠══════════════════════════════════════════════════════════════╣
║ Sensors (${selectedSensorsList.length}): ║
${selectedSensorsList.map(s => `║ - ${s.name.padEnd(54)}║`).join('\n') || '║ (none selected) ║'}
║ ║
║ Actuators (${selectedActuatorsList.length}): ║
${selectedActuatorsList.map(a => `║ - ${a.name.padEnd(54)}║`).join('\n') || '║ (none selected) ║'}
║ ║
║ Connectivity: ${(selectedConnectivity || 'Not selected').padEnd(44)}║
║ Cloud Service: ${(selectedCloud || 'Not selected').padEnd(43)}║
╠══════════════════════════════════════════════════════════════╣
║ REQUIREMENTS ║
╠══════════════════════════════════════════════════════════════╣
║ Power Budget: ${(totalPower.toFixed(1) + ' W').padEnd(44)}║
║ Bandwidth: ${(totalBandwidth.toFixed(1) + ' KB/s').padEnd(48)}║
║ Latency: ${domain.latencyReq.padEnd(50)}║
║ Security Level: ${domain.securityLevel.padEnd(42)}║
╠══════════════════════════════════════════════════════════════╣
║ COST ESTIMATE ║
╠══════════════════════════════════════════════════════════════╣
║ Hardware Total: $${totalCost.toString().padEnd(41)}║
║ Cloud (monthly): ${selectedCloud ? '~$50/mo' : 'N/A'.padEnd(41)}║
╚══════════════════════════════════════════════════════════════╝
`.trim();
const exportAreaEl = container.select("#export-area");
exportAreaEl.style("display", "block")
.property("value", summary);
// Select all text for easy copying
exportAreaEl.node().select();
}
// Initialize UI
updateUI();
return container.node();
}137.2 Understanding the Use Case Builder
This interactive tool helps you design IoT solutions by considering the key components and their interactions:
137.2.1 Component Categories
- Sensors - Data collection devices that monitor physical parameters
- Actuators - Devices that take action based on processed data
- Connectivity - Communication protocols linking edge devices to the network
- Cloud Services - Backend platforms for data storage, processing, and analytics
137.2.2 Domain-Specific Considerations
Each industry domain has unique requirements:
| Domain | Key Sensors | Critical Requirements |
|---|---|---|
| Smart Home | Temperature, Motion, Camera | Low latency for automation |
| Healthcare | Vital signs, Fall detection | Critical security, reliability |
| Agriculture | Soil, Weather, NDVI | Long range, low power |
| Industrial | Vibration, Thermal, Flow | Ultra-low latency, high reliability |
| Smart City | Traffic, Air quality, Parking | Scalability, wide coverage |
| Retail | RFID, Beacons, Footfall | Real-time analytics |
| Logistics | GPS, Temperature, Shock | Global connectivity, tracking |
137.2.3 Auto-Generated Requirements
The tool automatically calculates:
- Power Budget: Sum of all device power consumption
- Bandwidth: Aggregate data transmission needs
- Latency: Domain-specific response time requirements
- Security Level: Based on data sensitivity
TipDesign Best Practice
Start with your core use case requirements, then add components incrementally. The architecture diagram helps visualize how your selection creates a complete IoT solution.
137.3 Related Topics
- IoT Application Domains - Deep dive into industry applications
- IoT Use Cases - Real-world implementation examples
- Edge-Fog-Cloud Architecture - System architecture patterns
Interactive tool created for the IoT Class Textbook