医疗设备维护警报系统
这是一个Project Management, Multimodal AI领域的自动化工作流,包含 14 个节点。主要使用 Code, Cron, Wait, Filter, WhatsApp 等节点。 使用Google Sheets监控医疗设备并发送WhatsApp和邮件警报
- •Google Sheets API 凭证
{
"id": "hWACWrSaTJyZTxzH",
"meta": {
"instanceId": "dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281",
"templateCredsSetupCompleted": true
},
"name": "医疗设备维护警报系统",
"tags": [],
"nodes": [
{
"id": "661d56b2-1dba-47ab-91fa-56900b544b9b",
"name": "每日设备检查(早上6点)",
"type": "n8n-nodes-base.cron",
"position": [
-1500,
140
],
"parameters": {},
"typeVersion": 1
},
{
"id": "14df28e8-686d-4c2a-8754-64e817e88941",
"name": "读取设备数据",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1280,
140
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Equipment"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4
},
{
"id": "bf61b7e2-79e9-4af7-b30b-f2aa260b51f1",
"name": "处理设备警报",
"type": "n8n-nodes-base.code",
"position": [
-1060,
140
],
"parameters": {
"jsCode": "const equipmentList = $input.all();\nconst alerts = [];\nconst today = new Date();\n\nfor (const equipment of equipmentList) {\n const equipData = equipment.json;\n \n // Skip header row\n if (equipData['Equipment ID'] === 'Equipment ID') continue;\n \n // Parse dates\n const lastMaintenance = new Date(equipData['Last Maintenance']);\n const lastCalibration = new Date(equipData['Last Calibration']);\n const warrantyExpiry = new Date(equipData['Warranty Expiry']);\n \n // Calculate days since last maintenance/calibration\n const daysSinceMaintenance = Math.floor((today - lastMaintenance) / (1000 * 60 * 60 * 24));\n const daysSinceCalibration = Math.floor((today - lastCalibration) / (1000 * 60 * 60 * 24));\n const daysToWarrantyExpiry = Math.floor((warrantyExpiry - today) / (1000 * 60 * 60 * 24));\n \n // Get maintenance and calibration intervals\n const maintenanceInterval = parseInt(equipData['Maintenance Interval (Days)']) || 90;\n const calibrationInterval = parseInt(equipData['Calibration Interval (Days)']) || 365;\n \n // Current usage hours\n const currentUsage = parseFloat(equipData['Current Usage Hours']) || 0;\n const maxUsage = parseFloat(equipData['Max Usage Hours']) || 8760; // Default 1 year\n const usagePercentage = (currentUsage / maxUsage) * 100;\n \n // Determine alert types and priority\n let alertTypes = [];\n let priority = 'Normal';\n let alertMessage = '';\n \n // Maintenance alerts\n if (daysSinceMaintenance >= maintenanceInterval) {\n alertTypes.push('OVERDUE_MAINTENANCE');\n priority = 'High';\n alertMessage += `⚠️ OVERDUE MAINTENANCE (${daysSinceMaintenance} days overdue)\\n`;\n } else if (daysSinceMaintenance >= maintenanceInterval - 7) {\n alertTypes.push('UPCOMING_MAINTENANCE');\n if (priority === 'Normal') priority = 'Medium';\n const daysLeft = maintenanceInterval - daysSinceMaintenance;\n alertMessage += `🔧 Maintenance due in ${daysLeft} days\\n`;\n }\n \n // Calibration alerts\n if (daysSinceCalibration >= calibrationInterval) {\n alertTypes.push('OVERDUE_CALIBRATION');\n priority = 'High';\n alertMessage += `⚠️ OVERDUE CALIBRATION (${daysSinceCalibration} days overdue)\\n`;\n } else if (daysSinceCalibration >= calibrationInterval - 14) {\n alertTypes.push('UPCOMING_CALIBRATION');\n if (priority === 'Normal') priority = 'Medium';\n const daysLeft = calibrationInterval - daysSinceCalibration;\n alertMessage += `🎯 Calibration due in ${daysLeft} days\\n`;\n }\n \n // Usage alerts\n if (usagePercentage >= 95) {\n alertTypes.push('CRITICAL_USAGE');\n priority = 'Critical';\n alertMessage += `🚨 CRITICAL USAGE: ${usagePercentage.toFixed(1)}% of max hours\\n`;\n } else if (usagePercentage >= 80) {\n alertTypes.push('HIGH_USAGE');\n if (priority === 'Normal' || priority === 'Medium') priority = 'Medium';\n alertMessage += `📊 High usage: ${usagePercentage.toFixed(1)}% of max hours\\n`;\n }\n \n // Warranty alerts\n if (daysToWarrantyExpiry <= 0) {\n alertTypes.push('WARRANTY_EXPIRED');\n priority = 'High';\n alertMessage += `❌ WARRANTY EXPIRED (${Math.abs(daysToWarrantyExpiry)} days ago)\\n`;\n } else if (daysToWarrantyExpiry <= 30) {\n alertTypes.push('WARRANTY_EXPIRING');\n if (priority === 'Normal') priority = 'Medium';\n alertMessage += `⏰ Warranty expires in ${daysToWarrantyExpiry} days\\n`;\n }\n \n // Status-based alerts\n if (equipData['Status'] === 'Out of Service') {\n alertTypes.push('OUT_OF_SERVICE');\n priority = 'Critical';\n alertMessage += `🔴 EQUIPMENT OUT OF SERVICE\\n`;\n } else if (equipData['Status'] === 'Needs Repair') {\n alertTypes.push('NEEDS_REPAIR');\n priority = 'High';\n alertMessage += `🔧 EQUIPMENT NEEDS REPAIR\\n`;\n }\n \n // Only create alert if there are issues\n if (alertTypes.length > 0) {\n const alert = {\n equipmentId: equipData['Equipment ID'],\n equipmentName: equipData['Equipment Name'],\n location: equipData['Location'],\n department: equipData['Department'],\n status: equipData['Status'],\n alertTypes: alertTypes,\n priority: priority,\n alertMessage: alertMessage.trim(),\n technicianEmail: equipData['Technician Email'],\n technicianWhatsApp: equipData['Technician WhatsApp'],\n supervisorEmail: equipData['Supervisor Email'],\n daysSinceMaintenance: daysSinceMaintenance,\n daysSinceCalibration: daysSinceCalibration,\n usagePercentage: usagePercentage.toFixed(1),\n daysToWarrantyExpiry: daysToWarrantyExpiry,\n manufacturer: equipData['Manufacturer'],\n model: equipData['Model'],\n serialNumber: equipData['Serial Number'],\n currentDate: today.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n })\n };\n \n // Create detailed email content\n alert.emailSubject = `🏥 Equipment Alert: ${alert.equipmentName} (${alert.equipmentId}) - ${priority} Priority`;\n \n alert.emailBody = `\nDear Maintenance Team,\n\nEquipment Maintenance Alert - ${alert.currentDate}\n\n🏥 EQUIPMENT DETAILS:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nEquipment ID: ${alert.equipmentId}\nName: ${alert.equipmentName}\nLocation: ${alert.location}\nDepartment: ${alert.department}\nStatus: ${alert.status}\nPriority: ${priority}\n\n📋 EQUIPMENT SPECIFICATIONS:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nManufacturer: ${alert.manufacturer}\nModel: ${alert.model}\nSerial Number: ${alert.serialNumber}\n\n⚠️ ALERT DETAILS:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n${alert.alertMessage}\n\n📊 MAINTENANCE STATUS:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n• Days since last maintenance: ${alert.daysSinceMaintenance}\n• Days since last calibration: ${alert.daysSinceCalibration}\n• Current usage: ${alert.usagePercentage}% of maximum\n• Warranty expires in: ${alert.daysToWarrantyExpiry} days\n\n🔧 ACTION REQUIRED:\nPlease schedule appropriate maintenance/calibration as indicated above.\nContact supervisor if equipment is critical for patient care.\n\nBest regards,\nEquipment Management System\n `;\n \n // Create WhatsApp message\n alert.whatsappMessage = `🏥 *EQUIPMENT ALERT*\\n\\n🔧 *${alert.equipmentName}*\\n📍 Location: ${alert.location}\\n🚨 Priority: ${priority}\\n\\n${alert.alertMessage.replace(/\\n/g, '\\n')}\\n\\n📊 Usage: ${alert.usagePercentage}%\\n📅 Alert Date: ${alert.currentDate}`;\n \n alerts.push(alert);\n }\n}\n\n// Sort alerts by priority (Critical > High > Medium > Normal)\nconst priorityOrder = { 'Critical': 1, 'High': 2, 'Medium': 3, 'Normal': 4 };\nalerts.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);\n\nreturn alerts.map(alert => ({ json: alert }));"
},
"typeVersion": 2
},
{
"id": "cf09a396-a848-4014-8fd2-513d36832831",
"name": "筛选带警报的设备",
"type": "n8n-nodes-base.filter",
"position": [
-620,
140
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-alerts",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.alertTypes.length }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "b176f175-4868-438d-b16b-1334cd5f1e69",
"name": "发送技术员邮件",
"type": "n8n-nodes-base.emailSend",
"position": [
-400,
-260
],
"webhookId": "a7899621-107e-426f-93d7-b9a08dd1a711",
"parameters": {
"options": {},
"subject": "={{ $json.emailSubject }}",
"toEmail": "={{ $json.technicianEmail }}",
"fromEmail": "your-email@gmail.com"
},
"credentials": {
"smtp": {
"id": "G1kyF8cSWTZ4vouN",
"name": "SMTP -test"
}
},
"typeVersion": 2
},
{
"id": "eb4277e9-7e3c-4dd6-83fe-43b823527b47",
"name": "筛选关键设备",
"type": "n8n-nodes-base.filter",
"position": [
-400,
-60
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "critical-priority",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.priority }}",
"rightValue": "Critical"
}
]
}
},
"typeVersion": 2
},
{
"id": "4ecad11b-1b12-4d54-b44c-17b3b6879c59",
"name": "向主管发送关键警报",
"type": "n8n-nodes-base.emailSend",
"position": [
-180,
-160
],
"webhookId": "c2c5a667-387d-4beb-a567-bc02a08d12c9",
"parameters": {
"options": {},
"subject": "🚨 CRITICAL EQUIPMENT ALERT - {{ $json.equipmentName }}",
"toEmail": "supervisor@hospital.com,maintenance.manager@hospital.com",
"fromEmail": "your-email@gmail.com"
},
"credentials": {
"smtp": {
"id": "G1kyF8cSWTZ4vouN",
"name": "SMTP -test"
}
},
"typeVersion": 2
},
{
"id": "b3f1bdc8-25c1-4bfa-88ab-c577a01836b0",
"name": "记录维护警报",
"type": "n8n-nodes-base.googleSheets",
"position": [
-400,
340
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=1",
"cachedResultName": "Alert_Log"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4
},
{
"id": "a35161f0-1747-4cf1-a189-3d255053468b",
"name": "筛选逾期设备",
"type": "n8n-nodes-base.filter",
"position": [
-400,
540
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "overdue-maintenance",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.alertTypes.includes('OVERDUE_MAINTENANCE') || $json.alertTypes.includes('OVERDUE_CALIBRATION') }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "d4e4bd40-5570-4463-a094-e5f54d4f58de",
"name": "更新设备状态",
"type": "n8n-nodes-base.googleSheets",
"position": [
-180,
540
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Equipment"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"id": "ScSS2KxGQULuPtdy",
"name": "Google Sheets- test"
}
},
"typeVersion": 4
},
{
"id": "aea195b9-fd94-4910-b249-352d629f9bab",
"name": "任务暂停5秒",
"type": "n8n-nodes-base.wait",
"position": [
-840,
140
],
"webhookId": "19f6b41c-a026-4cd5-bc47-624aab2cd751",
"parameters": {},
"typeVersion": 1.1
},
{
"id": "fda3f3f5-cf5d-491c-a73e-2600a2277567",
"name": "发送消息",
"type": "n8n-nodes-base.whatsApp",
"position": [
-400,
140
],
"webhookId": "15bd0b4f-0ebd-46ee-811d-fac093883808",
"parameters": {
"textBody": "=🚨 EQUIPMENT ALERT - {{ $json.equipmentName }}",
"operation": "send",
"phoneNumberId": "=+919876587688",
"additionalFields": {},
"recipientPhoneNumber": "+9199998877766"
},
"credentials": {
"whatsAppApi": {
"id": "b0PxTDPdWzznWnfG",
"name": "WhatsApp-test "
}
},
"typeVersion": 1
},
{
"id": "0f690c13-e2b7-4c0d-8c06-d4b679a33f66",
"name": "发送关键警报消息",
"type": "n8n-nodes-base.whatsApp",
"position": [
-180,
140
],
"webhookId": "15bd0b4f-0ebd-46ee-811d-fac093883808",
"parameters": {
"textBody": "=🚨 CRITICAL EQUIPMENT ALERT - {{ $json.equipmentName }}",
"operation": "send",
"phoneNumberId": "=+919876587688",
"additionalFields": {},
"recipientPhoneNumber": "+9199998877766"
},
"credentials": {
"whatsAppApi": {
"id": "b0PxTDPdWzznWnfG",
"name": "WhatsApp-test "
}
},
"typeVersion": 1
},
{
"id": "b9eac557-be5c-4482-bc22-1871cf5622aa",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1360,
-280
],
"parameters": {
"color": 6,
"width": 560,
"height": 320,
"content": "## 工作原理"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "763d56dd-6308-4e58-a96a-088242a0e354",
"connections": {
"Read Equipment Data": {
"main": [
[
{
"node": "Process Equipment Alerts",
"type": "main",
"index": 0
}
]
]
},
"Tack Break For 5 Sec": {
"main": [
[
{
"node": "Filter Equipment with Alerts",
"type": "main",
"index": 0
}
]
]
},
"Filter Overdue Equipment": {
"main": [
[
{
"node": "Update Equipment Status",
"type": "main",
"index": 0
}
]
]
},
"Process Equipment Alerts": {
"main": [
[
{
"node": "Tack Break For 5 Sec",
"type": "main",
"index": 0
}
]
]
},
"Filter Critical Equipment": {
"main": [
[
{
"node": "Send Critical Alert to Supervisors",
"type": "main",
"index": 0
},
{
"node": "Send Critical Alert Massage",
"type": "main",
"index": 0
}
]
]
},
"Daily Equipment Check (6 AM)": {
"main": [
[
{
"node": "Read Equipment Data",
"type": "main",
"index": 0
}
]
]
},
"Filter Equipment with Alerts": {
"main": [
[
{
"node": "Send Technician Email",
"type": "main",
"index": 0
},
{
"node": "Filter Critical Equipment",
"type": "main",
"index": 0
},
{
"node": "Log Maintenance Alerts",
"type": "main",
"index": 0
},
{
"node": "Filter Overdue Equipment",
"type": "main",
"index": 0
},
{
"node": "Send message",
"type": "main",
"index": 0
}
]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 项目管理, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Oneclick AI Squad
@oneclick-aiThe AI Squad Initiative is a pioneering effort to build, automate and scale AI-powered workflows using n8n.io. Our mission is to help individuals and businesses integrate AI agents seamlessly into their daily operations from automating tasks and enhancing productivity to creating innovative, intelligent solutions. We design modular, reusable AI workflow templates that empower creators, developers and teams to supercharge their automation with minimal effort and maximum impact.
分享此工作流