I have the following setup. It takes a date picker for the user interface and the time entry for the user interface in EST, taking into account DST. When entered it stores these two variables in global sources called triggerTime and triggerDate. It stores them in UTC 24 hour formatting. In my check date and time function I'm trying to compare the date and time entered against the system time and when they match trigger source11 to go through the flow. It is not matching or there is some other issue, maybe the system date is in a different format? I have the debug on all of my nodes. I get the date entry and the time entry and see that it is stored in the global sources correctly. I do not see any other debug info after the time entry.
If I unwire the Check Date and Time from Split Digits/Assign IR and wire in an eztimer node to Split Digits/Assign IR and choose a time in the future, the system will send source11 through the flow when that time is reached. eztimer doesn't take into account a date, just a time. It will not work for my situation as I need to check a date and a time. Everything after check date and time in my flow works to send source11 through...
For a date picked as 5/23/2024 and a time entered as 3:17 PM EST it stores triggerDate "05/23/2024" and triggerTime "19:17:00". In my eztimer node if I enter in 19:17:00, when that time is reached it will trigger source11 through the flow as mentioned above.
Any help would be appreciate...Thanks in adavance!
[
{
"id": "841a93d93256814b",
"type": "globalcache-out",
"z": "bfa8244b190d540b",
"name": "Source11",
"controller": "e0bfc5286dd39809",
"unit_number": "1",
"output": "1",
"gccommand": "sendir",
"x": 1820,
"y": 2640,
"wires": []
},
{
"id": "de0fc19df0d25941",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Send IR to GC",
"func": "// Retrieve matchedCommands array from global context\nvar matchedCommands11 = global.get('matchedCommands11');\n\n// Check if matchedCommands is defined and is an array\nif (Array.isArray(matchedCommands11)) {\n // Iterate over each IR command in the matchedCommands array\n matchedCommands11.forEach(function(irCommand) {\n // Construct a message object with the IR command as the payload\n var msgToSend = {\n payload: irCommand\n };\n \n // Send the message to the Global Cache device\n // Make sure to replace 'globalCacheNode' with the actual name of your Global Cache node\n node.send(msgToSend);\n });\n} else {\n // Handle the case when matchedCommands is empty or not an array\n node.error(\"No matched IR commands found in the global context.\");\n}\n\n// Don't forget to return the message\nreturn null;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1580,
"y": 2640,
"wires": [
[
"841a93d93256814b"
]
]
},
{
"id": "7db0eef0a925f692",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Split digits/Assign IR",
"func": "// Define IR commands array\nvar irCommands = [\n // ir command 0\n \"1,58000,1,37,23,351,23,164,23,94,23,164,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,94,23,164,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n // ir command 1\n \"1,58000,1,37,23,351,23,164,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 2\n \"1,58000,1,37,23,351,23,164,23,164,23,164,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,164,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 3\n \"1,58000,1,37,23,351,23,164,23,164,23,164,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,164,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 4\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 5\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,164,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 6\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 7\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 8\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,94,23,164,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\",\n //ir command 9\n \"1,58000,1,37,23,351,23,164,23,164,23,94,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351,23,164,23,164,23,94,23,94,23,94,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,164,23,351\"\n // Add more commands as needed\n];\n\n// Get the value of source11 from the message payload\nvar source11 = msg.payload;\n\n// Check if source11 is a number\nif (typeof source11 === 'number') {\n // Convert source11 to a string to handle multi-digit numbers\n var source11String = source11.toString();\n\n // Convert source2String to an array of digits\n var numberArray = source11String.split('').map(Number);\n\n // Initialize an array to store matched IR commands\n var matchedCommands11 = [];\n\n // Iterate over each digit in the number array\n numberArray.forEach(function(digit) {\n // Ensure the digit is within the range 0-9\n if (digit >= 0 && digit <= 9) {\n // Get the corresponding IR command for the digit\n var command = irCommands[digit];\n // Push the command to the array of matched commands\n matchedCommands11.push(command);\n } else {\n node.warn(\"Invalid digit: \" + digit);\n }\n });\n\n // Store the array of matched commands in the global context\n global.set(\"matchedCommands11\", matchedCommands11);\n} else {\n // Handle the case when source11 is not a number\n node.error(\"Default channel must be a number.\");\n}\n\n// Return the message\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1320,
"y": 2640,
"wires": [
[
"de0fc19df0d25941"
]
]
},
{
"id": "da010df42e283fb9",
"type": "ui_text_input",
"z": "bfa8244b190d540b",
"name": "Set Trigger Time",
"label": "Enter Time (hh:mm AM/PM):",
"tooltip": "Time needs to be in non-24-hour format (e.g., 4:00 PM)",
"group": "1f50c834885d8903",
"order": 3,
"width": 3,
"height": 1,
"passthru": true,
"mode": "text",
"delay": 300,
"topic": "",
"topicType": "str",
"x": 160,
"y": 2580,
"wires": [
[
"b833486452a31031",
"ebd015427b917d12"
]
]
},
{
"id": "ebd015427b917d12",
"type": "debug",
"z": "bfa8244b190d540b",
"name": "Debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 810,
"y": 2500,
"wires": []
},
{
"id": "9f5678f9c6a6e760",
"type": "ui_date_picker",
"z": "bfa8244b190d540b",
"name": "Set Trigger Date",
"label": "Select Date (mm/dd/yyyy)",
"group": "1f50c834885d8903",
"order": 2,
"width": 5,
"height": 1,
"passthru": true,
"topic": "",
"topicType": "str",
"x": 160,
"y": 2640,
"wires": [
[
"f2da2682d19a231b",
"ebd015427b917d12"
]
]
},
{
"id": "f2da2682d19a231b",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Date Picker to Object",
"func": "// Check if the payload is a valid date string or a timestamp\nvar dateStr = msg.payload.toString(); // Ensure the payload is treated as a string\nnode.log('Received payload: ' + dateStr);\n\n// Check if the payload is a valid timestamp (numeric value)\nvar timestamp = parseInt(dateStr, 10);\nif (!isNaN(timestamp)) {\n // Convert timestamp to Date object\n var date = new Date(timestamp);\n\n // Check if the created Date object is valid\n if (isNaN(date.getTime())) {\n node.error('Invalid timestamp: ' + dateStr);\n return null; // Return null to end the function execution\n }\n\n // Set the payload to the Date object\n msg.payload = date;\n\n // Pass the message to the next node in the flow\n return msg;\n}\n\n// Parse the date string using a regular expression\nvar match = dateStr.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\nif (!match) {\n node.error('Invalid date format: ' + dateStr);\n return null; // Return null to end the function execution\n}\n\n// Extract day, month, and year from the matched groups\nvar day = parseInt(match[2], 10);\nvar month = parseInt(match[1], 10) - 1; // Month is 0-based in JavaScript Date object\nvar year = parseInt(match[3], 10);\n\n// Create a new Date object\nvar date = new Date(year, month, day);\n\n// Check if the created Date object is valid\nif (isNaN(date.getTime())) {\n node.error('Invalid date: ' + dateStr);\n return null; // Return null to end the function execution\n}\n\n// Set the payload to the Date object\nmsg.payload = date;\n\n// Pass the message to the next node in the flow\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 440,
"y": 2640,
"wires": [
[
"c19b210ff990938e",
"ebd015427b917d12"
]
]
},
{
"id": "c19b210ff990938e",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Set Global Trigger Date",
"func": "// Set Global Trigger Date function\nif (!(msg.payload instanceof Date)) {\n node.error('Payload is not a Date object');\n return null;\n}\n\nvar date = msg.payload;\n\n// Adjust the date to the local timezone\nvar localDate = new Date(date.toLocaleString('en-US', {timeZone: 'America/New_York'}));\nnode.log('Local date: ' + localDate);\n\n// Extract date components from the adjusted date\nvar localDay = localDate.getDate();\nvar localMonth = localDate.getMonth() + 1; // Month index starts from 0, so add 1\nvar localYear = localDate.getFullYear();\n\n// Rearrange to mm/dd/yyyy format\nvar triggerDate = localMonth + '/' + localDay + '/' + localYear;\nnode.log('Trigger date set to: ' + triggerDate);\n\n// Store the date in the global context variable 'triggerDate'\nglobal.set('triggerDate', triggerDate);\n\n// Return null to end function execution without emitting any message\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 730,
"y": 2640,
"wires": [
[
"352983aa107ccbfb",
"ebd015427b917d12"
]
]
},
{
"id": "b833486452a31031",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Set Global Trigger Time",
"func": "// Set Global Trigger Time function\nvar timeInput = msg.payload.trim(); // Trim any leading/trailing whitespace\nnode.log('Received time input: ' + timeInput);\n\n// Parse the time input to extract hours, minutes, and AM/PM designation\nvar match = timeInput.match(/^(1[0-2]|0?[1-9]):([0-5][0-9])\\s?(AM|PM)$/i);\nif (!match) {\n node.error('Invalid time format: ' + timeInput);\n return null;\n}\n\nvar hours = parseInt(match[1], 10);\nvar minutes = parseInt(match[2], 10);\nvar period = match[3].toUpperCase();\nnode.log('Parsed time: ' + hours + ':' + minutes + ' ' + period);\n\n// Adjust hours for PM times\nif (period === 'PM' && hours < 12) {\n hours += 12;\n} else if (period === 'AM' && hours === 12) {\n hours = 0; // Midnight edge case\n}\n\n// Create a new Date object for the input time in EST\nvar inputDate = new Date();\ninputDate.setHours(hours, minutes, 0);\nnode.log('Input date object: ' + inputDate);\n\n// Determine if the current date is within DST\nvar jan = new Date(inputDate.getFullYear(), 0, 1);\nvar jul = new Date(inputDate.getFullYear(), 6, 1);\nvar isDST = Math.min(jan.getTimezoneOffset(), jul.getTimezoneOffset()) === inputDate.getTimezoneOffset();\nnode.log('Daylight saving time: ' + (isDST ? 'yes' : 'no'));\n\n// Get the UTC offset including DST\nvar utcOffset = isDST ? 4 : 5; // EDT (UTC-4) during DST, EST (UTC-5) otherwise\nnode.log('UTC offset: ' + utcOffset);\n\n// Adjust for the timezone difference\ninputDate.setHours(inputDate.getHours() + utcOffset);\n\n// Format UTC time (24-hour format)\nvar utcHours = ('0' + inputDate.getUTCHours()).slice(-2);\nvar utcMinutes = ('0' + inputDate.getUTCMinutes()).slice(-2);\nvar utcTime = utcHours + ':' + utcMinutes + ':00';\nnode.log('UTC time: ' + utcTime);\n\n// Store the UTC time in the global context variable 'triggerTime'\nglobal.set(\"triggerTime\", utcTime);\n\n// Store the date in the desired format (mm/dd/yyyy) in the global context variable 'triggerDate'\nvar month = ('0' + (inputDate.getMonth() + 1)).slice(-2); // Month is 0-based, so add 1\nvar day = ('0' + inputDate.getDate()).slice(-2);\nvar year = inputDate.getFullYear();\nvar triggerDate = month + '/' + day + '/' + year;\nglobal.set(\"triggerDate\", triggerDate);\n\n// Return null to end function execution without emitting any message\nreturn null;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 2580,
"wires": [
[
"ebd015427b917d12"
]
]
},
{
"id": "352983aa107ccbfb",
"type": "function",
"z": "bfa8244b190d540b",
"name": "Check Date and Time",
"func": "// Check Date and Time function\nvar triggerTime = global.get('triggerTime'); // Get triggerTime from global context\nvar triggerDate = global.get('triggerDate'); // Get triggerDate from global context\n\nif (!triggerTime || !triggerDate) {\n node.warn('Global triggerTime or triggerDate not set.');\n return null;\n}\n\n// Format the current date and time in UTC\nvar now = new Date();\nvar utcNow = now.getUTCHours() + ':' + ('0' + now.getUTCMinutes()).slice(-2) + ':00';\n\nnode.log('Current UTC time: ' + utcNow);\nnode.log('Trigger time: ' + triggerTime);\n\n// Compare current UTC time with triggerTime\nif (utcNow === triggerTime) {\n node.log('Time match found. Triggering source11.');\n msg.payload = 'source11'; // Replace with your actual payload or trigger mechanism\n return msg;\n} else {\n node.log('Time match not found.');\n return null;\n}\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1040,
"y": 2640,
"wires": [
[
"ebd015427b917d12",
"7db0eef0a925f692"
]
]
},
{
"id": "e0bfc5286dd39809",
"type": "globalcache-controller",
"name": "Test.GC.MFT",
"host": "172.16.11.228",
"port": "4998",
"mode": "request-disconnect"
},
{
"id": "1f50c834885d8903",
"type": "ui_group",
"name": "Jason",
"tab": "0ceb20451ccb4b40",
"order": 1,
"disp": true,
"width": 8,
"collapse": false
},
{
"id": "0ceb20451ccb4b40",
"type": "ui_tab",
"name": "Jason Test",
"icon": "dashboard",
"order": 6,
"disabled": false,
"hidden": false
}
]