@cepseudo/ngsi-ld 1.0.0

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.
Files changed (142) hide show
  1. package/README.md +425 -0
  2. package/dist/cache/entity_cache.d.ts +42 -0
  3. package/dist/cache/entity_cache.d.ts.map +1 -0
  4. package/dist/cache/entity_cache.js +93 -0
  5. package/dist/cache/entity_cache.js.map +1 -0
  6. package/dist/components/ngsi_ld_collector.d.ts +25 -0
  7. package/dist/components/ngsi_ld_collector.d.ts.map +1 -0
  8. package/dist/components/ngsi_ld_collector.js +13 -0
  9. package/dist/components/ngsi_ld_collector.js.map +1 -0
  10. package/dist/components/ngsi_ld_harvester.d.ts +25 -0
  11. package/dist/components/ngsi_ld_harvester.d.ts.map +1 -0
  12. package/dist/components/ngsi_ld_harvester.js +13 -0
  13. package/dist/components/ngsi_ld_harvester.js.map +1 -0
  14. package/dist/components/type_guards.d.ts +15 -0
  15. package/dist/components/type_guards.d.ts.map +1 -0
  16. package/dist/components/type_guards.js +25 -0
  17. package/dist/components/type_guards.js.map +1 -0
  18. package/dist/endpoints/attrs.d.ts +7 -0
  19. package/dist/endpoints/attrs.d.ts.map +1 -0
  20. package/dist/endpoints/attrs.js +37 -0
  21. package/dist/endpoints/attrs.js.map +1 -0
  22. package/dist/endpoints/entities.d.ts +9 -0
  23. package/dist/endpoints/entities.d.ts.map +1 -0
  24. package/dist/endpoints/entities.js +149 -0
  25. package/dist/endpoints/entities.js.map +1 -0
  26. package/dist/endpoints/subscriptions.d.ts +8 -0
  27. package/dist/endpoints/subscriptions.d.ts.map +1 -0
  28. package/dist/endpoints/subscriptions.js +109 -0
  29. package/dist/endpoints/subscriptions.js.map +1 -0
  30. package/dist/endpoints/types.d.ts +7 -0
  31. package/dist/endpoints/types.d.ts.map +1 -0
  32. package/dist/endpoints/types.js +45 -0
  33. package/dist/endpoints/types.js.map +1 -0
  34. package/dist/helpers/property.d.ts +33 -0
  35. package/dist/helpers/property.d.ts.map +1 -0
  36. package/dist/helpers/property.js +40 -0
  37. package/dist/helpers/property.js.map +1 -0
  38. package/dist/helpers/urn.d.ts +26 -0
  39. package/dist/helpers/urn.d.ts.map +1 -0
  40. package/dist/helpers/urn.js +30 -0
  41. package/dist/helpers/urn.js.map +1 -0
  42. package/dist/index.d.ts +22 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +19 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/models/agrifood/agri_parcel.d.ts +17 -0
  47. package/dist/models/agrifood/agri_parcel.d.ts.map +1 -0
  48. package/dist/models/agrifood/agri_parcel.js +27 -0
  49. package/dist/models/agrifood/agri_parcel.js.map +1 -0
  50. package/dist/models/agrifood/agri_soil_measurement.d.ts +17 -0
  51. package/dist/models/agrifood/agri_soil_measurement.d.ts.map +1 -0
  52. package/dist/models/agrifood/agri_soil_measurement.js +31 -0
  53. package/dist/models/agrifood/agri_soil_measurement.js.map +1 -0
  54. package/dist/models/agrifood/agri_weather_observed.d.ts +20 -0
  55. package/dist/models/agrifood/agri_weather_observed.d.ts.map +1 -0
  56. package/dist/models/agrifood/agri_weather_observed.js +34 -0
  57. package/dist/models/agrifood/agri_weather_observed.js.map +1 -0
  58. package/dist/models/device/device.d.ts +24 -0
  59. package/dist/models/device/device.d.ts.map +1 -0
  60. package/dist/models/device/device.js +39 -0
  61. package/dist/models/device/device.js.map +1 -0
  62. package/dist/models/device/device_measurement.d.ts +16 -0
  63. package/dist/models/device/device_measurement.d.ts.map +1 -0
  64. package/dist/models/device/device_measurement.js +34 -0
  65. package/dist/models/device/device_measurement.js.map +1 -0
  66. package/dist/models/environment/air_quality_observed.d.ts +22 -0
  67. package/dist/models/environment/air_quality_observed.d.ts.map +1 -0
  68. package/dist/models/environment/air_quality_observed.js +50 -0
  69. package/dist/models/environment/air_quality_observed.js.map +1 -0
  70. package/dist/models/environment/noise_level_observed.d.ts +17 -0
  71. package/dist/models/environment/noise_level_observed.d.ts.map +1 -0
  72. package/dist/models/environment/noise_level_observed.js +31 -0
  73. package/dist/models/environment/noise_level_observed.js.map +1 -0
  74. package/dist/models/environment/water_quality_observed.d.ts +20 -0
  75. package/dist/models/environment/water_quality_observed.d.ts.map +1 -0
  76. package/dist/models/environment/water_quality_observed.js +46 -0
  77. package/dist/models/environment/water_quality_observed.js.map +1 -0
  78. package/dist/models/environment/weather_observed.d.ts +19 -0
  79. package/dist/models/environment/weather_observed.d.ts.map +1 -0
  80. package/dist/models/environment/weather_observed.js +46 -0
  81. package/dist/models/environment/weather_observed.js.map +1 -0
  82. package/dist/models/index.d.ts +25 -0
  83. package/dist/models/index.d.ts.map +1 -0
  84. package/dist/models/index.js +17 -0
  85. package/dist/models/index.js.map +1 -0
  86. package/dist/models/smart_city/parking_spot.d.ts +14 -0
  87. package/dist/models/smart_city/parking_spot.d.ts.map +1 -0
  88. package/dist/models/smart_city/parking_spot.js +27 -0
  89. package/dist/models/smart_city/parking_spot.js.map +1 -0
  90. package/dist/models/smart_city/street_light.d.ts +16 -0
  91. package/dist/models/smart_city/street_light.d.ts.map +1 -0
  92. package/dist/models/smart_city/street_light.js +33 -0
  93. package/dist/models/smart_city/street_light.js.map +1 -0
  94. package/dist/models/smart_city/traffic_flow_observed.d.ts +19 -0
  95. package/dist/models/smart_city/traffic_flow_observed.d.ts.map +1 -0
  96. package/dist/models/smart_city/traffic_flow_observed.js +37 -0
  97. package/dist/models/smart_city/traffic_flow_observed.js.map +1 -0
  98. package/dist/notifications/notification_sender.d.ts +16 -0
  99. package/dist/notifications/notification_sender.d.ts.map +1 -0
  100. package/dist/notifications/notification_sender.js +70 -0
  101. package/dist/notifications/notification_sender.js.map +1 -0
  102. package/dist/notifications/notification_worker.d.ts +19 -0
  103. package/dist/notifications/notification_worker.d.ts.map +1 -0
  104. package/dist/notifications/notification_worker.js +65 -0
  105. package/dist/notifications/notification_worker.js.map +1 -0
  106. package/dist/plugin.d.ts +35 -0
  107. package/dist/plugin.d.ts.map +1 -0
  108. package/dist/plugin.js +113 -0
  109. package/dist/plugin.js.map +1 -0
  110. package/dist/subscriptions/q_parser.d.ts +42 -0
  111. package/dist/subscriptions/q_parser.d.ts.map +1 -0
  112. package/dist/subscriptions/q_parser.js +113 -0
  113. package/dist/subscriptions/q_parser.js.map +1 -0
  114. package/dist/subscriptions/subscription_cache.d.ts +46 -0
  115. package/dist/subscriptions/subscription_cache.d.ts.map +1 -0
  116. package/dist/subscriptions/subscription_cache.js +105 -0
  117. package/dist/subscriptions/subscription_cache.js.map +1 -0
  118. package/dist/subscriptions/subscription_matcher.d.ts +23 -0
  119. package/dist/subscriptions/subscription_matcher.d.ts.map +1 -0
  120. package/dist/subscriptions/subscription_matcher.js +84 -0
  121. package/dist/subscriptions/subscription_matcher.js.map +1 -0
  122. package/dist/subscriptions/subscription_store.d.ts +42 -0
  123. package/dist/subscriptions/subscription_store.d.ts.map +1 -0
  124. package/dist/subscriptions/subscription_store.js +189 -0
  125. package/dist/subscriptions/subscription_store.js.map +1 -0
  126. package/dist/types/context.d.ts +9 -0
  127. package/dist/types/context.d.ts.map +1 -0
  128. package/dist/types/context.js +5 -0
  129. package/dist/types/context.js.map +1 -0
  130. package/dist/types/entity.d.ts +46 -0
  131. package/dist/types/entity.d.ts.map +1 -0
  132. package/dist/types/entity.js +2 -0
  133. package/dist/types/entity.js.map +1 -0
  134. package/dist/types/notification.d.ts +22 -0
  135. package/dist/types/notification.d.ts.map +1 -0
  136. package/dist/types/notification.js +2 -0
  137. package/dist/types/notification.js.map +1 -0
  138. package/dist/types/subscription.d.ts +54 -0
  139. package/dist/types/subscription.d.ts.map +1 -0
  140. package/dist/types/subscription.js +2 -0
  141. package/dist/types/subscription.js.map +1 -0
  142. package/package.json +74 -0
