@camstack/addon-post-analysis 1.2.666 → 1.2.668
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/{clip-model-registry-Uc_C1x81.mjs → clip-model-registry-BYJ5lbPi.mjs} +922 -509
- package/dist/{clip-model-registry-BIhYJRFt.js → clip-model-registry-DTC5bkf8.js} +922 -509
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-FkeZoNXj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DBEA3TPX.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DxtNkzmw.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CU7mDiJp.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-BBhgVoNl.mjs → hostInit-ChYqK-gn.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +460 -116
- package/dist/pipeline-analytics/index.mjs +460 -116
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CnYZAdvw.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Br6eWzp_.mjs +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as MAX_TRACK_RELATIONS, $i as zoneAnalyticsCapability, $n as buildViewerLink, $r as ncMediaPolicyError, $t as NcTemplatePreviewSchema, A as DETECTION_MACRO_CLASSES, Aa as record, Ai as ruleKindOf, An as TrackPlacementSchema, Ar as isAlarmControllableCap, At as NcAlarmConfigSchema, B as EXPORT_DENSE_MAX_RANGES, Bi as summarizeReview, Bn as alertEpisodeId, Br as isKnownTemplateVar, Bt as NcRuleSchema, C as COCO_TO_MACRO, Ca as boolean, Cn as SetTrackPurityResultSchema, Cr as ensureAlarmProfiles, Ct as NC_GROUPING_MIN_SEC, D as DEFAULT_DETAIL_CROP_CONVENTION, Da as number, Di as ruleBelongsToAlarm$1, Dn as TimelapseRuleInputSchema, Dr as failureContributionCapability, Dt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, E as CoverStateSchema, Ea as looseObject, Ei as ruleAutoTriggersAlarm, En as TRACK_RELATIONS_DEFAULT_LIMIT, Er as faceGalleryCapability, Et as NC_STATE_SUMMARY_SECTION_IDS, F as EMBEDDING_REQUIREMENTS_FAILED, Fa as union, Fi as startMoverUnderClearance, Fn as TrackSourceSchema, Fr as isDefaultAlarmProfileId, Ft as NcConditionDescriptorSchema, G as LabelAttributionSchema, Gi as systemEventFilterApplies, Gn as applyNonBlockingEdit, Gr as isScheduleActive, Gt as NcSnoozeInputSchema, H as FULL_IMAGE_BBOX, Hi as syncActiveAlarmProfileSettings, Hn as alertEpisodePayload, Hr as isMediaOwnerType, Ht as NcRuleUpdateInputSchema, I as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ia as unknown, Ii as storageOccupancyCapability, In as activateAlarmProfile, Ir as isDetectionMacroClass, It as NcConditionsSchema, J as LockStateSchema, Ji as templateCarriesSummary, Jn as assertTimelapseCadences, Jr as isVectorIndexDimConflict, Jt as NcStateSummarySectionIdSchema, K as ListTrackRelationsInputSchema, Ki as systemEventSummaryScheduleOf, Kn as applySecureOnArmEdit, Kr as isSystemDelivery, Kt as NcSnoozeSchema, L as EVENT_DENSITY_BATCH_MAX, La as DeviceType, Li as subKindsOf, Ln as addonWidgetsSourceCapability, Lr as isDrawableSubjectPath, Lt as NcRuleActionSchema, M as DeclaredDevices, Ma as string, Mi as secureActuationFor, Mn as TrackRelationKindSchema, Mr as isAlertEpisodeSeverity, Mt as NcAlarmSensorsInputSchema, N as DetectionSourceSchema, Na as templateLiteral, Ni as sensorRaisedOf, Nn as TrackRelationSchema, Nr as isAppLinkBase, Nt as NcAlarmSensorsSchema, O as DEFAULT_EVENT_COLOR, Oa as object, Oi as ruleDeviceCompatCapQueries, On as TimelapseRulePatchSchema, Or as gifDeriveSpeed, Ot as NC_TAXONOMY, P as EMBEDDING_MODEL_FAILED, Pa as tuple, Pi as servedTemplateVars, Pn as TrackSideSchema, Pr as isAudioClassName, Pt as NcAlarmSettingsPatchSchema, Q as MAX_TRACK_PURITIES, Qi as withSystemEventClasses, Qn as buildSubjectPath, Qr as memoizePinnedFfmpeg, Qt as NcTemplatePreviewInputSchema, R as EVENT_KIND_BY_CAP, Ra as errMsg, Ri as subjectPathSampleFromBox, Rn as alarmDeviceSecureOnArm, Rr as isEventKindLabelKey, Rt as NcRuleInputSchema, S as BucketAccumulator, Sa as array, Si as resolveNcMediaImage, Sn as SetTrackPurityInputSchema, Sr as encodeVectorBase64, St as NC_GROUPING_MAX_SEC, T as ClearTrackRelationResultSchema, Ta as literal, Ti as rootSupplyServes, Tn as TIMELAPSE_DENSE_FLOOR_SEC, Tr as evictionPolicyOfLocation, Tt as NC_SNOOZE_MAX_MINUTES, U as FailureCounters, Ui as systemEventDeliveryProblems, Un as applyBlockingEdit, Ur as isRetiredClearKey, Ut as NcScheduleSchema, V as FIRST_LEVEL_MACRO_CLASSES, Vi as sunTimes, Vn as alertEpisodeKind, Vr as isLabelSupplyStepId, Vt as NcRuleTargetSchema, W as LABEL_SUPPLY_MACRO, Wi as systemEventFamilyProblems, Wn as applyModeDelaysEdits, Wr as isRootSuppliableStepId, Wt as NcSharedSequenceSchema, X as MAX_BIRTH_DECISION_RECORDS, Xi as vectorDimFromBase64, Xn as audioModeOf, Xr as linkedStepOf, Xt as NcTaxonomySchema, Y as MAX_ARCHIVED_DEBUG_NOTES, Yi as templateVarsFor, Yn as audioMetricsCapability, Yr as kebabToCamel, Yt as NcSystemEventKindSchema, Z as MAX_BIRTH_LATENCY_PROXY_MS, Zi as viewerLinkBaseOf, Zn as buildEventKindDescriptor, Zr as mayWriteToLocation, Zt as NcTemplateDefaultSchema, _ as AlarmArmModeSchema, _a as nodePin, _i as resolveClipSearchMinScore, _n as SCENE_DEFAULT_QUIET_SECONDS, _t as NC_CONFIRM_DEFAULT_TIMEOUT_MS, a as CLIP_EMBEDDING_STEP_ID, aa as CAP_ADVANCE_FIELDS, ai as paintHex, an as RECORDING_EXPORT_MAX_READ_BYTES, ar as consumableLowPercentOf, at as NC_ALARM_DELAY_FIELDS, b as BaseDevice, ba as ZodObject, bi as resolveModeDelays, bn as SCENE_RESET_RECAPTURES, bt as NC_DEFAULT_SNOOZE_MINUTES, c as readClusterModelPinStrict, ca as RECORD_MAX_DATA_BYTES, cn as RetrainDismissedSchema, cr as createAlarmProfile, ct as NC_ALARM_SYSTEM_EVENT_KINDS, d as APPEARANCE_BIN_COUNT, da as customAction, di as plateGalleryCapability, dn as RetrainVerdictSubjectSchema, dr as derivePostTriggeredAction, dt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, ea as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, ei as normalizeNcAction, en as NcTemplateVarDescriptorSchema, er as bundledCamstack, et as MOTION_CLOSE_AFTER_MS, f as APPEARANCE_BLOCKS, fa as defineAddonMigrations, fi as projectSubjectPath, fn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, fr as deriveRecordingMode, ft as NC_CLIP_POST_ROLL_DEFAULT_SEC, g as ActionTargetResolver, ga as isDeviceScopedCap, gi as renameAlarmProfile, gn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, gr as deviceRemovalHookCapability, gt as NC_CONFIRM_DEFAULT_MAX_IMAGE_PX, h as AUDIO_MACRO_LABELS, ha as hydrateSchema, hi as readTimelapseGeneratedAt, hn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, hr as deviceAttentionKind, ht as NC_CONDITION_CATALOG, ia as BaseAddon, ii as occupancyScope, ir as consumableFormOf, it as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, j as DETECTION_PIPELINE_CAP_NAME, ja as strictObject, ji as sceneMonitorCapability, jn as TrackPuritySchema, jr as isAlertEpisodeOpen, jt as NcAlarmPostTriggeredActionSchema, k as DEFAULT_TIMELAPSE_PREVIEW_TEXT, ka as partialRecord, ki as ruleGroupingApplies, kn as TimelapseRuleSchema, kr as gifFromMp4Args, kt as NC_TEMPLATE_VARS, l as resolveClusterModelPin, la as RECORD_QUERY_MAX, li as pickFaceRescoreIntervalMinutes, ln as RetrainOriginSchema, lr as deleteAlarmProfile, lt as NC_ALARM_TRIGGERED_MAX_SEC, m as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, ma as defineRecordKinds, mi as readMotionTriggeredBy, mn as SCENE_DEFAULT_ANCHOR_THRESHOLD, mr as describeSystemEventFamilyProblem, mt as NC_CLIP_RETENTION_MAX_SEC, na as evaluateSensorEdge, ni as normalizeNcMediaPolicy, nn as OpsLogEntrySchema, nr as classifyRetrainReview, nt as MotionTriggeredBySchema, o as CLUSTER_MODEL_OWNER_ADDON_ID, oa as CamProfileSchema, oi as paletteResultSchema, on as RECORDING_SOURCE_CAMSTACK_ADDON, or as coreBlockIdFromAddonId, ot as NC_ALARM_DELAY_MAX_SEC, p as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, pa as defineCustomActions, pi as readDeviceStateFrom, pn as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, pr as describeSystemEventDeliveryProblem, pt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, q as ListTrackRelationsResultSchema, qi as systemEventSummarySplitOf, qn as armRemovalReconcile, qr as isSystemEventSummaryRule, qt as NcSnoozeSuppressedSchema, ra as isSourceCap, ri as notificationRulesCapability, rn as PackageLlmVerdictSchema, rr as cloneAlarmSettings, rt as NC_ALARM_DEFAULT_PROFILE_ID, s as FACE_EMBEDDING_STEP_ID, sa as InvalidRecordError, si as parseAlertEpisodePayload, sn as RebuildObjectEmbeddingsRefusalSchema, sr as cosineSimilarity$1, st as NC_ALARM_NOTIFY_FIELDS, t as BUILTIN_CLIP_MODELS, ta as canonicalHash, ti as normalizeNcCapTarget, tn as OPS_LOG_DEFAULT_LIMIT, tr as calendarEventLocalSpan, tt as MediaFileKindEnum, u as ACTION_TARGET_INVALIDATION_EVENTS, ua as createEvent, ui as pipelineAnalyticsCapability, un as RetrainStatusSchema, ur as deriveDetailCropRect, ut as NC_AUDIO_CONFIRM_HITS_DEFAULT, v as ArchivedDebugNoteSchema, vi as resolveDeliveryParams, vn as SCENE_DEFAULT_UNCOVERED_POLICY, vt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, w as ClearTrackRelationInputSchema, wa as discriminatedUnion, wi as retrainRevisionConflictMessage, wn as SetTrackRelationInputSchema, wr as eventKindLabel, wt as NC_SENSOR_TRANSITION_KINDS, x as BirthDecisionRecordSchema, xa as _enum, xi as resolveModeNotifyPolicy, xn as SceneMonitorSchema, xt as NC_GROUPING_DEFAULT_SEC, y as BIRTH_DECISION_DEFAULT_LIMIT, ya as sleep$1, yi as resolveLocationMode, yn as SCENE_DIVERGED, yr as embeddingRefusalOf, yt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, z as EVENT_OWNER_TYPES, za as EventCategory, zi as subjectPathSvgPoints, zn as alarmPanelCapability, zr as isEventOwnerType, zt as NcRulePatchSchema } from "../clip-model-registry-
|
|
1
|
+
import { $ as MAX_TRACK_RELATIONS, $i as zoneAnalyticsCapability, $n as buildViewerLink, $r as ncMediaPolicyError, $t as NcTemplatePreviewSchema, A as DETECTION_MACRO_CLASSES, Aa as record, Ai as ruleKindOf, An as TrackPlacementSchema, Ar as isAlarmControllableCap, At as NcAlarmConfigSchema, B as EXPORT_DENSE_MAX_RANGES, Bi as summarizeReview, Bn as alertEpisodeId, Br as isKnownTemplateVar, Bt as NcRuleSchema, C as COCO_TO_MACRO, Ca as boolean, Cn as SetTrackPurityResultSchema, Cr as ensureAlarmProfiles, Ct as NC_GROUPING_MIN_SEC, D as DEFAULT_DETAIL_CROP_CONVENTION, Da as number, Di as ruleBelongsToAlarm$1, Dn as TimelapseRuleInputSchema, Dr as failureContributionCapability, Dt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, E as CoverStateSchema, Ea as looseObject, Ei as ruleAutoTriggersAlarm, En as TRACK_RELATIONS_DEFAULT_LIMIT, Er as faceGalleryCapability, Et as NC_STATE_SUMMARY_SECTION_IDS, F as EMBEDDING_REQUIREMENTS_FAILED, Fa as union, Fi as startMoverUnderClearance, Fn as TrackSourceSchema, Fr as isDefaultAlarmProfileId, Ft as NcConditionDescriptorSchema, G as LabelAttributionSchema, Gi as systemEventFilterApplies, Gn as applyNonBlockingEdit, Gr as isScheduleActive, Gt as NcSnoozeInputSchema, H as FULL_IMAGE_BBOX, Hi as syncActiveAlarmProfileSettings, Hn as alertEpisodePayload, Hr as isMediaOwnerType, Ht as NcRuleUpdateInputSchema, I as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ia as unknown, Ii as storageOccupancyCapability, In as activateAlarmProfile, Ir as isDetectionMacroClass, It as NcConditionsSchema, J as LockStateSchema, Ji as templateCarriesSummary, Jn as assertTimelapseCadences, Jr as isVectorIndexDimConflict, Jt as NcStateSummarySectionIdSchema, K as ListTrackRelationsInputSchema, Ki as systemEventSummaryScheduleOf, Kn as applySecureOnArmEdit, Kr as isSystemDelivery, Kt as NcSnoozeSchema, L as EVENT_DENSITY_BATCH_MAX, La as DeviceType, Li as subKindsOf, Ln as addonWidgetsSourceCapability, Lr as isDrawableSubjectPath, Lt as NcRuleActionSchema, M as DeclaredDevices, Ma as string, Mi as secureActuationFor, Mn as TrackRelationKindSchema, Mr as isAlertEpisodeSeverity, Mt as NcAlarmSensorsInputSchema, N as DetectionSourceSchema, Na as templateLiteral, Ni as sensorRaisedOf, Nn as TrackRelationSchema, Nr as isAppLinkBase, Nt as NcAlarmSensorsSchema, O as DEFAULT_EVENT_COLOR, Oa as object, Oi as ruleDeviceCompatCapQueries, On as TimelapseRulePatchSchema, Or as gifDeriveSpeed, Ot as NC_TAXONOMY, P as EMBEDDING_MODEL_FAILED, Pa as tuple, Pi as servedTemplateVars, Pn as TrackSideSchema, Pr as isAudioClassName, Pt as NcAlarmSettingsPatchSchema, Q as MAX_TRACK_PURITIES, Qi as withSystemEventClasses, Qn as buildSubjectPath, Qr as memoizePinnedFfmpeg, Qt as NcTemplatePreviewInputSchema, R as EVENT_KIND_BY_CAP, Ra as errMsg, Ri as subjectPathSampleFromBox, Rn as alarmDeviceSecureOnArm, Rr as isEventKindLabelKey, Rt as NcRuleInputSchema, S as BucketAccumulator, Sa as array, Si as resolveNcMediaImage, Sn as SetTrackPurityInputSchema, Sr as encodeVectorBase64, St as NC_GROUPING_MAX_SEC, T as ClearTrackRelationResultSchema, Ta as literal, Ti as rootSupplyServes, Tn as TIMELAPSE_DENSE_FLOOR_SEC, Tr as evictionPolicyOfLocation, Tt as NC_SNOOZE_MAX_MINUTES, U as FailureCounters, Ui as systemEventDeliveryProblems, Un as applyBlockingEdit, Ur as isRetiredClearKey, Ut as NcScheduleSchema, V as FIRST_LEVEL_MACRO_CLASSES, Vi as sunTimes, Vn as alertEpisodeKind, Vr as isLabelSupplyStepId, Vt as NcRuleTargetSchema, W as LABEL_SUPPLY_MACRO, Wi as systemEventFamilyProblems, Wn as applyModeDelaysEdits, Wr as isRootSuppliableStepId, Wt as NcSharedSequenceSchema, X as MAX_BIRTH_DECISION_RECORDS, Xi as vectorDimFromBase64, Xn as audioModeOf, Xr as linkedStepOf, Xt as NcTaxonomySchema, Y as MAX_ARCHIVED_DEBUG_NOTES, Yi as templateVarsFor, Yn as audioMetricsCapability, Yr as kebabToCamel, Yt as NcSystemEventKindSchema, Z as MAX_BIRTH_LATENCY_PROXY_MS, Zi as viewerLinkBaseOf, Zn as buildEventKindDescriptor, Zr as mayWriteToLocation, Zt as NcTemplateDefaultSchema, _ as AlarmArmModeSchema, _a as nodePin, _i as resolveClipSearchMinScore, _n as SCENE_DEFAULT_QUIET_SECONDS, _t as NC_CONFIRM_DEFAULT_TIMEOUT_MS, a as CLIP_EMBEDDING_STEP_ID, aa as CAP_ADVANCE_FIELDS, ai as paintHex, an as RECORDING_EXPORT_MAX_READ_BYTES, ar as consumableLowPercentOf, at as NC_ALARM_DELAY_FIELDS, b as BaseDevice, ba as ZodObject, bi as resolveModeDelays, bn as SCENE_RESET_RECAPTURES, bt as NC_DEFAULT_SNOOZE_MINUTES, c as readClusterModelPinStrict, ca as RECORD_MAX_DATA_BYTES, cn as RetrainDismissedSchema, cr as createAlarmProfile, ct as NC_ALARM_SYSTEM_EVENT_KINDS, d as APPEARANCE_BIN_COUNT, da as customAction, di as plateGalleryCapability, dn as RetrainVerdictSubjectSchema, dr as derivePostTriggeredAction, dt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, ea as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, ei as normalizeNcAction, en as NcTemplateVarDescriptorSchema, er as bundledCamstack, et as MOTION_CLOSE_AFTER_MS, f as APPEARANCE_BLOCKS, fa as defineAddonMigrations, fi as projectSubjectPath, fn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, fr as deriveRecordingMode, ft as NC_CLIP_POST_ROLL_DEFAULT_SEC, g as ActionTargetResolver, ga as isDeviceScopedCap, gi as renameAlarmProfile, gn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, gr as deviceRemovalHookCapability, gt as NC_CONFIRM_DEFAULT_MAX_IMAGE_PX, h as AUDIO_MACRO_LABELS, ha as hydrateSchema, hi as readTimelapseGeneratedAt, hn as SCENE_DEFAULT_CHECK_INTERVAL_SEC, hr as deviceAttentionKind, ht as NC_CONDITION_CATALOG, ia as BaseAddon, ii as occupancyScope, ir as consumableFormOf, it as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, j as DETECTION_PIPELINE_CAP_NAME, ja as strictObject, ji as sceneMonitorCapability, jn as TrackPuritySchema, jr as isAlertEpisodeOpen, jt as NcAlarmPostTriggeredActionSchema, k as DEFAULT_TIMELAPSE_PREVIEW_TEXT, ka as partialRecord, ki as ruleGroupingApplies, kn as TimelapseRuleSchema, kr as gifFromMp4Args, kt as NC_TEMPLATE_VARS, l as resolveClusterModelPin, la as RECORD_QUERY_MAX, li as pickFaceRescoreIntervalMinutes, ln as RetrainOriginSchema, lr as deleteAlarmProfile, lt as NC_ALARM_TRIGGERED_MAX_SEC, m as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, ma as defineRecordKinds, mi as readMotionTriggeredBy, mn as SCENE_DEFAULT_ANCHOR_THRESHOLD, mr as describeSystemEventFamilyProblem, mt as NC_CLIP_RETENTION_MAX_SEC, na as evaluateSensorEdge, ni as normalizeNcMediaPolicy, nn as OpsLogEntrySchema, nr as classifyRetrainReview, nt as MotionTriggeredBySchema, o as CLUSTER_MODEL_OWNER_ADDON_ID, oa as CamProfileSchema, oi as paletteResultSchema, on as RECORDING_SOURCE_CAMSTACK_ADDON, or as coreBlockIdFromAddonId, ot as NC_ALARM_DELAY_MAX_SEC, p as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, pa as defineCustomActions, pi as readDeviceStateFrom, pn as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, pr as describeSystemEventDeliveryProblem, pt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, q as ListTrackRelationsResultSchema, qi as systemEventSummarySplitOf, qn as armRemovalReconcile, qr as isSystemEventSummaryRule, qt as NcSnoozeSuppressedSchema, ra as isSourceCap, ri as notificationRulesCapability, rn as PackageLlmVerdictSchema, rr as cloneAlarmSettings, rt as NC_ALARM_DEFAULT_PROFILE_ID, s as FACE_EMBEDDING_STEP_ID, sa as InvalidRecordError, si as parseAlertEpisodePayload, sn as RebuildObjectEmbeddingsRefusalSchema, sr as cosineSimilarity$1, st as NC_ALARM_NOTIFY_FIELDS, t as BUILTIN_CLIP_MODELS, ta as canonicalHash, ti as normalizeNcCapTarget, tn as OPS_LOG_DEFAULT_LIMIT, tr as calendarEventLocalSpan, tt as MediaFileKindEnum, u as ACTION_TARGET_INVALIDATION_EVENTS, ua as createEvent, ui as pipelineAnalyticsCapability, un as RetrainStatusSchema, ur as deriveDetailCropRect, ut as NC_AUDIO_CONFIRM_HITS_DEFAULT, v as ArchivedDebugNoteSchema, vi as resolveDeliveryParams, vn as SCENE_DEFAULT_UNCOVERED_POLICY, vt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, w as ClearTrackRelationInputSchema, wa as discriminatedUnion, wi as retrainRevisionConflictMessage, wn as SetTrackRelationInputSchema, wr as eventKindLabel, wt as NC_SENSOR_TRANSITION_KINDS, x as BirthDecisionRecordSchema, xa as _enum, xi as resolveModeNotifyPolicy, xn as SceneMonitorSchema, xt as NC_GROUPING_DEFAULT_SEC, y as BIRTH_DECISION_DEFAULT_LIMIT, ya as sleep$1, yi as resolveLocationMode, yn as SCENE_DIVERGED, yr as embeddingRefusalOf, yt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, z as EVENT_OWNER_TYPES, za as EventCategory, zi as subjectPathSvgPoints, zn as alarmPanelCapability, zr as isEventOwnerType, zt as NcRulePatchSchema } from "../clip-model-registry-BYJ5lbPi.mjs";
|
|
2
2
|
import { t as __exportAll } from "../embedding-encoder/index.mjs";
|
|
3
3
|
import * as fs$1 from "node:fs";
|
|
4
4
|
import { createWriteStream, promises } from "node:fs";
|
|
@@ -59659,6 +59659,140 @@ async function promoteWithStill(input) {
|
|
|
59659
59659
|
});
|
|
59660
59660
|
}
|
|
59661
59661
|
//#endregion
|
|
59662
|
+
//#region src/pipeline-analytics/pipeline/key-frame-persist.ts
|
|
59663
|
+
/**
|
|
59664
|
+
* A box is written only when it can be USED — a degenerate rectangle, or one
|
|
59665
|
+
* measured on a degenerate frame, says nothing and would read back as a box at
|
|
59666
|
+
* the origin. Absent is the honest answer; the reader then pairs a snapshot,
|
|
59667
|
+
* exactly as it did before D510.
|
|
59668
|
+
*
|
|
59669
|
+
* Its result is spread into BOTH writes: the small companion is derived from
|
|
59670
|
+
* the very bytes of the native one, so it is the same scene at the same
|
|
59671
|
+
* instant and the box maps into it by ratio like any other scale of the frame.
|
|
59672
|
+
* A box on one row and not the other would make the summary's answer depend on
|
|
59673
|
+
* which row a reader happened to pick.
|
|
59674
|
+
*/
|
|
59675
|
+
function isStatableSubject(subject) {
|
|
59676
|
+
if (subject === void 0) return false;
|
|
59677
|
+
return subject.w > 0 && subject.h > 0 && subject.frameWidth > 0 && subject.frameHeight > 0;
|
|
59678
|
+
}
|
|
59679
|
+
/**
|
|
59680
|
+
* Read, derive and store one track's key frame + its web companion.
|
|
59681
|
+
*
|
|
59682
|
+
* PARCEL-OR-NOTHING: no parcel writes nothing and the caller's bounded retry
|
|
59683
|
+
* parks a later frame. The `keyFrame` write lands FIRST and its media id (D482)
|
|
59684
|
+
* is what the outcome carries — a `keyFrameSmall` failure afterwards must not
|
|
59685
|
+
* re-arm a retry that would re-shoot a key frame the rebuild can already read.
|
|
59686
|
+
*/
|
|
59687
|
+
async function persistTrackKeyFrame(deps, input) {
|
|
59688
|
+
const { deviceId, trackId, retry } = input;
|
|
59689
|
+
const drop = {
|
|
59690
|
+
tags: { deviceId },
|
|
59691
|
+
meta: {
|
|
59692
|
+
trackId,
|
|
59693
|
+
retry
|
|
59694
|
+
}
|
|
59695
|
+
};
|
|
59696
|
+
try {
|
|
59697
|
+
const parcel = await deps.fetchParkedKeyFrame(deviceId, trackId);
|
|
59698
|
+
if (parcel === null || parcel.jpeg.byteLength === 0) {
|
|
59699
|
+
deps.logger.error("key-frame parcel missing — nothing to write, retry parks a later frame", { ...drop });
|
|
59700
|
+
return { kind: "parcel-missing" };
|
|
59701
|
+
}
|
|
59702
|
+
const subjectBox = isStatableSubject(parcel.subject) ? { subjectBox: parcel.subject } : {};
|
|
59703
|
+
const keyFrameMediaId = await deps.media.putReplacing({
|
|
59704
|
+
deviceId,
|
|
59705
|
+
ownerKind: "track",
|
|
59706
|
+
ownerId: trackId,
|
|
59707
|
+
kind: "keyFrame",
|
|
59708
|
+
timestamp: parcel.timestamp,
|
|
59709
|
+
data: parcel.jpeg,
|
|
59710
|
+
...subjectBox
|
|
59711
|
+
});
|
|
59712
|
+
try {
|
|
59713
|
+
const keyFrameSmall = await deps.deriveSmall(parcel.jpeg);
|
|
59714
|
+
await deps.media.putReplacing({
|
|
59715
|
+
deviceId,
|
|
59716
|
+
ownerKind: "track",
|
|
59717
|
+
ownerId: trackId,
|
|
59718
|
+
kind: "keyFrameSmall",
|
|
59719
|
+
timestamp: parcel.timestamp,
|
|
59720
|
+
data: keyFrameSmall,
|
|
59721
|
+
...subjectBox
|
|
59722
|
+
});
|
|
59723
|
+
} catch (err) {
|
|
59724
|
+
deps.logger.warn("keyFrameSmall write failed — the native keyFrame is stored", {
|
|
59725
|
+
...drop,
|
|
59726
|
+
meta: {
|
|
59727
|
+
...drop.meta,
|
|
59728
|
+
nodeId: parcel.nodeId,
|
|
59729
|
+
error: errMsg(err)
|
|
59730
|
+
}
|
|
59731
|
+
});
|
|
59732
|
+
}
|
|
59733
|
+
deps.logger.debug("key frame written from the parked parcel", {
|
|
59734
|
+
...drop,
|
|
59735
|
+
meta: {
|
|
59736
|
+
...drop.meta,
|
|
59737
|
+
nodeId: parcel.nodeId,
|
|
59738
|
+
width: parcel.width,
|
|
59739
|
+
height: parcel.height,
|
|
59740
|
+
bytes: parcel.jpeg.byteLength,
|
|
59741
|
+
parkedTimestamp: parcel.timestamp
|
|
59742
|
+
}
|
|
59743
|
+
});
|
|
59744
|
+
return {
|
|
59745
|
+
kind: "landed",
|
|
59746
|
+
keyFrameMediaId
|
|
59747
|
+
};
|
|
59748
|
+
} catch (err) {
|
|
59749
|
+
const error = errMsg(err);
|
|
59750
|
+
deps.logger.warn("key-frame write failed", {
|
|
59751
|
+
...drop,
|
|
59752
|
+
meta: {
|
|
59753
|
+
...drop.meta,
|
|
59754
|
+
error
|
|
59755
|
+
}
|
|
59756
|
+
});
|
|
59757
|
+
return {
|
|
59758
|
+
kind: "error",
|
|
59759
|
+
error
|
|
59760
|
+
};
|
|
59761
|
+
}
|
|
59762
|
+
}
|
|
59763
|
+
/**
|
|
59764
|
+
* Write one parked frame under an OBJECT event (`object:<id>`), once.
|
|
59765
|
+
*
|
|
59766
|
+
* A package delivery has no track row owning a key frame, and the notification
|
|
59767
|
+
* ladder reads only `track:` and `object:` owners — so without this the
|
|
59768
|
+
* delivery ships text-only. `null` = no parcel to write (said at the caller).
|
|
59769
|
+
* `putReplacing` makes a repeat the same row, never a second one.
|
|
59770
|
+
*/
|
|
59771
|
+
async function persistObjectFrame(deps, input) {
|
|
59772
|
+
const { deviceId, trackId, objectId, timestamp } = input;
|
|
59773
|
+
const parcel = await deps.fetchParkedKeyFrame(deviceId, trackId);
|
|
59774
|
+
if (parcel === null || parcel.jpeg.byteLength === 0) {
|
|
59775
|
+
deps.logger.warn("object frame parcel missing — nothing to write", {
|
|
59776
|
+
tags: { deviceId },
|
|
59777
|
+
meta: {
|
|
59778
|
+
trackId,
|
|
59779
|
+
objectId
|
|
59780
|
+
}
|
|
59781
|
+
});
|
|
59782
|
+
return null;
|
|
59783
|
+
}
|
|
59784
|
+
const subjectBox = isStatableSubject(parcel.subject) ? { subjectBox: parcel.subject } : {};
|
|
59785
|
+
return deps.media.putReplacing({
|
|
59786
|
+
deviceId,
|
|
59787
|
+
ownerKind: "object",
|
|
59788
|
+
ownerId: objectId,
|
|
59789
|
+
kind: "keyFrame",
|
|
59790
|
+
timestamp,
|
|
59791
|
+
data: parcel.jpeg,
|
|
59792
|
+
...subjectBox
|
|
59793
|
+
});
|
|
59794
|
+
}
|
|
59795
|
+
//#endregion
|
|
59662
59796
|
//#region src/pipeline-analytics/pipeline/person-over-vehicle.ts
|
|
59663
59797
|
/**
|
|
59664
59798
|
* How much of the PERSON box must sit inside a vehicle box to be counted.
|
|
@@ -69040,10 +69174,18 @@ function applianceCycleOf(subject) {
|
|
|
69040
69174
|
//#region src/notification-center/appliance-cycle-runs.ts
|
|
69041
69175
|
var CYCLE_FACTS_WAIT_MS = 3e3;
|
|
69042
69176
|
var CYCLE_FACTS_POLL_MS = 250;
|
|
69043
|
-
/** A closed run belongs to this finish when it ended within this much
|
|
69177
|
+
/** A closed run belongs to this finish when it ended within this much AFTER it. */
|
|
69044
69178
|
var CYCLE_RUN_MATCH_MS = 10 * 6e4;
|
|
69179
|
+
/**
|
|
69180
|
+
* ... or up to this long BEFORE it: a run ends at the last real active instant
|
|
69181
|
+
* (the start of the pending stop), and the finish is announced one stop dwell
|
|
69182
|
+
* later - the longest a stop dwell is proposed is 20 minutes.
|
|
69183
|
+
*/
|
|
69184
|
+
var CYCLE_RUN_END_LAG_MS = 30 * 6e4;
|
|
69045
69185
|
function factsOfClosed(run, finishedAtMs) {
|
|
69046
|
-
if (run.endedAt === null
|
|
69186
|
+
if (run.endedAt === null) return NC_UNKNOWN_CYCLE_FACTS;
|
|
69187
|
+
const lag = finishedAtMs - run.endedAt;
|
|
69188
|
+
if (lag > CYCLE_RUN_END_LAG_MS || -lag > CYCLE_RUN_MATCH_MS) return NC_UNKNOWN_CYCLE_FACTS;
|
|
69047
69189
|
return {
|
|
69048
69190
|
durationMs: run.durationMs,
|
|
69049
69191
|
energyKwh: run.detail.energyKwh
|
|
@@ -71066,6 +71208,12 @@ Object.freeze({
|
|
|
71066
71208
|
"idleStopMinutes": 30
|
|
71067
71209
|
} } }
|
|
71068
71210
|
},
|
|
71211
|
+
"media-player": {
|
|
71212
|
+
"channelDown": { "steps": 1 },
|
|
71213
|
+
"channelUp": { "steps": 1 },
|
|
71214
|
+
"volumeDown": { "steps": 1 },
|
|
71215
|
+
"volumeUp": { "steps": 1 }
|
|
71216
|
+
},
|
|
71069
71217
|
"mqtt-broker": { "startEmbeddedBroker": {
|
|
71070
71218
|
"port": 1883,
|
|
71071
71219
|
"allowAnonymous": false
|
|
@@ -71309,6 +71457,7 @@ Object.freeze({
|
|
|
71309
71457
|
"device-export": [
|
|
71310
71458
|
"listExposedDevices",
|
|
71311
71459
|
"listExposedEntities",
|
|
71460
|
+
"listInstances",
|
|
71312
71461
|
"listSupportedDeviceKinds",
|
|
71313
71462
|
"listSupportedEntityKinds"
|
|
71314
71463
|
],
|
|
@@ -71560,6 +71709,15 @@ var WORD_LEVEL_FIELD = {
|
|
|
71560
71709
|
*/
|
|
71561
71710
|
var BOOLEAN_LEVEL_FIELD = { "running-state": "running" };
|
|
71562
71711
|
/**
|
|
71712
|
+
* The device-history series key of a level cap's boolean — `cap:<cap>.<field>`,
|
|
71713
|
+
* the shape of `capSeriesKey` (system builtin, not importable from an addon;
|
|
71714
|
+
* the wiring spec pins the literal). `null` for a cap with no boolean level.
|
|
71715
|
+
*/
|
|
71716
|
+
function levelSeriesKey(capName) {
|
|
71717
|
+
const field = BOOLEAN_LEVEL_FIELD[capName];
|
|
71718
|
+
return field === void 0 ? null : `cap:${capName}.${field}`;
|
|
71719
|
+
}
|
|
71720
|
+
/**
|
|
71563
71721
|
* Caps whose level is a WORD with NO change stamp: cap → field. `enum-sensor`
|
|
71564
71722
|
* carries `{ value, lastFetchedAt }`, and `lastFetchedAt` moves on every
|
|
71565
71723
|
* provider refresh, so it says nothing about when the word changed. Gated by
|
|
@@ -71586,6 +71744,7 @@ var WORD_LEVEL_INACTIVE = {
|
|
|
71586
71744
|
* post-analysis runner, D28).
|
|
71587
71745
|
*/
|
|
71588
71746
|
var ADVANCE_FIELD = CAP_ADVANCE_FIELDS;
|
|
71747
|
+
var DEFAULT_SEED_WAIT_MS = 2e3;
|
|
71589
71748
|
/** Default drop-summary window: one line per device per ten minutes, at most. */
|
|
71590
71749
|
var DEFAULT_DROP_SUMMARY_WINDOW_MS = 6e5;
|
|
71591
71750
|
var SensorTransitionGate = class {
|
|
@@ -71597,6 +71756,14 @@ var SensorTransitionGate = class {
|
|
|
71597
71756
|
lastStamps = /* @__PURE__ */ new Map();
|
|
71598
71757
|
/** Drops since the window opened, keyed by `${deviceId}:${capName}:${reason}`. */
|
|
71599
71758
|
drops = /* @__PURE__ */ new Map();
|
|
71759
|
+
/** Seed reads started, by key; a settled one stays so a seed is read once. */
|
|
71760
|
+
seeds = /* @__PURE__ */ new Map();
|
|
71761
|
+
seedsSettled = /* @__PURE__ */ new Set();
|
|
71762
|
+
/** Seeds whose wait ran out: decided as unseeded from then on. */
|
|
71763
|
+
seedsAbandoned = /* @__PURE__ */ new Set();
|
|
71764
|
+
readSeed;
|
|
71765
|
+
onSeedFailed;
|
|
71766
|
+
seedWaitMs;
|
|
71600
71767
|
windowStartedAt;
|
|
71601
71768
|
startedAtMs;
|
|
71602
71769
|
now;
|
|
@@ -71608,6 +71775,55 @@ var SensorTransitionGate = class {
|
|
|
71608
71775
|
this.freshnessMs = options.firstSightingFreshnessMs ?? DEFAULT_FIRST_SIGHTING_FRESHNESS_MS;
|
|
71609
71776
|
this.summaryWindowMs = options.summaryWindowMs ?? DEFAULT_DROP_SUMMARY_WINDOW_MS;
|
|
71610
71777
|
this.windowStartedAt = options.now();
|
|
71778
|
+
this.readSeed = options.readSeed;
|
|
71779
|
+
this.onSeedFailed = options.onSeedFailed;
|
|
71780
|
+
this.seedWaitMs = options.seedWaitMs ?? DEFAULT_SEED_WAIT_MS;
|
|
71781
|
+
}
|
|
71782
|
+
/**
|
|
71783
|
+
* {@link observe}, plus: a level cap's first boolean `false` whose persisted
|
|
71784
|
+
* prior is still being read waits for that read, bounded by `seedWaitMs`, and
|
|
71785
|
+
* is decided again. This is the only wait on the path, and it is on a read
|
|
71786
|
+
* that was started at the FIRST sighting of the device (a null at boot, long
|
|
71787
|
+
* before the boolean) — never one begun by the event itself unless the
|
|
71788
|
+
* boolean really is the first thing seen. A read that fails or times out
|
|
71789
|
+
* decides as unseeded, i.e. exactly as before the seed existed (D49).
|
|
71790
|
+
*/
|
|
71791
|
+
async observeSettled(deviceId, capName, slice) {
|
|
71792
|
+
const first = this.observe(deviceId, capName, slice);
|
|
71793
|
+
if (first.changed || first.reason !== "seed-pending") return first;
|
|
71794
|
+
const key = `${deviceId}:${capName}`;
|
|
71795
|
+
const pending = this.seeds.get(key);
|
|
71796
|
+
if (pending !== void 0) {
|
|
71797
|
+
let timer;
|
|
71798
|
+
const timeout = new Promise((resolve) => {
|
|
71799
|
+
timer = setTimeout(resolve, this.seedWaitMs);
|
|
71800
|
+
});
|
|
71801
|
+
await Promise.race([pending, timeout]);
|
|
71802
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
71803
|
+
if (!this.seedsSettled.has(key)) this.seedsAbandoned.add(key);
|
|
71804
|
+
}
|
|
71805
|
+
return this.observe(deviceId, capName, slice);
|
|
71806
|
+
}
|
|
71807
|
+
/** Start the one seed read of a level cap's key; never awaited here. */
|
|
71808
|
+
ensureSeed(deviceId, capName) {
|
|
71809
|
+
const read = this.readSeed;
|
|
71810
|
+
if (read === void 0) return;
|
|
71811
|
+
const key = `${deviceId}:${capName}`;
|
|
71812
|
+
if (this.seeds.has(key)) return;
|
|
71813
|
+
const settle = () => {
|
|
71814
|
+
this.seedsSettled.add(key);
|
|
71815
|
+
};
|
|
71816
|
+
const started = read(deviceId, capName).then((seed) => {
|
|
71817
|
+
if (seed !== null && !this.lastValues.has(key)) this.lastValues.set(key, seed.value);
|
|
71818
|
+
settle();
|
|
71819
|
+
}, (error) => {
|
|
71820
|
+
this.onSeedFailed?.(deviceId, capName, error);
|
|
71821
|
+
settle();
|
|
71822
|
+
});
|
|
71823
|
+
this.seeds.set(key, started);
|
|
71824
|
+
}
|
|
71825
|
+
seedPending(key) {
|
|
71826
|
+
return this.seeds.has(key) && !this.seedsSettled.has(key) && !this.seedsAbandoned.has(key);
|
|
71611
71827
|
}
|
|
71612
71828
|
/**
|
|
71613
71829
|
* Feed one `DeviceStateChanged` slice for a cap `EVENT_KIND_BY_CAP` maps.
|
|
@@ -71619,6 +71835,7 @@ var SensorTransitionGate = class {
|
|
|
71619
71835
|
* a boolean in either direction, or a word-level cap's word changing.
|
|
71620
71836
|
*/
|
|
71621
71837
|
observe(deviceId, capName, slice) {
|
|
71838
|
+
if (BOOLEAN_LEVEL_FIELD[capName] !== void 0) this.ensureSeed(deviceId, capName);
|
|
71622
71839
|
if (slice["lastChangedAt"] === 0) return this.drop(deviceId, capName, "cold-slice");
|
|
71623
71840
|
const unstampedField = UNSTAMPED_WORD_FIELD[capName];
|
|
71624
71841
|
if (unstampedField !== void 0) return this.observeUnstampedWord(deviceId, capName, slice, unstampedField);
|
|
@@ -71674,6 +71891,10 @@ var SensorTransitionGate = class {
|
|
|
71674
71891
|
if (typeof raw !== "boolean") return this.drop(deviceId, capName, "non-boolean-value");
|
|
71675
71892
|
const key = `${deviceId}:${capName}`;
|
|
71676
71893
|
const prior = this.lastValues.get(key);
|
|
71894
|
+
if (prior === void 0 && !raw && this.seedPending(key)) return {
|
|
71895
|
+
changed: false,
|
|
71896
|
+
reason: "seed-pending"
|
|
71897
|
+
};
|
|
71677
71898
|
this.lastValues.set(key, raw);
|
|
71678
71899
|
if (prior === void 0) {
|
|
71679
71900
|
if (!raw) return this.drop(deviceId, capName, "baseline-seeded-inactive");
|
|
@@ -85512,6 +85733,15 @@ function isLinkedStillId(id) {
|
|
|
85512
85733
|
var NC_LINKED_WAKE_CAPTURE_TIMEOUT_MS = 15e3;
|
|
85513
85734
|
var NC_LINKED_WAKE_POLL_MS = 1e3;
|
|
85514
85735
|
var NC_LINKED_WAKE_MIN_GAP_MS = 6e4;
|
|
85736
|
+
/**
|
|
85737
|
+
* D60 — a tile the freshness read calls stale is RE-POLLED, unforced, until the
|
|
85738
|
+
* wrapper hands back a frame from the event or this bound is spent. The wrapper
|
|
85739
|
+
* settles a soft miss with its old cached hit; one more ask, a moment later,
|
|
85740
|
+
* usually finds the refreshed one. The bound sits inside the dispatcher's still
|
|
85741
|
+
* deadline (`NC_STILL_WAIT_MS`, 3 s): the row waits for it through `pendingUntil`.
|
|
85742
|
+
*/
|
|
85743
|
+
var NC_LINKED_STALE_POLL_MS = 500;
|
|
85744
|
+
var NC_LINKED_STALE_MAX_POLLS = 5;
|
|
85515
85745
|
/** Per camera — the marker's own bound (`SENSOR_MARKER_SNAPSHOT_TIMEOUT_MS`). */
|
|
85516
85746
|
var SENSOR_LINKED_CAPTURE_TIMEOUT_MS = 2500;
|
|
85517
85747
|
/** The capture-free wrapper-state read, per camera. It runs IN PARALLEL with
|
|
@@ -85521,6 +85751,8 @@ var SENSOR_LINKED_CAPTURE_TIMEOUT_MS = 2500;
|
|
|
85521
85751
|
* photograph). A read that misses the bound or fails is UNKNOWN and keeps the
|
|
85522
85752
|
* tile (D49). */
|
|
85523
85753
|
var SENSOR_LINKED_STATE_READ_TIMEOUT_MS = SENSOR_LINKED_CAPTURE_TIMEOUT_MS;
|
|
85754
|
+
/** The battery-slice read behind the unknown-state wake: cheap, and bounded. */
|
|
85755
|
+
var SENSOR_LINKED_BATTERY_READ_TIMEOUT_MS = 1e3;
|
|
85524
85756
|
/** The one cache-only freshness read for the set — one hop, after the
|
|
85525
85757
|
* captures. A read that misses it keeps every tile and says `freshness
|
|
85526
85758
|
* unverified` (D49). */
|
|
@@ -85626,13 +85858,13 @@ var NcLinkedStillShelf = class {
|
|
|
85626
85858
|
startedAt,
|
|
85627
85859
|
options
|
|
85628
85860
|
};
|
|
85629
|
-
let
|
|
85861
|
+
let judged;
|
|
85630
85862
|
try {
|
|
85631
|
-
results = await Promise.all(stills.cameraIds.map((id) => this.captureOne(id, ctx)));
|
|
85863
|
+
const results = await Promise.all(stills.cameraIds.map((id) => this.captureOne(id, ctx)));
|
|
85864
|
+
judged = await this.repollStale(ctx, atMs, await this.judgeFreshness(stills.sensorId, results, atMs));
|
|
85632
85865
|
} finally {
|
|
85633
85866
|
this.pendingWakes.delete(setId);
|
|
85634
85867
|
}
|
|
85635
|
-
const judged = await this.judgeFreshness(stills.sensorId, results, atMs);
|
|
85636
85868
|
for (const r of judged) this.logTile(stills.sensorId, r);
|
|
85637
85869
|
const landed = judged.filter(isLandedTile);
|
|
85638
85870
|
const composed = await this.compose(stills.sensorId, landed, atMs);
|
|
@@ -85679,6 +85911,16 @@ var NcLinkedStillShelf = class {
|
|
|
85679
85911
|
if (verdict.reason === "waking" && ctx.options.wakeSleeping) return this.awaitWaking(cameraId, ctx);
|
|
85680
85912
|
if (verdict.reason === "unreachable" && ctx.options.wakeSleeping) return excluded("wake-skipped:unreachable");
|
|
85681
85913
|
if (verdict.reason !== null) return excluded(verdict.reason);
|
|
85914
|
+
if (verdict.unknown !== null && capture.outcome === "empty" && ctx.options.wakeSleeping && await this.isBatteryCamera(cameraId)) {
|
|
85915
|
+
this.deps.logger.info("linked camera state unknown and capture empty — waking as a battery camera", {
|
|
85916
|
+
tags: { deviceId: cameraId },
|
|
85917
|
+
meta: {
|
|
85918
|
+
sensorId: ctx.sensorId,
|
|
85919
|
+
stateUnknown: verdict.unknown
|
|
85920
|
+
}
|
|
85921
|
+
});
|
|
85922
|
+
return this.wakeOne(cameraId, ctx);
|
|
85923
|
+
}
|
|
85682
85924
|
return {
|
|
85683
85925
|
cameraId,
|
|
85684
85926
|
...capture,
|
|
@@ -85686,6 +85928,20 @@ var NcLinkedStillShelf = class {
|
|
|
85686
85928
|
tookMs: took()
|
|
85687
85929
|
};
|
|
85688
85930
|
}
|
|
85931
|
+
/** Only a camera KNOWN to be a battery camera is woken on an unknown state. */
|
|
85932
|
+
async isBatteryCamera(cameraId) {
|
|
85933
|
+
const read = this.deps.isBatteryCamera;
|
|
85934
|
+
if (read === void 0) return false;
|
|
85935
|
+
try {
|
|
85936
|
+
return await withTimeout$2(read(cameraId), SENSOR_LINKED_BATTERY_READ_TIMEOUT_MS, "battery read") === true;
|
|
85937
|
+
} catch (err) {
|
|
85938
|
+
this.deps.logger.warn("linked camera battery read failed — not woken on an unknown state", {
|
|
85939
|
+
tags: { deviceId: cameraId },
|
|
85940
|
+
meta: { error: String(err) }
|
|
85941
|
+
});
|
|
85942
|
+
return false;
|
|
85943
|
+
}
|
|
85944
|
+
}
|
|
85689
85945
|
/** D998: one forced capture, by the rule's leave, at most once per gap per camera. */
|
|
85690
85946
|
async wakeOne(cameraId, ctx) {
|
|
85691
85947
|
const took = () => this.deps.now() - ctx.startedAt;
|
|
@@ -85747,8 +86003,46 @@ var NcLinkedStillShelf = class {
|
|
|
85747
86003
|
};
|
|
85748
86004
|
}
|
|
85749
86005
|
markPending(ctx) {
|
|
85750
|
-
|
|
85751
|
-
|
|
86006
|
+
this.markPendingUntil(ctx.setId, ctx.startedAt + NC_LINKED_WAKE_CAPTURE_TIMEOUT_MS + NC_LINKED_WAKE_POLL_MS);
|
|
86007
|
+
}
|
|
86008
|
+
markPendingUntil(setId, until) {
|
|
86009
|
+
this.pendingWakes.set(setId, Math.max(this.pendingWakes.get(setId) ?? 0, until));
|
|
86010
|
+
}
|
|
86011
|
+
/**
|
|
86012
|
+
* D60: a `stale` tile asks again (unforced — a poll never wakes) until its
|
|
86013
|
+
* frame is from the event or the bound is spent; the row's still-wait is held
|
|
86014
|
+
* open meanwhile. A camera that never freshens stays `stale`, said on its line.
|
|
86015
|
+
*/
|
|
86016
|
+
async repollStale(ctx, atMs, judged) {
|
|
86017
|
+
let current = judged;
|
|
86018
|
+
if (!current.some((r) => r.outcome === "stale")) return current;
|
|
86019
|
+
this.markPendingUntil(ctx.setId, this.deps.now() + NC_LINKED_STALE_POLL_MS * 6);
|
|
86020
|
+
for (let i = 0; i < NC_LINKED_STALE_MAX_POLLS; i++) {
|
|
86021
|
+
const waiting = current.filter((r) => r.outcome === "stale").map((r) => r.cameraId);
|
|
86022
|
+
if (waiting.length === 0) break;
|
|
86023
|
+
await new Promise((resolve) => setTimeout(resolve, NC_LINKED_STALE_POLL_MS));
|
|
86024
|
+
const landedAgain = (await Promise.all(waiting.map(async (cameraId) => {
|
|
86025
|
+
const capture = await this.captureStill(cameraId, false, SENSOR_LINKED_CAPTURE_TIMEOUT_MS);
|
|
86026
|
+
return capture.outcome === "landed" && capture.jpeg !== void 0 ? {
|
|
86027
|
+
cameraId,
|
|
86028
|
+
outcome: "landed",
|
|
86029
|
+
jpeg: capture.jpeg,
|
|
86030
|
+
tookMs: this.deps.now() - ctx.startedAt
|
|
86031
|
+
} : null;
|
|
86032
|
+
}))).filter((r) => r !== null);
|
|
86033
|
+
if (landedAgain.length === 0) continue;
|
|
86034
|
+
const rejudged = await this.judgeFreshness(ctx.sensorId, landedAgain, atMs);
|
|
86035
|
+
const fresh = new Map(rejudged.filter((r) => r.outcome === "landed").map((r) => [r.cameraId, r]));
|
|
86036
|
+
current = current.map((r) => fresh.get(r.cameraId) ?? r);
|
|
86037
|
+
for (const cameraId of fresh.keys()) this.deps.logger.info("linked camera frame was stale — a re-poll brought one from the event", {
|
|
86038
|
+
tags: { deviceId: cameraId },
|
|
86039
|
+
meta: {
|
|
86040
|
+
sensorId: ctx.sensorId,
|
|
86041
|
+
polls: i + 1
|
|
86042
|
+
}
|
|
86043
|
+
});
|
|
86044
|
+
}
|
|
86045
|
+
return current;
|
|
85752
86046
|
}
|
|
85753
86047
|
/** A wake that brought nothing back names itself, not the generic `empty`. */
|
|
85754
86048
|
asWakeResult(capture) {
|
|
@@ -85817,9 +86111,17 @@ var NcLinkedStillShelf = class {
|
|
|
85817
86111
|
unknown: null
|
|
85818
86112
|
};
|
|
85819
86113
|
} catch (err) {
|
|
86114
|
+
const timedOut = err instanceof LinkedReadTimeout;
|
|
86115
|
+
this.deps.logger.warn("linked camera snapshot state read failed — state unknown", {
|
|
86116
|
+
tags: { deviceId: cameraId },
|
|
86117
|
+
meta: {
|
|
86118
|
+
error: String(err),
|
|
86119
|
+
timedOut
|
|
86120
|
+
}
|
|
86121
|
+
});
|
|
85820
86122
|
return {
|
|
85821
86123
|
reason: null,
|
|
85822
|
-
unknown:
|
|
86124
|
+
unknown: timedOut ? "timeout" : "error"
|
|
85823
86125
|
};
|
|
85824
86126
|
}
|
|
85825
86127
|
}
|
|
@@ -107461,6 +107763,7 @@ var NotificationCenter = class {
|
|
|
107461
107763
|
this.linkedStills = getSnapshot !== void 0 ? new NcLinkedStillShelf({
|
|
107462
107764
|
getSnapshot,
|
|
107463
107765
|
...deps.getSnapshotState !== void 0 ? { getSnapshotState: deps.getSnapshotState } : {},
|
|
107766
|
+
...deps.isBatteryCamera !== void 0 ? { isBatteryCamera: deps.isBatteryCamera } : {},
|
|
107464
107767
|
...deps.getFrameCapturedAt !== void 0 ? { getFrameCapturedAt: deps.getFrameCapturedAt } : {},
|
|
107465
107768
|
isOnline: (id) => this.deviceDirectory.get(id)?.online,
|
|
107466
107769
|
logger: this.logger.child("linked-stills"),
|
|
@@ -110232,6 +110535,7 @@ var BuildNotificationCenter = class extends BuildNotificationCenterBase {
|
|
|
110232
110535
|
now: () => Date.now()
|
|
110233
110536
|
}),
|
|
110234
110537
|
...buildLinkedSnapshotReads(api.snapshot),
|
|
110538
|
+
isBatteryCamera: async (deviceId) => await api.battery.getStatus.query({ deviceId }) !== null,
|
|
110235
110539
|
identityIdsByName: async () => {
|
|
110236
110540
|
const byName = /* @__PURE__ */ new Map();
|
|
110237
110541
|
const identities = await stores.identityStore.listIdentities();
|
|
@@ -114429,6 +114733,12 @@ function deliveredIdempotencyKey(entryId) {
|
|
|
114429
114733
|
function pickedUpIdempotencyKey(entryId) {
|
|
114430
114734
|
return `pa-pkg-${entryId}-pickedup`;
|
|
114431
114735
|
}
|
|
114736
|
+
/**
|
|
114737
|
+
* How long a delivery waits for its still to be written before it ships
|
|
114738
|
+
* without one. Under the notification still poll (`NC_STILL_WAIT_MS`, 3 s) so
|
|
114739
|
+
* a slow store never holds the alert longer than the dispatcher would.
|
|
114740
|
+
*/
|
|
114741
|
+
var PACKAGE_FRAME_PERSIST_BOUND_MS = 2e3;
|
|
114432
114742
|
var PackageDropDetector = class {
|
|
114433
114743
|
deps;
|
|
114434
114744
|
/** Per-device mirror of the last LOGGED value of the `packageDropEnabled`
|
|
@@ -114442,6 +114752,62 @@ var PackageDropDetector = class {
|
|
|
114442
114752
|
* LLM gate (D931). `null` means the delivery is dropped (no, or no yes).
|
|
114443
114753
|
* An empty object means the rule did not ask. A verdict is spread onto the row.
|
|
114444
114754
|
*/
|
|
114755
|
+
/**
|
|
114756
|
+
* The delivery's still, written once under `object:<rowId>` when the entry
|
|
114757
|
+
* had no key frame. Never throws and never waits past
|
|
114758
|
+
* {@link PACKAGE_FRAME_PERSIST_BOUND_MS}: a delivery without a picture still
|
|
114759
|
+
* ships, and says why (D391).
|
|
114760
|
+
*/
|
|
114761
|
+
async persistDeliveryStill(entry, rowId, timestamp) {
|
|
114762
|
+
const persist = this.deps.persistDeliveryFrame;
|
|
114763
|
+
if (persist === void 0) return void 0;
|
|
114764
|
+
const tags = { deviceId: entry.deviceId };
|
|
114765
|
+
const meta = {
|
|
114766
|
+
entryId: entry.id,
|
|
114767
|
+
rowId
|
|
114768
|
+
};
|
|
114769
|
+
let timer;
|
|
114770
|
+
try {
|
|
114771
|
+
const bound = new Promise((resolve) => {
|
|
114772
|
+
timer = setTimeout(() => resolve("timeout"), PACKAGE_FRAME_PERSIST_BOUND_MS);
|
|
114773
|
+
});
|
|
114774
|
+
const written = await Promise.race([persist({
|
|
114775
|
+
deviceId: entry.deviceId,
|
|
114776
|
+
trackId: entry.sourceTrackId ?? entry.id,
|
|
114777
|
+
rowId,
|
|
114778
|
+
timestamp
|
|
114779
|
+
}), bound]);
|
|
114780
|
+
if (written === "timeout") {
|
|
114781
|
+
this.deps.logger.warn("package delivery still not written in time — shipping without it", {
|
|
114782
|
+
tags,
|
|
114783
|
+
meta: {
|
|
114784
|
+
...meta,
|
|
114785
|
+
boundMs: PACKAGE_FRAME_PERSIST_BOUND_MS
|
|
114786
|
+
}
|
|
114787
|
+
});
|
|
114788
|
+
return;
|
|
114789
|
+
}
|
|
114790
|
+
if (written === null) {
|
|
114791
|
+
this.deps.logger.warn("package delivery has no frame to write — shipping without a still", {
|
|
114792
|
+
tags,
|
|
114793
|
+
meta
|
|
114794
|
+
});
|
|
114795
|
+
return;
|
|
114796
|
+
}
|
|
114797
|
+
return written;
|
|
114798
|
+
} catch (err) {
|
|
114799
|
+
this.deps.logger.warn("package delivery still write failed — shipping without it", {
|
|
114800
|
+
tags,
|
|
114801
|
+
meta: {
|
|
114802
|
+
...meta,
|
|
114803
|
+
error: errMsg(err)
|
|
114804
|
+
}
|
|
114805
|
+
});
|
|
114806
|
+
return;
|
|
114807
|
+
} finally {
|
|
114808
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
114809
|
+
}
|
|
114810
|
+
}
|
|
114445
114811
|
async llmFields(entry, rules, hitZones, tags) {
|
|
114446
114812
|
if (!rules.some((rule) => rule.confirmWithLlm === true && rule.zoneIds.some((id) => hitZones.includes(id)))) return {};
|
|
114447
114813
|
const confirm = this.deps.confirmPackage;
|
|
@@ -114703,6 +115069,7 @@ var PackageDropDetector = class {
|
|
|
114703
115069
|
});
|
|
114704
115070
|
return;
|
|
114705
115071
|
}
|
|
115072
|
+
const keyFrameMediaId = entry.keyFrameMediaId ?? await this.persistDeliveryStill(entry, rowId, rowTimestamp);
|
|
114706
115073
|
const ev = {
|
|
114707
115074
|
...draft,
|
|
114708
115075
|
id: rowId
|
|
@@ -114714,7 +115081,7 @@ var PackageDropDetector = class {
|
|
|
114714
115081
|
eventId: String(rowId),
|
|
114715
115082
|
className: entry.className,
|
|
114716
115083
|
zoneIds: hitZones,
|
|
114717
|
-
...
|
|
115084
|
+
...keyFrameMediaId !== void 0 ? { keyFrameMediaId } : {},
|
|
114718
115085
|
bbox: {
|
|
114719
115086
|
x: entry.bbox.x,
|
|
114720
115087
|
y: entry.bbox.y,
|
|
@@ -118277,6 +118644,7 @@ var BuildStores = class extends BuildStoresBase {
|
|
|
118277
118644
|
resolveSettings: (deviceId) => this.resolveDevicePackageDropSettings(deviceId),
|
|
118278
118645
|
resolveZoneMembershipMinOverlap: async (deviceId) => (await this.resolveDeviceTrackingSettings(deviceId)).zoneMembershipMinOverlap,
|
|
118279
118646
|
confirmPackage: (input) => this.deps.confirmPackage(input),
|
|
118647
|
+
persistDeliveryFrame: (request) => this.deps.persistPackageDeliveryFrame(request),
|
|
118280
118648
|
onLlmSilence: (edge) => {
|
|
118281
118649
|
const deviceId = edge.phase === "silent" ? edge.note.deviceId : edge.deviceId;
|
|
118282
118650
|
this.ctx.eventBus.emit({
|
|
@@ -120398,108 +120766,6 @@ async function ensureTrackHierarchyMedia(deps, input) {
|
|
|
120398
120766
|
await Promise.all(tasks);
|
|
120399
120767
|
}
|
|
120400
120768
|
//#endregion
|
|
120401
|
-
//#region src/pipeline-analytics/pipeline/key-frame-persist.ts
|
|
120402
|
-
/**
|
|
120403
|
-
* A box is written only when it can be USED — a degenerate rectangle, or one
|
|
120404
|
-
* measured on a degenerate frame, says nothing and would read back as a box at
|
|
120405
|
-
* the origin. Absent is the honest answer; the reader then pairs a snapshot,
|
|
120406
|
-
* exactly as it did before D510.
|
|
120407
|
-
*
|
|
120408
|
-
* Its result is spread into BOTH writes: the small companion is derived from
|
|
120409
|
-
* the very bytes of the native one, so it is the same scene at the same
|
|
120410
|
-
* instant and the box maps into it by ratio like any other scale of the frame.
|
|
120411
|
-
* A box on one row and not the other would make the summary's answer depend on
|
|
120412
|
-
* which row a reader happened to pick.
|
|
120413
|
-
*/
|
|
120414
|
-
function isStatableSubject(subject) {
|
|
120415
|
-
if (subject === void 0) return false;
|
|
120416
|
-
return subject.w > 0 && subject.h > 0 && subject.frameWidth > 0 && subject.frameHeight > 0;
|
|
120417
|
-
}
|
|
120418
|
-
/**
|
|
120419
|
-
* Read, derive and store one track's key frame + its web companion.
|
|
120420
|
-
*
|
|
120421
|
-
* PARCEL-OR-NOTHING: no parcel writes nothing and the caller's bounded retry
|
|
120422
|
-
* parks a later frame. The `keyFrame` write lands FIRST and its media id (D482)
|
|
120423
|
-
* is what the outcome carries — a `keyFrameSmall` failure afterwards must not
|
|
120424
|
-
* re-arm a retry that would re-shoot a key frame the rebuild can already read.
|
|
120425
|
-
*/
|
|
120426
|
-
async function persistTrackKeyFrame(deps, input) {
|
|
120427
|
-
const { deviceId, trackId, retry } = input;
|
|
120428
|
-
const drop = {
|
|
120429
|
-
tags: { deviceId },
|
|
120430
|
-
meta: {
|
|
120431
|
-
trackId,
|
|
120432
|
-
retry
|
|
120433
|
-
}
|
|
120434
|
-
};
|
|
120435
|
-
try {
|
|
120436
|
-
const parcel = await deps.fetchParkedKeyFrame(deviceId, trackId);
|
|
120437
|
-
if (parcel === null || parcel.jpeg.byteLength === 0) {
|
|
120438
|
-
deps.logger.error("key-frame parcel missing — nothing to write, retry parks a later frame", { ...drop });
|
|
120439
|
-
return { kind: "parcel-missing" };
|
|
120440
|
-
}
|
|
120441
|
-
const subjectBox = isStatableSubject(parcel.subject) ? { subjectBox: parcel.subject } : {};
|
|
120442
|
-
const keyFrameMediaId = await deps.media.putReplacing({
|
|
120443
|
-
deviceId,
|
|
120444
|
-
ownerKind: "track",
|
|
120445
|
-
ownerId: trackId,
|
|
120446
|
-
kind: "keyFrame",
|
|
120447
|
-
timestamp: parcel.timestamp,
|
|
120448
|
-
data: parcel.jpeg,
|
|
120449
|
-
...subjectBox
|
|
120450
|
-
});
|
|
120451
|
-
try {
|
|
120452
|
-
const keyFrameSmall = await deps.deriveSmall(parcel.jpeg);
|
|
120453
|
-
await deps.media.putReplacing({
|
|
120454
|
-
deviceId,
|
|
120455
|
-
ownerKind: "track",
|
|
120456
|
-
ownerId: trackId,
|
|
120457
|
-
kind: "keyFrameSmall",
|
|
120458
|
-
timestamp: parcel.timestamp,
|
|
120459
|
-
data: keyFrameSmall,
|
|
120460
|
-
...subjectBox
|
|
120461
|
-
});
|
|
120462
|
-
} catch (err) {
|
|
120463
|
-
deps.logger.warn("keyFrameSmall write failed — the native keyFrame is stored", {
|
|
120464
|
-
...drop,
|
|
120465
|
-
meta: {
|
|
120466
|
-
...drop.meta,
|
|
120467
|
-
nodeId: parcel.nodeId,
|
|
120468
|
-
error: errMsg(err)
|
|
120469
|
-
}
|
|
120470
|
-
});
|
|
120471
|
-
}
|
|
120472
|
-
deps.logger.debug("key frame written from the parked parcel", {
|
|
120473
|
-
...drop,
|
|
120474
|
-
meta: {
|
|
120475
|
-
...drop.meta,
|
|
120476
|
-
nodeId: parcel.nodeId,
|
|
120477
|
-
width: parcel.width,
|
|
120478
|
-
height: parcel.height,
|
|
120479
|
-
bytes: parcel.jpeg.byteLength,
|
|
120480
|
-
parkedTimestamp: parcel.timestamp
|
|
120481
|
-
}
|
|
120482
|
-
});
|
|
120483
|
-
return {
|
|
120484
|
-
kind: "landed",
|
|
120485
|
-
keyFrameMediaId
|
|
120486
|
-
};
|
|
120487
|
-
} catch (err) {
|
|
120488
|
-
const error = errMsg(err);
|
|
120489
|
-
deps.logger.warn("key-frame write failed", {
|
|
120490
|
-
...drop,
|
|
120491
|
-
meta: {
|
|
120492
|
-
...drop.meta,
|
|
120493
|
-
error
|
|
120494
|
-
}
|
|
120495
|
-
});
|
|
120496
|
-
return {
|
|
120497
|
-
kind: "error",
|
|
120498
|
-
error
|
|
120499
|
-
};
|
|
120500
|
-
}
|
|
120501
|
-
}
|
|
120502
|
-
//#endregion
|
|
120503
120769
|
//#region src/pipeline-analytics/pipeline/key-frame-retry.ts
|
|
120504
120770
|
/** Retry-path attempts allowed per track. The operator's number. */
|
|
120505
120771
|
var KEY_FRAME_MAX_RETRIES = 3;
|
|
@@ -122083,6 +122349,8 @@ var DEFAULT_ASSIST_MIN_SCORE = .3;
|
|
|
122083
122349
|
* cannot page the whole table into memory to build a manifest.
|
|
122084
122350
|
*/
|
|
122085
122351
|
var RETRAIN_EXPORT_MAX = 2e4;
|
|
122352
|
+
/** How far back a restart looks for a level cap's last persisted boolean. */
|
|
122353
|
+
var LEVEL_SEED_WINDOW_MS = 48 * 36e5;
|
|
122086
122354
|
/**
|
|
122087
122355
|
* Pipeline Analytics addon — subscribes to `PipelineInferenceResult` +
|
|
122088
122356
|
* `PipelineAudioInferenceResult` on the bus, refines raw detections
|
|
@@ -122358,7 +122626,15 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
122358
122626
|
*/
|
|
122359
122627
|
sensorTransitions = new SensorTransitionGate({
|
|
122360
122628
|
startedAtMs: Date.now(),
|
|
122361
|
-
now: () => Date.now()
|
|
122629
|
+
now: () => Date.now(),
|
|
122630
|
+
readSeed: (deviceId, capName) => this.readPersistedLevel(deviceId, capName),
|
|
122631
|
+
onSeedFailed: (deviceId, capName, error) => this.ctx.logger.warn("level seed read failed — gate starts unseeded", {
|
|
122632
|
+
tags: { deviceId },
|
|
122633
|
+
meta: {
|
|
122634
|
+
capName,
|
|
122635
|
+
error: errMsg(error)
|
|
122636
|
+
}
|
|
122637
|
+
})
|
|
122362
122638
|
});
|
|
122363
122639
|
/** `camera-index-unknown` drops, summarised per window — see the file. */
|
|
122364
122640
|
cameraIndexUnknownDrops = new CameraIndexUnknownDrops({ nowMs: Date.now() });
|
|
@@ -124170,6 +124446,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
124170
124446
|
this.packageDropDetector = value;
|
|
124171
124447
|
},
|
|
124172
124448
|
confirmPackage: (input) => this.confirmPackageDelivery(input),
|
|
124449
|
+
persistPackageDeliveryFrame: (request) => this.persistPackageDeliveryFrame(request),
|
|
124173
124450
|
stationaryEvidence: () => this.stationaryEvidence,
|
|
124174
124451
|
setStationaryEvidence: (value) => {
|
|
124175
124452
|
this.stationaryEvidence = value;
|
|
@@ -128325,6 +128602,44 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
128325
128602
|
via: "frame"
|
|
128326
128603
|
});
|
|
128327
128604
|
}
|
|
128605
|
+
/**
|
|
128606
|
+
* #383: a delivery whose entry had no key frame writes the source track's
|
|
128607
|
+
* parked frame under the object row it just created — the one owner the
|
|
128608
|
+
* notification ladder reads for a package event.
|
|
128609
|
+
*/
|
|
128610
|
+
async persistPackageDeliveryFrame(request) {
|
|
128611
|
+
const mediaStore = this.mediaStore;
|
|
128612
|
+
if (mediaStore === null) return null;
|
|
128613
|
+
return persistObjectFrame({
|
|
128614
|
+
fetchParkedKeyFrame: async (deviceId, trackId) => {
|
|
128615
|
+
const parcel = await this.mediaCapture.fetchParkedParcel(trackId, "keyFrame");
|
|
128616
|
+
if (parcel === null || parcel.info.deviceId !== deviceId) return null;
|
|
128617
|
+
const subject = parcel.info.subject;
|
|
128618
|
+
return {
|
|
128619
|
+
jpeg: parcel.jpeg,
|
|
128620
|
+
width: parcel.width,
|
|
128621
|
+
height: parcel.height,
|
|
128622
|
+
timestamp: parcel.timestamp,
|
|
128623
|
+
nodeId: parcel.info.nodeId,
|
|
128624
|
+
subject: {
|
|
128625
|
+
x: subject.bbox.x,
|
|
128626
|
+
y: subject.bbox.y,
|
|
128627
|
+
w: subject.bbox.w,
|
|
128628
|
+
h: subject.bbox.h,
|
|
128629
|
+
frameWidth: subject.frameWidth,
|
|
128630
|
+
frameHeight: subject.frameHeight
|
|
128631
|
+
}
|
|
128632
|
+
};
|
|
128633
|
+
},
|
|
128634
|
+
media: mediaStore,
|
|
128635
|
+
logger: this.ctx.logger
|
|
128636
|
+
}, {
|
|
128637
|
+
deviceId: request.deviceId,
|
|
128638
|
+
trackId: request.trackId,
|
|
128639
|
+
objectId: String(request.rowId),
|
|
128640
|
+
timestamp: request.timestamp
|
|
128641
|
+
});
|
|
128642
|
+
}
|
|
128328
128643
|
async confirmPackageDelivery(input) {
|
|
128329
128644
|
const crops = this.packageScene?.cropsFor(input.deviceId);
|
|
128330
128645
|
return confirmPackageWithLlm({
|
|
@@ -129326,7 +129641,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
129326
129641
|
const store = this.sensorEventStore;
|
|
129327
129642
|
const cache = this.linkedCamerasCache;
|
|
129328
129643
|
if (store === null || cache === null) return;
|
|
129329
|
-
if (!this.sensorSliceCarriedATransition(data)) return;
|
|
129644
|
+
if (!await this.sensorSliceCarriedATransition(data)) return;
|
|
129330
129645
|
const cameras = await resolveSensorNotificationCameras(cache, data).catch((err) => {
|
|
129331
129646
|
this.ctx.logger.debug("linked-camera resolution failed — evaluated per row", {
|
|
129332
129647
|
tags: { deviceId: data.deviceId },
|
|
@@ -129494,7 +129809,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
129494
129809
|
* The drops are SUMMARISED, never logged one by one: this path carries every
|
|
129495
129810
|
* camera's native `motion` slice at motion rate.
|
|
129496
129811
|
*/
|
|
129497
|
-
sensorSliceCarriedATransition(data) {
|
|
129812
|
+
async sensorSliceCarriedATransition(data) {
|
|
129498
129813
|
const slice = data.slice;
|
|
129499
129814
|
if (typeof slice !== "object" || slice === null || Array.isArray(slice)) {
|
|
129500
129815
|
this.ctx.logger.debug("sensor state change carried no slice — dropped", {
|
|
@@ -129503,7 +129818,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
129503
129818
|
});
|
|
129504
129819
|
return false;
|
|
129505
129820
|
}
|
|
129506
|
-
const verdict = this.sensorTransitions.
|
|
129821
|
+
const verdict = await this.sensorTransitions.observeSettled(data.deviceId, data.capName, { ...slice });
|
|
129507
129822
|
this.flushSensorTransitionDrops();
|
|
129508
129823
|
if (verdict.changed) {
|
|
129509
129824
|
const entries = Object.entries(slice);
|
|
@@ -129521,6 +129836,35 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
129521
129836
|
return verdict.changed;
|
|
129522
129837
|
}
|
|
129523
129838
|
/**
|
|
129839
|
+
* The last persisted boolean of a level cap, from device-history — the
|
|
129840
|
+
* gate's seed after a restart. Off the event path (the gate starts it at the
|
|
129841
|
+
* first sighting). A cap that declares no history field, or a series with no
|
|
129842
|
+
* point, answers `null`.
|
|
129843
|
+
*/
|
|
129844
|
+
async readPersistedLevel(deviceId, capName) {
|
|
129845
|
+
const key = levelSeriesKey(capName);
|
|
129846
|
+
if (key === null) return null;
|
|
129847
|
+
const to = Date.now();
|
|
129848
|
+
const result = await this.ctx.api.deviceHistory.query.query({
|
|
129849
|
+
deviceId,
|
|
129850
|
+
key,
|
|
129851
|
+
from: to - LEVEL_SEED_WINDOW_MS,
|
|
129852
|
+
to,
|
|
129853
|
+
resolution: "raw",
|
|
129854
|
+
maxPoints: 200
|
|
129855
|
+
});
|
|
129856
|
+
const latest = result.series.flatMap((s) => s.points).reduce((best, p) => best === null || p.t > best.t ? p : best, null);
|
|
129857
|
+
if (latest !== null && latest.last !== null) return {
|
|
129858
|
+
value: latest.last >= .5,
|
|
129859
|
+
since: latest.t
|
|
129860
|
+
};
|
|
129861
|
+
const held = result.series.flatMap((s) => s.before === null ? [] : [s.before]).reduce((best, b) => best === null || b.t > best.t ? b : best, null);
|
|
129862
|
+
return held !== null && held.value !== null ? {
|
|
129863
|
+
value: held.value >= .5,
|
|
129864
|
+
since: held.t
|
|
129865
|
+
} : null;
|
|
129866
|
+
}
|
|
129867
|
+
/**
|
|
129524
129868
|
* One `info` line per (device, cap, reason) per window, or none.
|
|
129525
129869
|
*
|
|
129526
129870
|
* A branch that drops work says so — but this one drops ~0.6 events/s
|