You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
By default, meter readings use `external_id` for upsert matching. However, when readings originate from ECP (End Customer Portal) and are later echoed back by the ERP system, duplicates can occur because:
2188
+
- ECP readings don't have an `external_id` initially
2189
+
- ERP often truncates timestamps to date precision, causing timestamp mismatches
2190
+
2191
+
The `reading_matching` option allows you to configure how incoming readings are matched against existing readings.
|`external_id`| Default. Match readings by `external_id` attribute (default behavior) |
2198
+
|`strict-date`| Match by meter_id + counter_id + direction + date (German timezone) |
2199
+
2200
+
**Configuration:**
2201
+
```json
2202
+
{
2203
+
"meter_readings": [
2204
+
{
2205
+
"reading_matching": "strict-date",
2206
+
"meter": { ... },
2207
+
"fields": [ ... ]
2208
+
}
2209
+
]
2210
+
}
2211
+
```
2212
+
2213
+
**`strict-date` Strategy Details:**
2214
+
2215
+
When using `strict-date`:
2216
+
1. Before creating a reading, the system looks up existing readings for the same meter_id + counter_id + direction on the same **German calendar day** (Europe/Berlin timezone)
2217
+
2. If a **single match** is found: The existing reading is updated with ERP data (including setting `external_id` for future syncs)
2218
+
3. If **multiple matches** are found: An error is logged and the operation is skipped (to avoid creating duplicates)
2219
+
4. If **no match** is found: A new reading is created normally
2220
+
2221
+
**Why German Timezone?**
2222
+
2223
+
ECP users in Germany submit readings that are stored with full timestamp precision. When the ERP echoes the reading back, it often truncates to date-only (e.g., `2025-01-15T00:00:00Z`). By comparing dates in German timezone:
2224
+
- A reading submitted at 23:30 CET on Jan 15 will match an ERP echo dated Jan 15
2225
+
- Timestamps across the UTC midnight boundary are handled correctly
2226
+
2227
+
**Example: ECP → ERP Roundtrip**
2228
+
2229
+
1. Customer submits reading via ECP at `2025-01-15T14:30:45.123Z` (15:30 German time)
2230
+
2. Reading is saved in metering-api without `external_id`
2231
+
3. ERP receives the reading and echoes it back with `timestamp: "2025-01-15T00:00:00Z"` and `external_id: "ERP-12345"`
2232
+
4. With `reading_matching: "strict-date"`:
2233
+
- System finds existing reading on Jan 15 (German date)
2234
+
- Updates it with ERP's `external_id`, `timestamp`, and `value`
| ERP sends same reading multiple times | All updates hit the same record |
2243
+
| ERP modifies value | Overwrites ECP value (ERP is source of truth) |
2244
+
| Reading only from ERP (no prior ECP) | Creates new reading normally |
2245
+
| Multiple readings on same date | Log error, skip to avoid duplicate |
2246
+
2247
+
**Complete Example:**
2248
+
2249
+
```json
2250
+
{
2251
+
"version": "2.0",
2252
+
"mapping": {
2253
+
"events": {
2254
+
"MeterReadingsChanged": {
2255
+
"meter_readings": [
2256
+
{
2257
+
"reading_matching": "strict-date",
2258
+
"jsonataExpression": "$.readings",
2259
+
"meter": {
2260
+
"unique_ids": [
2261
+
{
2262
+
"attribute": "external_id",
2263
+
"field": "meter_id"
2264
+
}
2265
+
]
2266
+
},
2267
+
"meter_counter": {
2268
+
"unique_ids": [
2269
+
{
2270
+
"attribute": "external_id",
2271
+
"field": "counter_id"
2272
+
}
2273
+
]
2274
+
},
2275
+
"fields": [
2276
+
{
2277
+
"attribute": "external_id",
2278
+
"field": "reading_id"
2279
+
},
2280
+
{
2281
+
"attribute": "timestamp",
2282
+
"field": "read_at"
2283
+
},
2284
+
{
2285
+
"attribute": "source",
2286
+
"constant": "ERP"
2287
+
},
2288
+
{
2289
+
"attribute": "value",
2290
+
"field": "reading_value"
2291
+
},
2292
+
{
2293
+
"attribute": "direction",
2294
+
"field": "direction"
2295
+
}
2296
+
]
2297
+
}
2298
+
]
2299
+
}
2300
+
}
2301
+
}
2302
+
}
2303
+
```
2304
+
2184
2305
## Array Attribute Operations
2185
2306
2186
2307
Regular array attributes (like `_tags`, custom array fields, etc.) support `_set`, `_append`, and `_append_all` operations. These work similarly to relation operations but for simple array values.
0 commit comments