Skip to content

Commit fb250b6

Browse files
committed
new: added example for 24h data simulation
new example that can be used to replay sample data on a 24h scheme
1 parent 802709b commit fb250b6

6 files changed

+103
-0
lines changed
Loading
Loading
185 KB
Loading
33.8 KB
Loading
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"id":"8edcf448.d73278","type":"tab","allowCycles":false,"label":"24h Data Simulator","disabled":false,"info":"author: [email protected]\n\n\ndescription:\nData simulation system that replays a single day's \nreference dataset in a continuous loop. \n\nUses a 24-hour sample file as a template \nto generate repeating daily patterns \nfor testing and simulation purposes."},{"id":"960fe822.f78cd8","type":"group","z":"8edcf448.d73278","name":"Daily Reference Pattern Replay // Continous data ingest and simulation based on 24h scheme reference file ","style":{"label":true},"nodes":["2159bd3e.fbd582","48bd139.db610ec","ceec7ee7.e5625","1d69b214.0f6bfe","eeee3487.33cae8","f4518285.e6eaf","d1f2548d.d27528","52de7c95.f92fe4"],"x":75,"y":120,"w":1110,"h":189},{"id":"2159bd3e.fbd582","type":"debug","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"","active":true,"console":"false","xaxis":"_time","complete":"true","x":1090,"y":160,"wires":[],"_type":"node"},{"id":"48bd139.db610ec","type":"function","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"Filter last x minutes","func":"function filterAndUpdateTimestamps(msg, timeRangeMinutes) {\n var data = msg.payload;\n var now = new Date();\n var timeRangeMs = timeRangeMinutes * 60000; // Convert minutes to milliseconds\n var cutoffTime = new Date(now.getTime() - timeRangeMs);\n\n // Debug: Log input data length\n node.warn(`Input data length: ${data.length}`);\n node.warn(`Filtering last ${timeRangeMinutes} minutes, from ${cutoffTime.toISOString()} to ${now.toISOString()}`);\n\n if (!Array.isArray(data)) {\n node.error(\"Input data is not an array\");\n return [];\n }\n\n // First, update all timestamps to today's date\n var updatedData = data.map(entry => {\n if (!entry._time) {\n node.warn(`Entry missing _time field: ${JSON.stringify(entry)}`);\n return entry;\n }\n var entryTime = new Date(entry._time);\n if (isNaN(entryTime.getTime())) {\n node.warn(`Invalid date: ${entry._time}`);\n return entry;\n }\n var updatedTime = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate(),\n entryTime.getHours(),\n entryTime.getMinutes(),\n entryTime.getSeconds(),\n entryTime.getMilliseconds()\n );\n return {\n ...entry,\n _time: updatedTime.toISOString()\n };\n });\n\n // Then, filter the updated data\n var filteredData = updatedData.filter(entry => {\n var entryTime = new Date(entry._time);\n return entryTime >= cutoffTime && entryTime <= now;\n });\n\n // Debug: Log filtered data length\n node.warn(`Filtered data length: ${filteredData.length}`);\n\n return filteredData;\n}\n\n// Usage\n// This can be set to any value you want in MINUTES\nvar timeRangeMinutes = msg.flowSetting_simulatorRun // 5; \n\nmsg.payload = filterAndUpdateTimestamps(msg, timeRangeMinutes);\n\n// Debug: Log final payload length\nnode.warn(`Final payload length: ${msg.payload.length}`);\n\nreturn msg;","outputs":1,"language":"javascript","noerr":0,"x":710,"y":200,"wires":[["ceec7ee7.e5625"]],"_type":"node"},{"id":"ceec7ee7.e5625","type":"function","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"prep TS values","func":"msg.payload = msg.payload.map(entry => {\n // Create a new object with all properties from the entry\n return Object.assign({}, entry);\n \n // Alternatively, use the spread operator:\n // return { ...entry };\n});\nreturn msg;","outputs":1,"language":"javascript","noerr":0,"x":920,"y":200,"wires":[["2159bd3e.fbd582","52de7c95.f92fe4"]],"_type":"node"},{"id":"1d69b214.0f6bfe","type":"inject","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"every 5min","topic":"","payload":"","payloadType":"date","repeat":"300","repeatEnd":"0","endTime":"0","crontab":"","offset":"","once":false,"properties":"","timezone":"utc","betweentimesunit":"m","showNextExecution":true,"powerMode":false,"x":190,"y":200,"wires":[["f4518285.e6eaf"]]},{"id":"eeee3487.33cae8","type":"comment","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"⬆️⬆️⬆️ adjust and config your flow here","info":"DO ONLY setup here, no other changes are needed","sticky":1,"x":460,"y":260,"wires":[],"_type":"node"},{"id":"f4518285.e6eaf","type":"function","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"CONFIG","func":"// ******************** CONFIGURATION TEMPLATE ********************\n// //\n// // EDITABLE VALUES:\n// var assetId = \"myAssetId\"; // Enter your asset ID\n// var aspectName = \"myAspectName\"; // Enter your aspect name\n// var filename = \"myFileNameWithPath\"; // Enter your file path\n// var simulatorRun = 5; // Enter the occurance your flow is run in minutes [min]\n// //\n// // DO NOT MODIFY BELOW THIS LINE\n// // **************************************************************\n// msg.asset = assetId\n// msg.file = filename\n// msg.topic = assetId + \"/\" + aspectName;\n// return msg;\n// **************************************************************\n\n\n// EDITABLE VALUES:\nvar assetId = \"26a76a1e8d8f48d791fc4ded12e39686\"; // Enter your asset ID\nvar aspectName = \"environmentData\"; // Enter your aspect name\nvar filename = \"env-data.json\"; // Enter your file path\nvar simulatorRun = 5; // set to run every 5min\n//\n//\n// DO NOT MODIFY BELOW THIS LINE\n// **************************************************************\nmsg.asset = assetId\nmsg.file = filename\nmsg.topic = assetId + \"/\" + aspectName;\nmsg.flowSetting_simulatorRun = simulatorRun\n\nreturn msg;\n","outputs":1,"language":"javascript","noerr":0,"x":360,"y":200,"wires":[["d1f2548d.d27528"]],"_type":"node"},{"id":"d1f2548d.d27528","type":"read file","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"","asset":"","file":"","x":520,"y":200,"wires":[["48bd139.db610ec"]]},{"id":"52de7c95.f92fe4","type":"write timeseries","z":"8edcf448.d73278","g":"960fe822.f78cd8","name":"","topic":"","topicData":"","topicLabel":"","assetName":"","aspectName":"","useMerging":false,"x":1100,"y":200,"wires":[]}]

24h_Data_Simulation/readme.md

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# 24-hour Data Simulation Pattern Replay
2+
3+
This flow creates a continuous data simulation by automatically repeating a 24-hour reference dataset.
4+
It transforms a single day's worth of sample data into an ongoing simulation pattern, making it perfect for industrial testing and monitoring scenarios.
5+
6+
The diagram below illustrates the underlying logic:
7+
![image](./doc/explain-of-logic.png)
8+
9+
Here's the Visual Flow Creator (VFC) implementation:
10+
![image](./doc/24h-replay-for_data-simulation.png)
11+
12+
**Contents**
13+
- [24-hour Data Simulation Pattern Replay](#24-hour-data-simulation-pattern-replay)
14+
- [Prerequisites](#prerequisites)
15+
- [Reference Data File Structure](#reference-data-file-structure)
16+
- [Reference File Storage](#reference-file-storage)
17+
- [Setup \& Configuration](#setup--configuration)
18+
- [How It Works](#how-it-works)
19+
- [Results](#results)
20+
- [Additional Resources](#additional-resources)
21+
## Prerequisites
22+
23+
### Reference Data File Structure
24+
25+
Your reference file must contain timestamps (`_time`) and all variables defined in the Aspect. The timestamps must meet these requirements:
26+
27+
- All timestamps must be from the same day
28+
- Data must span the full day (from `00:00` to `23:59`)
29+
30+
You can customize the data sampling frequency (e.g., every 1 minute or 15 minutes) based on your needs. Important: Ensure your simulation schedule matches your reference data frequency. For example, if your reference data has 15-minute intervals but your flow runs every 5 minutes, some executions won't generate new data.
31+
32+
```json
33+
[
34+
{
35+
"_time": "2024-07-29T00:00:00.000000Z",
36+
"temperature": 24.77,
37+
"humidity": 42.02,
38+
"pressure": 979.1
39+
},
40+
{
41+
"_time": "2024-07-29T00:01:00.000000Z",
42+
"temperature": 24.77,
43+
"humidity": 42.02,
44+
"pressure": 979.1
45+
},
46+
...
47+
{
48+
"_time": "2024-07-29T23:59:00.000000Z",
49+
"temperature": 29.73,
50+
"humidity": 46.08,
51+
"pressure": 982.2
52+
}
53+
]
54+
```
55+
56+
### Reference File Storage
57+
58+
Upload your JSON reference file (containing 24 hours of sample data) directly to the asset. You have two options:
59+
60+
1. Via Asset Manager:
61+
![Reference File Upload via Asset Manager](./doc/FileUpload_AssetManager.png)
62+
2. Via Monitor:
63+
![image](./doc/FileUpload_Monitor.png)
64+
65+
## Setup & Configuration
66+
67+
1. Import the provided flow into Visual Flow Creator
68+
2. Update the CONFIG node with your specific parameters:
69+
70+
```javascript
71+
var assetId = "your-asset-id"; // Target asset identifier
72+
var aspectName = "your-aspect-name"; // Aspect to simulate
73+
var filename = "your-file.json"; // Reference data filename
74+
var simulatorRun = 5; // Simulation interval (minutes)
75+
```
76+
77+
3. Verify that your reference file is available at the specified asset location
78+
4. Deploy the flow
79+
5. Save your configuration
80+
81+
:cloud: :heavy_check_mark: Your simulation is now ready to run!
82+
83+
## How It Works
84+
85+
1. The flow activates at specified intervals (default: every 5 minutes)
86+
2. Retrieves the reference data from your asset
87+
3. Selects relevant data points based on the current time and last execution
88+
4. Adjusts timestamps to match the current day while maintaining the original time patterns
89+
5. Uploads the updated data to timeseries storage
90+
91+
## Results
92+
93+
- Seamless, continuous data pattern simulation
94+
- Preserved time intervals between data points
95+
- Consistent daily pattern reproduction
96+
- Automatic timestamp updates
97+
- Hands-free operation once configured
98+
99+
## Additional Resources
100+
101+
- [Industrial IoT - Insights Hub Documentation](https://documentation.mindsphere.io/resources/html/iot-hub/en-US/index.html)
102+
- [Visual Flow Creator Documentation](https://documentation.mindsphere.io/resources/html/visual-flow-creator/en-US/index.html)

0 commit comments

Comments
 (0)