// Protocol scoring and recommendation logic
function getRecommendations(answers) {
const protocols = [
{
name: "LoRaWAN",
icon: "📡",
scores: { range: {long: 10, medium: 5, cellular: 0, short: 2}, power: {"ultra-low": 10, low: 8, unlimited: 5},
dataRate: {tiny: 10, small: 6, medium: 2, large: 0}, latency: {tolerant: 10, moderate: 7, fast: 3, realtime: 0},
topology: {uplink: 10, downlink: 5, bidirectional: 6, p2p: 0}, infrastructure: {gateway: 10, wifi: 3, cellular: 2, none: 0}},
description: "Long-range, low-power for infrequent sensor data",
useCases: ["Agriculture monitoring", "Smart meters", "Asset tracking", "Environmental sensors"],
pros: ["15+ km range", "10+ year battery", "Low cost per device"],
cons: ["Low data rate (0.3-27 kbps)", "High latency", "Requires gateway infrastructure"]
},
{
name: "NB-IoT",
icon: "📶",
scores: { range: {cellular: 10, long: 7, medium: 5, short: 3}, power: {"ultra-low": 8, low: 9, unlimited: 7},
dataRate: {tiny: 10, small: 8, medium: 5, large: 0}, latency: {tolerant: 10, moderate: 8, fast: 5, realtime: 2},
topology: {uplink: 10, downlink: 8, bidirectional: 8, p2p: 0}, infrastructure: {cellular: 10, gateway: 5, wifi: 3, none: 0}},
description: "Cellular IoT for wide-area deployment",
useCases: ["Smart cities", "Utility meters", "Wearables", "Fleet management"],
pros: ["Uses existing cell towers", "Good indoor penetration", "Carrier-managed"],
cons: ["Monthly data fees", "Carrier dependency", "Limited in rural areas"]
},
{
name: "Wi-Fi",
icon: "📶",
scores: { range: {short: 10, medium: 5, long: 0, cellular: 0}, power: {"ultra-low": 0, low: 3, unlimited: 10},
dataRate: {large: 10, medium: 10, small: 10, tiny: 8}, latency: {realtime: 10, fast: 10, moderate: 10, tolerant: 10},
topology: {bidirectional: 10, uplink: 9, downlink: 9, p2p: 5}, infrastructure: {wifi: 10, gateway: 5, cellular: 0, none: 0}},
description: "High-bandwidth for plugged-in devices",
useCases: ["Smart home appliances", "IP cameras", "Voice assistants", "Industrial HMIs"],
pros: ["High bandwidth (Mbps)", "Low latency", "Ubiquitous infrastructure"],
cons: ["High power consumption", "Limited range", "Congestion in dense deployments"]
},
{
name: "BLE (Bluetooth Low Energy)",
icon: "🔵",
scores: { range: {short: 10, medium: 3, long: 0, cellular: 0}, power: {"ultra-low": 9, low: 10, unlimited: 8},
dataRate: {tiny: 10, small: 9, medium: 6, large: 2}, latency: {realtime: 8, fast: 10, moderate: 10, tolerant: 10},
topology: {p2p: 10, bidirectional: 8, uplink: 7, downlink: 7}, infrastructure: {none: 10, wifi: 7, gateway: 6, cellular: 0}},
description: "Low-power for smartphone-connected devices",
useCases: ["Fitness trackers", "Beacons", "Smart watches", "Wireless sensors"],
pros: ["Very low power", "Smartphone connectivity", "No infrastructure needed"],
cons: ["Short range (10-100m)", "Requires phone/gateway nearby", "Limited mesh support"]
},
{
name: "Zigbee",
icon: "🕸️",
scores: { range: {short: 8, medium: 6, long: 0, cellular: 0}, power: {"ultra-low": 8, low: 9, unlimited: 7},
dataRate: {tiny: 10, small: 8, medium: 4, large: 0}, latency: {realtime: 6, fast: 8, moderate: 10, tolerant: 10},
topology: {p2p: 8, bidirectional: 9, uplink: 8, downlink: 8}, infrastructure: {gateway: 10, wifi: 5, none: 4, cellular: 0}},
description: "Mesh networking for smart home/building",
useCases: ["Smart home devices", "Building automation", "Industrial sensors", "Lighting control"],
pros: ["Self-healing mesh", "Low power", "Mature ecosystem"],
cons: ["Requires coordinator", "2.4 GHz congestion", "Short individual range"]
},
{
name: "MQTT over Wi-Fi/Cellular",
icon: "📨",
scores: { range: {short: 8, medium: 8, long: 5, cellular: 9}, power: {"ultra-low": 2, low: 5, unlimited: 10},
dataRate: {tiny: 10, small: 10, medium: 9, large: 7}, latency: {realtime: 8, fast: 10, moderate: 10, tolerant: 10},
topology: {uplink: 10, downlink: 10, bidirectional: 10, p2p: 3}, infrastructure: {wifi: 10, cellular: 10, gateway: 8, none: 0}},
description: "Pub/sub messaging over existing networks",
useCases: ["Cloud connectivity", "Real-time dashboards", "Device management", "Telemetry"],
pros: ["Efficient pub/sub", "QoS levels", "Wide language support"],
cons: ["Requires IP connectivity", "Broker infrastructure", "Not for ultra-constrained"]
},
{
name: "CoAP",
icon: "🔗",
scores: { range: {short: 8, medium: 8, long: 3, cellular: 7}, power: {"ultra-low": 8, low: 8, unlimited: 8},
dataRate: {tiny: 10, small: 9, medium: 7, large: 3}, latency: {realtime: 7, fast: 9, moderate: 10, tolerant: 10},
topology: {p2p: 10, bidirectional: 9, uplink: 8, downlink: 8}, infrastructure: {gateway: 9, wifi: 8, none: 6, cellular: 7}},
description: "RESTful protocol for constrained devices",
useCases: ["M2M communication", "Sensor networks", "Smart objects", "Home automation"],
pros: ["HTTP-like simplicity", "UDP efficient", "Works on constrained devices"],
cons: ["Less ecosystem than MQTT", "Limited browser support", "Needs proxy for web"]
}
];
// Calculate scores
const scored = protocols.map(p => {
let total = 0;
let count = 0;
for (const [key, value] of Object.entries(answers)) {
if (p.scores[key] && p.scores[key][value] !== undefined) {
total += p.scores[key][value];
count++;
}
}
return { ...p, score: count > 0 ? Math.round(total / count * 10) : 0 };
});
// Sort by score
scored.sort((a, b) => b.score - a.score);
// Render recommendations
return html`
<div style="display: flex; flex-direction: column; gap: 15px;">
${scored.slice(0, 4).map((p, i) => html`
<div style="border: 2px solid ${i === 0 ? '#27AE60' : '#dee2e6'}; border-radius: 12px; padding: 20px;
background: ${i === 0 ? '#E8F6F3' : 'white'};">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 28px;">${p.icon}</span>
<span style="font-size: 20px; font-weight: bold; color: #2C3E50;">${p.name}</span>
${i === 0 ? html`<span style="background: #27AE60; color: white; padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: bold;">BEST MATCH</span>` : ''}
</div>
<div style="font-size: 24px; font-weight: bold; color: ${p.score >= 70 ? '#27AE60' : p.score >= 50 ? '#F39C12' : '#E74C3C'};">
${p.score}%
</div>
</div>
<p style="color: #666; margin: 10px 0; font-size: 14px;">${p.description}</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 15px; font-size: 13px;">
<div>
<strong style="color: #27AE60;">✓ Pros:</strong>
<ul style="margin: 5px 0; padding-left: 20px; color: #666;">
${p.pros.map(pro => html`<li>${pro}</li>`)}
</ul>
</div>
<div>
<strong style="color: #E74C3C;">✗ Cons:</strong>
<ul style="margin: 5px 0; padding-left: 20px; color: #666;">
${p.cons.map(con => html`<li>${con}</li>`)}
</ul>
</div>
</div>
<div style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #eee;">
<strong style="font-size: 12px; color: #666;">Use Cases:</strong>
<span style="font-size: 12px; color: #888;"> ${p.useCases.join(' • ')}</span>
</div>
</div>
`)}
</div>
<div style="margin-top: 20px; padding: 15px; background: #FEF9E7; border-radius: 8px; border-left: 4px solid #F39C12;">
<strong>Your Requirements Summary:</strong>
<div style="display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px;">
${Object.entries(answers).map(([k, v]) => html`
<span style="background: white; padding: 4px 10px; border-radius: 15px; font-size: 12px; border: 1px solid #ddd;">
${k}: ${v}
</span>
`)}
</div>
</div>
`;
}