@@ -0,0 +1,46 @@
1
+ import { property } from '../../helpers/property.js';
2
+ import { buildUrn } from '../../helpers/urn.js';
3
+ import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
4
+ /**
5
+ * Builds an NGSI-LD WeatherObserved entity.
6
+ */
7
+ export function buildWeatherObserved(attrs) {
8
+ const entity = {
9
+ id: buildUrn('WeatherObserved', attrs.localId),
10
+ type: 'WeatherObserved',
11
+ '@context': NGSI_LD_CORE_CONTEXT,
12
+ };
13
+ const observedAt = attrs.dateObserved;
14
+ if (attrs.dateObserved !== undefined) {
15
+ entity['dateObserved'] = property(attrs.dateObserved);
16
+ }
17
+ if (attrs.temperature !== undefined) {
18
+ entity['temperature'] = property(attrs.temperature, observedAt ? { observedAt } : undefined);
19
+ }
20
+ if (attrs.relativeHumidity !== undefined) {
21
+ entity['relativeHumidity'] = property(attrs.relativeHumidity, observedAt ? { observedAt } : undefined);
22
+ }
23
+ if (attrs.windSpeed !== undefined) {
24
+ entity['windSpeed'] = property(attrs.windSpeed, observedAt ? { observedAt } : undefined);
25
+ }
26
+ if (attrs.windDirection !== undefined) {
27
+ entity['windDirection'] = property(attrs.windDirection, observedAt ? { observedAt } : undefined);
28
+ }
29
+ if (attrs.atmosphericPressure !== undefined) {
30
+ entity['atmosphericPressure'] = property(attrs.atmosphericPressure, observedAt ? { observedAt } : undefined);
31
+ }
32
+ if (attrs.precipitation !== undefined) {
33
+ entity['precipitation'] = property(attrs.precipitation, observedAt ? { observedAt } : undefined);
34
+ }
35
+ if (attrs.snowHeight !== undefined) {
36
+ entity['snowHeight'] = property(attrs.snowHeight, observedAt ? { observedAt } : undefined);
37
+ }
38
+ if (attrs.visibility !== undefined) {
39
+ entity['visibility'] = property(attrs.visibility, observedAt ? { observedAt } : undefined);
40
+ }
41
+ if (attrs.weatherType !== undefined) {
42
+ entity['weatherType'] = property(attrs.weatherType);
43
+ }
44
+ return entity;
45
+ }
46
+ //# sourceMappingURL=weather_observed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weather_observed.js","sourceRoot":"","sources":["../../../src/models/environment/weather_observed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAgB7D;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACjE,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC;QAC9C,IAAI,EAAE,iBAAiB;QACvB,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAA;IAErC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAClI,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC5I,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IACtI,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAClJ,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IACtI,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAChI,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAChI,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,25 @@
1
+ export { buildAirQualityObserved } from './environment/air_quality_observed.js';
2
+ export type { AirQualityObservedAttributes } from './environment/air_quality_observed.js';
3
+ export { buildWeatherObserved } from './environment/weather_observed.js';
4
+ export type { WeatherObservedAttributes } from './environment/weather_observed.js';
5
+ export { buildWaterQualityObserved } from './environment/water_quality_observed.js';
6
+ export type { WaterQualityObservedAttributes } from './environment/water_quality_observed.js';
7
+ export { buildNoiseLevelObserved } from './environment/noise_level_observed.js';
8
+ export type { NoiseLevelObservedAttributes } from './environment/noise_level_observed.js';
9
+ export { buildStreetLight } from './smart_city/street_light.js';
10
+ export type { StreetLightAttributes } from './smart_city/street_light.js';
11
+ export { buildParkingSpot } from './smart_city/parking_spot.js';
12
+ export type { ParkingSpotAttributes } from './smart_city/parking_spot.js';
13
+ export { buildTrafficFlowObserved } from './smart_city/traffic_flow_observed.js';
14
+ export type { TrafficFlowObservedAttributes } from './smart_city/traffic_flow_observed.js';
15
+ export { buildAgriParcel } from './agrifood/agri_parcel.js';
16
+ export type { AgriParcelAttributes } from './agrifood/agri_parcel.js';
17
+ export { buildAgriSoilMeasurement } from './agrifood/agri_soil_measurement.js';
18
+ export type { AgriSoilMeasurementAttributes } from './agrifood/agri_soil_measurement.js';
19
+ export { buildAgriWeatherObserved } from './agrifood/agri_weather_observed.js';
20
+ export type { AgriWeatherObservedAttributes } from './agrifood/agri_weather_observed.js';
21
+ export { buildDevice } from './device/device.js';
22
+ export type { DeviceAttributes } from './device/device.js';
23
+ export { buildDeviceMeasurement } from './device/device_measurement.js';
24
+ export type { DeviceMeasurementAttributes } from './device/device_measurement.js';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAA;AAEzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAElF,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AACnF,YAAY,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAA;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAA;AAGzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAChF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAA;AAG1F,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,YAAY,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AAExF,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,YAAY,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AAGxF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,YAAY,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA"}
@@ -0,0 +1,17 @@
1
+ // Environment models
2
+ export { buildAirQualityObserved } from './environment/air_quality_observed.js';
3
+ export { buildWeatherObserved } from './environment/weather_observed.js';
4
+ export { buildWaterQualityObserved } from './environment/water_quality_observed.js';
5
+ export { buildNoiseLevelObserved } from './environment/noise_level_observed.js';
6
+ // Smart City models
7
+ export { buildStreetLight } from './smart_city/street_light.js';
8
+ export { buildParkingSpot } from './smart_city/parking_spot.js';
9
+ export { buildTrafficFlowObserved } from './smart_city/traffic_flow_observed.js';
10
+ // AgriFood models
11
+ export { buildAgriParcel } from './agrifood/agri_parcel.js';
12
+ export { buildAgriSoilMeasurement } from './agrifood/agri_soil_measurement.js';
13
+ export { buildAgriWeatherObserved } from './agrifood/agri_weather_observed.js';
14
+ // Device models
15
+ export { buildDevice } from './device/device.js';
16
+ export { buildDeviceMeasurement } from './device/device_measurement.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAG/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAGxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AAGnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAG/E,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAGhF,kBAAkB;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAG3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAG9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAG9E,gBAAgB;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { NgsiLdEntity } from '../../types/entity.js';
2
+ export interface ParkingSpotAttributes {
3
+ localId: string;
4
+ status?: 'free' | 'occupied' | 'closed' | 'unknown';
5
+ category?: string[];
6
+ refParkingSite?: string;
7
+ dateModified?: string;
8
+ name?: string;
9
+ }
10
+ /**
11
+ * Builds an NGSI-LD ParkingSpot entity.
12
+ */
13
+ export declare function buildParkingSpot(attrs: ParkingSpotAttributes): NgsiLdEntity;
14
+ //# sourceMappingURL=parking_spot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parking_spot.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/parking_spot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAA;IACnD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAqB3E"}
@@ -0,0 +1,27 @@
1
+ import { property } from '../../helpers/property.js';
2
+ import { buildUrn } from '../../helpers/urn.js';
3
+ import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
4
+ /**
5
+ * Builds an NGSI-LD ParkingSpot entity.
6
+ */
7
+ export function buildParkingSpot(attrs) {
8
+ const entity = {
9
+ id: buildUrn('ParkingSpot', attrs.localId),
10
+ type: 'ParkingSpot',
11
+ '@context': NGSI_LD_CORE_CONTEXT,
12
+ };
13
+ if (attrs.status !== undefined) {
14
+ entity['status'] = property(attrs.status);
15
+ }
16
+ if (attrs.category !== undefined) {
17
+ entity['category'] = property(attrs.category);
18
+ }
19
+ if (attrs.name !== undefined) {
20
+ entity['name'] = property(attrs.name);
21
+ }
22
+ if (attrs.dateModified !== undefined) {
23
+ entity['dateModified'] = property(attrs.dateModified);
24
+ }
25
+ return entity;
26
+ }
27
+ //# sourceMappingURL=parking_spot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parking_spot.js","sourceRoot":"","sources":["../../../src/models/smart_city/parking_spot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAW7D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IACzD,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;QAC1C,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAA6B,CAAA;IAC7E,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzC,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { NgsiLdEntity } from '../../types/entity.js';
2
+ export interface StreetLightAttributes {
3
+ localId: string;
4
+ status?: 'ok' | 'defectiveLamp' | 'columnIssue' | 'ballastProblem' | 'okLampNotWorking' | 'vandalized';
5
+ powerState?: 'on' | 'off' | 'low' | 'bootingUp';
6
+ illuminanceLevel?: number;
7
+ powerConsumption?: number;
8
+ dateLastSwitchingOn?: string;
9
+ dateLastSwitchingOff?: string;
10
+ refStreetLightGroup?: string;
11
+ }
12
+ /**
13
+ * Builds an NGSI-LD StreetLight entity.
14
+ */
15
+ export declare function buildStreetLight(attrs: StreetLightAttributes): NgsiLdEntity;
16
+ //# sourceMappingURL=street_light.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"street_light.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/street_light.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,IAAI,GAAG,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,YAAY,CAAA;IACtG,UAAU,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAA;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA2B3E"}
@@ -0,0 +1,33 @@
1
+ import { property } from '../../helpers/property.js';
2
+ import { buildUrn } from '../../helpers/urn.js';
3
+ import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
4
+ /**
5
+ * Builds an NGSI-LD StreetLight entity.
6
+ */
7
+ export function buildStreetLight(attrs) {
8
+ const entity = {
9
+ id: buildUrn('StreetLight', attrs.localId),
10
+ type: 'StreetLight',
11
+ '@context': NGSI_LD_CORE_CONTEXT,
12
+ };
13
+ if (attrs.status !== undefined) {
14
+ entity['status'] = property(attrs.status);
15
+ }
16
+ if (attrs.powerState !== undefined) {
17
+ entity['powerState'] = property(attrs.powerState);
18
+ }
19
+ if (attrs.illuminanceLevel !== undefined) {
20
+ entity['illuminanceLevel'] = property(attrs.illuminanceLevel);
21
+ }
22
+ if (attrs.powerConsumption !== undefined) {
23
+ entity['powerConsumption'] = property(attrs.powerConsumption);
24
+ }
25
+ if (attrs.dateLastSwitchingOn !== undefined) {
26
+ entity['dateLastSwitchingOn'] = property(attrs.dateLastSwitchingOn);
27
+ }
28
+ if (attrs.dateLastSwitchingOff !== undefined) {
29
+ entity['dateLastSwitchingOff'] = property(attrs.dateLastSwitchingOff);
30
+ }
31
+ return entity;
32
+ }
33
+ //# sourceMappingURL=street_light.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"street_light.js","sourceRoot":"","sources":["../../../src/models/smart_city/street_light.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAa7D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IACzD,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;QAC1C,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACrD,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,gBAAgB,CAA2B,CAAA;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,gBAAgB,CAA2B,CAAA;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,sBAAsB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { NgsiLdEntity } from '../../types/entity.js';
2
+ export interface TrafficFlowObservedAttributes {
3
+ localId: string;
4
+ dateObserved?: string;
5
+ intensity?: number;
6
+ occupancy?: number;
7
+ averageVehicleSpeed?: number;
8
+ averageVehicleLength?: number;
9
+ congested?: boolean;
10
+ averageHeadwayTime?: number;
11
+ laneId?: number;
12
+ laneDirection?: string;
13
+ vehicleType?: string;
14
+ }
15
+ /**
16
+ * Builds an NGSI-LD TrafficFlowObserved entity.
17
+ */
18
+ export declare function buildTrafficFlowObserved(attrs: TrafficFlowObservedAttributes): NgsiLdEntity;
19
+ //# sourceMappingURL=traffic_flow_observed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic_flow_observed.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/traffic_flow_observed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,6BAA6B;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,YAAY,CAgC3F"}
@@ -0,0 +1,37 @@
1
+ import { property } from '../../helpers/property.js';
2
+ import { buildUrn } from '../../helpers/urn.js';
3
+ import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
4
+ /**
5
+ * Builds an NGSI-LD TrafficFlowObserved entity.
6
+ */
7
+ export function buildTrafficFlowObserved(attrs) {
8
+ const entity = {
9
+ id: buildUrn('TrafficFlowObserved', attrs.localId),
10
+ type: 'TrafficFlowObserved',
11
+ '@context': NGSI_LD_CORE_CONTEXT,
12
+ };
13
+ const observedAt = attrs.dateObserved;
14
+ if (attrs.dateObserved !== undefined) {
15
+ entity['dateObserved'] = property(attrs.dateObserved);
16
+ }
17
+ if (attrs.intensity !== undefined) {
18
+ entity['intensity'] = property(attrs.intensity, observedAt ? { observedAt } : undefined);
19
+ }
20
+ if (attrs.occupancy !== undefined) {
21
+ entity['occupancy'] = property(attrs.occupancy, observedAt ? { observedAt } : undefined);
22
+ }
23
+ if (attrs.averageVehicleSpeed !== undefined) {
24
+ entity['averageVehicleSpeed'] = property(attrs.averageVehicleSpeed, observedAt ? { observedAt } : undefined);
25
+ }
26
+ if (attrs.congested !== undefined) {
27
+ entity['congested'] = property(attrs.congested);
28
+ }
29
+ if (attrs.laneId !== undefined) {
30
+ entity['laneId'] = property(attrs.laneId);
31
+ }
32
+ if (attrs.vehicleType !== undefined) {
33
+ entity['vehicleType'] = property(attrs.vehicleType);
34
+ }
35
+ return entity;
36
+ }
37
+ //# sourceMappingURL=traffic_flow_observed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traffic_flow_observed.js","sourceRoot":"","sources":["../../../src/models/smart_city/traffic_flow_observed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAgB7D;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAoC;IACzE,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC;QAClD,IAAI,EAAE,qBAAqB;QAC3B,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAA;IAErC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAClJ,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,MAAM,CAA2B,CAAA;IAC/E,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Queue } from 'bullmq';
2
+ import type { Subscription } from '../types/subscription.js';
3
+ import type { NgsiLdEntity } from '../types/entity.js';
4
+ import type { NotificationJobData } from '../types/notification.js';
5
+ /**
6
+ * Enqueues a notification delivery job in BullMQ.
7
+ *
8
+ * Constructs the appropriate payload (normalized or keyValues) and adds
9
+ * a job to the `ngsi-ld-notifications` queue.
10
+ *
11
+ * @param sub - The subscription to notify
12
+ * @param entity - The entity that triggered the notification
13
+ * @param queue - The BullMQ queue to enqueue into
14
+ */
15
+ export declare function enqueueNotification(sub: Subscription, entity: NgsiLdEntity, queue: Queue<NotificationJobData>): Promise<void>;
16
+ //# sourceMappingURL=notification_sender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification_sender.d.ts","sourceRoot":"","sources":["../../src/notifications/notification_sender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,0BAA0B,CAAA;AAoBxF;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACrC,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
@@ -0,0 +1,70 @@
1
+ import { randomUUID } from 'crypto';
2
+ /**
3
+ * Builds a keyValues projection of an NGSI-LD entity.
4
+ */
5
+ function toKeyValues(entity) {
6
+ const result = {
7
+ id: entity.id,
8
+ type: entity.type,
9
+ };
10
+ for (const [key, value] of Object.entries(entity)) {
11
+ if (key === 'id' || key === 'type' || key === '@context')
12
+ continue;
13
+ if (value && typeof value === 'object' && 'type' in value && 'value' in value) {
14
+ result[key] = value.value;
15
+ }
16
+ }
17
+ return result;
18
+ }
19
+ /**
20
+ * Enqueues a notification delivery job in BullMQ.
21
+ *
22
+ * Constructs the appropriate payload (normalized or keyValues) and adds
23
+ * a job to the `ngsi-ld-notifications` queue.
24
+ *
25
+ * @param sub - The subscription to notify
26
+ * @param entity - The entity that triggered the notification
27
+ * @param queue - The BullMQ queue to enqueue into
28
+ */
29
+ export async function enqueueNotification(sub, entity, queue) {
30
+ const notificationId = randomUUID();
31
+ const notifiedAt = new Date().toISOString();
32
+ // Project attributes if subscription specifies them
33
+ let entityToSend = entity;
34
+ if (sub.notificationAttrs && sub.notificationAttrs.length > 0) {
35
+ const projected = { id: entity.id, type: entity.type };
36
+ for (const attr of sub.notificationAttrs) {
37
+ if (entity[attr] !== undefined)
38
+ projected[attr] = entity[attr];
39
+ }
40
+ entityToSend = projected;
41
+ }
42
+ // Validate the endpoint URI before enqueueing
43
+ const endpoint = sub.notificationEndpoint;
44
+ if (!endpoint)
45
+ return;
46
+ const jobData = {
47
+ subscription: sub,
48
+ entity: entityToSend,
49
+ notificationId,
50
+ notifiedAt,
51
+ };
52
+ await queue.add('notify', jobData, {
53
+ attempts: 3,
54
+ backoff: {
55
+ type: 'exponential',
56
+ delay: 1000,
57
+ },
58
+ removeOnComplete: 100,
59
+ removeOnFail: 50,
60
+ });
61
+ // Build the full notification payload (for reference, stored in job data)
62
+ const _payload = {
63
+ id: `urn:ngsi-ld:Notification:${notificationId}`,
64
+ type: 'Notification',
65
+ subscriptionId: sub.id,
66
+ notifiedAt,
67
+ data: [sub.notificationFormat === 'keyValues' ? toKeyValues(entityToSend) : entityToSend],
68
+ };
69
+ }
70
+ //# sourceMappingURL=notification_sender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification_sender.js","sourceRoot":"","sources":["../../src/notifications/notification_sender.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC;;GAEG;AACH,SAAS,WAAW,CAAC,MAAoB;IACrC,MAAM,MAAM,GAA4B;QACpC,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;KACpB,CAAA;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,UAAU;YAAE,SAAQ;QAClE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5E,MAAM,CAAC,GAAG,CAAC,GAAI,KAA4B,CAAC,KAAK,CAAA;QACrD,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAA;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACrC,GAAiB,EACjB,MAAoB,EACpB,KAAiC;IAEjC,MAAM,cAAc,GAAG,UAAU,EAAE,CAAA;IACnC,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAE3C,oDAAoD;IACpD,IAAI,YAAY,GAAG,MAAM,CAAA;IACzB,IAAI,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QACpE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;QAClE,CAAC;QACD,YAAY,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAA;IACzC,IAAI,CAAC,QAAQ;QAAE,OAAM;IAErB,MAAM,OAAO,GAAwB;QACjC,YAAY,EAAE,GAAG;QACjB,MAAM,EAAE,YAAY;QACpB,cAAc;QACd,UAAU;KACb,CAAA;IAED,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE;QAC/B,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE;YACL,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,IAAI;SACd;QACD,gBAAgB,EAAE,GAAG;QACrB,YAAY,EAAE,EAAE;KACnB,CAAC,CAAA;IAEF,0EAA0E;IAC1E,MAAM,QAAQ,GAAwB;QAClC,EAAE,EAAE,4BAA4B,cAAc,EAAE;QAChD,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,GAAG,CAAC,EAAE;QACtB,UAAU;QACV,IAAI,EAAE,CAAC,GAAG,CAAC,kBAAkB,KAAK,WAAW,CAAC,CAAC,CAAE,WAAW,CAAC,YAAY,CAAkB,CAAC,CAAC,CAAC,YAAY,CAAC;KAC9G,CAAA;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Worker } from 'bullmq';
2
+ import type { ConnectionOptions } from 'bullmq';
3
+ import type { NotificationJobData } from '../types/notification.js';
4
+ import type { SubscriptionStore } from '../subscriptions/subscription_store.js';
5
+ import type { SubscriptionCache } from '../subscriptions/subscription_cache.js';
6
+ import type { Logger } from '@cepseudo/shared';
7
+ /**
8
+ * Starts the BullMQ worker that delivers NGSI-LD notifications.
9
+ *
10
+ * For each job:
11
+ * 1. Builds the NotificationPayload
12
+ * 2. HTTP POSTs to the subscriber's endpoint
13
+ * 3. Updates times_sent / times_failed / last_success_at in PostgreSQL
14
+ * 4. Updates last_notification_at in Redis
15
+ *
16
+ * Retry: exponential backoff — 1s → 5s → 25s (max 3 attempts via queue config)
17
+ */
18
+ export declare function startNotificationWorker(redis: ConnectionOptions, store: SubscriptionStore, cache: SubscriptionCache, logger: Logger): Worker<NotificationJobData>;
19
+ //# sourceMappingURL=notification_worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification_worker.d.ts","sourceRoot":"","sources":["../../src/notifications/notification_worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,0BAA0B,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAI9C;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACnC,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,GACf,MAAM,CAAC,mBAAmB,CAAC,CAyD7B"}
@@ -0,0 +1,65 @@
1
+ import { Worker } from 'bullmq';
2
+ const QUEUE_NAME = 'ngsi-ld-notifications';
3
+ /**
4
+ * Starts the BullMQ worker that delivers NGSI-LD notifications.
5
+ *
6
+ * For each job:
7
+ * 1. Builds the NotificationPayload
8
+ * 2. HTTP POSTs to the subscriber's endpoint
9
+ * 3. Updates times_sent / times_failed / last_success_at in PostgreSQL
10
+ * 4. Updates last_notification_at in Redis
11
+ *
12
+ * Retry: exponential backoff — 1s → 5s → 25s (max 3 attempts via queue config)
13
+ */
14
+ export function startNotificationWorker(redis, store, cache, logger) {
15
+ const worker = new Worker(QUEUE_NAME, async (job) => {
16
+ const { subscription: sub, entity, notificationId, notifiedAt } = job.data;
17
+ const payload = {
18
+ id: `urn:ngsi-ld:Notification:${notificationId}`,
19
+ type: 'Notification',
20
+ subscriptionId: sub.id,
21
+ notifiedAt,
22
+ data: [entity],
23
+ };
24
+ let success = false;
25
+ try {
26
+ const response = await fetch(sub.notificationEndpoint, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/ld+json',
30
+ 'Accept': 'application/json',
31
+ },
32
+ body: JSON.stringify(payload),
33
+ });
34
+ if (!response.ok) {
35
+ throw new Error(`HTTP ${response.status} from ${sub.notificationEndpoint}`);
36
+ }
37
+ success = true;
38
+ logger.info(`Notification delivered to ${sub.notificationEndpoint} for subscription ${sub.id}`);
39
+ }
40
+ catch (err) {
41
+ logger.warn(`Notification delivery failed for subscription ${sub.id}: ${err instanceof Error ? err.message : String(err)}`);
42
+ throw err; // Re-throw so BullMQ handles retry
43
+ }
44
+ finally {
45
+ // Update stats regardless of success/failure (best-effort)
46
+ try {
47
+ await store.recordNotification(sub.id, success, notifiedAt);
48
+ await cache.updateLastNotified(sub.id, notifiedAt);
49
+ }
50
+ catch (statsErr) {
51
+ logger.warn(`Failed to update notification stats for ${sub.id}: ${statsErr instanceof Error ? statsErr.message : String(statsErr)}`);
52
+ }
53
+ }
54
+ }, {
55
+ connection: redis,
56
+ concurrency: 5,
57
+ });
58
+ worker.on('failed', (job, err) => {
59
+ if (job) {
60
+ logger.warn(`Notification job ${job.id} failed permanently: ${err.message}`);
61
+ }
62
+ });
63
+ return worker;
64
+ }
65
+ //# sourceMappingURL=notification_worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification_worker.js","sourceRoot":"","sources":["../../src/notifications/notification_worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAO/B,MAAM,UAAU,GAAG,uBAAuB,CAAA;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACnC,KAAwB,EACxB,KAAwB,EACxB,KAAwB,EACxB,MAAc;IAEd,MAAM,MAAM,GAAG,IAAI,MAAM,CACrB,UAAU,EACV,KAAK,EAAC,GAAG,EAAC,EAAE;QACR,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;QAE1E,MAAM,OAAO,GAAwB;YACjC,EAAE,EAAE,4BAA4B,cAAc,EAAE;YAChD,IAAI,EAAE,cAAc;YACpB,cAAc,EAAE,GAAG,CAAC,EAAE;YACtB,UAAU;YACV,IAAI,EAAE,CAAC,MAAM,CAAC;SACjB,CAAA;QAED,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,oBAAoB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,qBAAqB;oBACrC,QAAQ,EAAE,kBAAkB;iBAC/B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAChC,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,CAAC,oBAAoB,EAAE,CAAC,CAAA;YAC/E,CAAC;YAED,OAAO,GAAG,IAAI,CAAA;YACd,MAAM,CAAC,IAAI,CAAC,6BAA6B,GAAG,CAAC,oBAAoB,qBAAqB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,iDAAiD,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC3H,MAAM,GAAG,CAAA,CAAC,mCAAmC;QACjD,CAAC;gBAAS,CAAC;YACP,2DAA2D;YAC3D,IAAI,CAAC;gBACD,MAAM,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;gBAC3D,MAAM,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;YACtD,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,2CAA2C,GAAG,CAAC,EAAE,KAAK,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YACxI,CAAC;QACL,CAAC;IACL,CAAC,EACD;QACI,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,CAAC;KACjB,CACJ,CAAA;IAED,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7B,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QAChF,CAAC;IACL,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { Router } from 'ultimate-express';
2
+ import type { DatabaseAdapter } from '@cepseudo/database';
3
+ import { Logger } from '@cepseudo/shared';
4
+ /**
5
+ * Configuration options for the NGSI-LD plugin.
6
+ */
7
+ export interface NgsiLdPluginOptions {
8
+ /** Express Router from the engine */
9
+ router: Router;
10
+ /** Database adapter for subscription persistence */
11
+ db: DatabaseAdapter;
12
+ /** Redis connection config for entity cache and subscription cache */
13
+ redis: {
14
+ host: string;
15
+ port: number;
16
+ password?: string;
17
+ };
18
+ /** All components registered in the engine */
19
+ components: unknown[];
20
+ /** Logger instance */
21
+ logger: Logger;
22
+ }
23
+ /**
24
+ * Registers the NGSI-LD plugin with the Digital Twin engine.
25
+ *
26
+ * This function:
27
+ * 1. Connects to Redis
28
+ * 2. Runs the subscription table migration
29
+ * 3. Warms up the subscription cache
30
+ * 4. Registers NGSI-LD HTTP endpoints
31
+ * 5. Starts the notification worker
32
+ * 6. Listens to engineEventBus for component completion events
33
+ */
34
+ export declare function registerNgsiLd(options: NgsiLdPluginOptions): Promise<void>;
35
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAA;AAczD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,EAAE,EAAE,eAAe,CAAA;IACnB,sEAAsE;IACtE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,8CAA8C;IAC9C,UAAU,EAAE,OAAO,EAAE,CAAA;IACrB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoGhF"}
package/dist/plugin.js ADDED
@@ -0,0 +1,113 @@
1
+ import { Queue } from 'bullmq';
2
+ import { Redis } from 'ioredis';
3
+ import { engineEventBus } from '@cepseudo/shared';
4
+ import { EntityCache } from './cache/entity_cache.js';
5
+ import { SubscriptionStore } from './subscriptions/subscription_store.js';
6
+ import { SubscriptionCache } from './subscriptions/subscription_cache.js';
7
+ import { SubscriptionMatcher } from './subscriptions/subscription_matcher.js';
8
+ import { isNgsiLdCollector, isNgsiLdHarvester } from './components/type_guards.js';
9
+ import { enqueueNotification } from './notifications/notification_sender.js';
10
+ import { startNotificationWorker } from './notifications/notification_worker.js';
11
+ import { registerEntityEndpoints } from './endpoints/entities.js';
12
+ import { registerAttrsEndpoints } from './endpoints/attrs.js';
13
+ import { registerSubscriptionEndpoints } from './endpoints/subscriptions.js';
14
+ import { registerTypesEndpoints } from './endpoints/types.js';
15
+ /**
16
+ * Registers the NGSI-LD plugin with the Digital Twin engine.
17
+ *
18
+ * This function:
19
+ * 1. Connects to Redis
20
+ * 2. Runs the subscription table migration
21
+ * 3. Warms up the subscription cache
22
+ * 4. Registers NGSI-LD HTTP endpoints
23
+ * 5. Starts the notification worker
24
+ * 6. Listens to engineEventBus for component completion events
25
+ */
26
+ export async function registerNgsiLd(options) {
27
+ const { router, db, redis: redisConfig, components, logger } = options;
28
+ // Connect to Redis
29
+ const redisConnection = new Redis({
30
+ host: redisConfig.host,
31
+ port: redisConfig.port,
32
+ password: redisConfig.password,
33
+ maxRetriesPerRequest: null,
34
+ enableReadyCheck: true,
35
+ });
36
+ // Create Redis connection for BullMQ (separate connection, same config)
37
+ const bullmqConnection = {
38
+ host: redisConfig.host,
39
+ port: redisConfig.port,
40
+ password: redisConfig.password,
41
+ };
42
+ // Initialize subsystems
43
+ const entityCache = new EntityCache(redisConnection);
44
+ const subscriptionStore = new SubscriptionStore(db);
45
+ const subscriptionCache = new SubscriptionCache(redisConnection);
46
+ const matcher = new SubscriptionMatcher(subscriptionCache);
47
+ // Run migration to create subscriptions table
48
+ await subscriptionStore.runMigration();
49
+ // Warm up subscription cache from database
50
+ const allSubs = await subscriptionStore.findAll();
51
+ await subscriptionCache.warmup(allSubs);
52
+ logger.info(`NGSI-LD plugin initialized: ${allSubs.length} subscriptions loaded`);
53
+ // BullMQ notification queue
54
+ const notificationQueue = new Queue('ngsi-ld-notifications', {
55
+ connection: bullmqConnection,
56
+ });
57
+ // Register HTTP endpoints
58
+ registerEntityEndpoints(router, entityCache, subscriptionStore, subscriptionCache);
59
+ registerAttrsEndpoints(router, entityCache);
60
+ registerSubscriptionEndpoints(router, subscriptionStore, subscriptionCache);
61
+ registerTypesEndpoints(router, entityCache);
62
+ // Start notification delivery worker
63
+ startNotificationWorker(bullmqConnection, subscriptionStore, subscriptionCache, logger);
64
+ // Listen to engine events for NGSI-LD-aware components
65
+ engineEventBus.on('component:event', async (event) => {
66
+ if (event.type !== 'collector:completed' &&
67
+ event.type !== 'harvester:completed') {
68
+ return;
69
+ }
70
+ const component = components.find(c => {
71
+ if (!c || typeof c !== 'object')
72
+ return false;
73
+ const conf = c.getConfiguration?.();
74
+ return conf?.name === event.componentName;
75
+ });
76
+ if (!component)
77
+ return;
78
+ if (!isNgsiLdCollector(component) && !isNgsiLdHarvester(component))
79
+ return;
80
+ try {
81
+ // Get the latest record from database
82
+ const record = await db.getLatestByName(event.componentName);
83
+ if (!record)
84
+ return;
85
+ // Parse the data
86
+ const blob = await record.data();
87
+ let data;
88
+ try {
89
+ data = JSON.parse(blob.toString());
90
+ }
91
+ catch {
92
+ data = blob.toString();
93
+ }
94
+ // Convert to NGSI-LD entity
95
+ const entity = component.toNgsiLdEntity(data, record);
96
+ const oldEntity = await entityCache.get(entity.id);
97
+ // Update cache
98
+ await entityCache.set(entity);
99
+ // Evaluate subscriptions
100
+ const matchingSubIds = await matcher.match(entity, oldEntity ?? undefined);
101
+ for (const subId of matchingSubIds) {
102
+ const sub = await subscriptionCache.getById(subId);
103
+ if (sub) {
104
+ await enqueueNotification(sub, entity, notificationQueue);
105
+ }
106
+ }
107
+ }
108
+ catch (err) {
109
+ logger.warn(`NGSI-LD event processing failed for ${event.componentName}: ${err instanceof Error ? err.message : String(err)}`);
110
+ }
111
+ });
112
+ }
113
+ //# sourceMappingURL=plugin.js.map