@parkflow/shared-types 1.0.1
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/.prettierrc +8 -0
- package/.vscode/settings.json +5 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +14 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/is-base64-or-na/index.d.ts +1 -0
- package/dist/decorators/is-base64-or-na/index.js +14 -0
- package/dist/decorators/is-base64-or-na/index.js.map +1 -0
- package/dist/decorators/is-base64-or-na/is-base64-or-na-validation.decorator.d.ts +5 -0
- package/dist/decorators/is-base64-or-na/is-base64-or-na-validation.decorator.js +23 -0
- package/dist/decorators/is-base64-or-na/is-base64-or-na-validation.decorator.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types/adaptive/einar/event.dto.d.ts +72 -0
- package/dist/types/adaptive/einar/event.dto.js +22 -0
- package/dist/types/adaptive/einar/event.dto.js.map +1 -0
- package/dist/types/adaptive/einar/index.d.ts +2 -0
- package/dist/types/adaptive/einar/index.js +15 -0
- package/dist/types/adaptive/einar/index.js.map +1 -0
- package/dist/types/adaptive/einar/job.dto.d.ts +8 -0
- package/dist/types/adaptive/einar/job.dto.js +8 -0
- package/dist/types/adaptive/einar/job.dto.js.map +1 -0
- package/dist/types/adaptive/index.d.ts +4 -0
- package/dist/types/adaptive/index.js +17 -0
- package/dist/types/adaptive/index.js.map +1 -0
- package/dist/types/adaptive/micro/index.d.ts +1 -0
- package/dist/types/adaptive/micro/index.js +14 -0
- package/dist/types/adaptive/micro/index.js.map +1 -0
- package/dist/types/adaptive/micro/micro-job.dto.d.ts +4 -0
- package/dist/types/adaptive/micro/micro-job.dto.js +8 -0
- package/dist/types/adaptive/micro/micro-job.dto.js.map +1 -0
- package/dist/types/adaptive/vidar/event.dto.d.ts +9 -0
- package/dist/types/adaptive/vidar/event.dto.js +42 -0
- package/dist/types/adaptive/vidar/event.dto.js.map +1 -0
- package/dist/types/adaptive/vidar/index.d.ts +3 -0
- package/dist/types/adaptive/vidar/index.js +16 -0
- package/dist/types/adaptive/vidar/index.js.map +1 -0
- package/dist/types/adaptive/vidar/job.dto.d.ts +8 -0
- package/dist/types/adaptive/vidar/job.dto.js +8 -0
- package/dist/types/adaptive/vidar/job.dto.js.map +1 -0
- package/dist/types/adaptive/vidar/vidar-direction.enum.d.ts +5 -0
- package/dist/types/adaptive/vidar/vidar-direction.enum.js +3 -0
- package/dist/types/adaptive/vidar/vidar-direction.enum.js.map +1 -0
- package/dist/types/adaptive/vidar-new/index.d.ts +4 -0
- package/dist/types/adaptive/vidar-new/index.js +17 -0
- package/dist/types/adaptive/vidar-new/index.js.map +1 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job-base.dto.d.ts +15 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job-base.dto.js +7 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job-base.dto.js.map +1 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.dto.d.ts +4 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.dto.js +8 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.dto.js.map +1 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.type.d.ts +3 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.type.js +3 -0
- package/dist/types/adaptive/vidar-new/vidar-new-job.type.js.map +1 -0
- package/dist/types/adaptive/vidar-new/vidar-new.event.dto.d.ts +13 -0
- package/dist/types/adaptive/vidar-new/vidar-new.event.dto.js +59 -0
- package/dist/types/adaptive/vidar-new/vidar-new.event.dto.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +17 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lpr/camera-type.d.ts +1 -0
- package/dist/types/lpr/camera-type.js +3 -0
- package/dist/types/lpr/camera-type.js.map +1 -0
- package/dist/types/lpr/index.d.ts +4 -0
- package/dist/types/lpr/index.js +17 -0
- package/dist/types/lpr/index.js.map +1 -0
- package/dist/types/lpr/lpr-direction.enum.d.ts +5 -0
- package/dist/types/lpr/lpr-direction.enum.js +10 -0
- package/dist/types/lpr/lpr-direction.enum.js.map +1 -0
- package/dist/types/lpr/lpr-job.interface.d.ts +22 -0
- package/dist/types/lpr/lpr-job.interface.js +3 -0
- package/dist/types/lpr/lpr-job.interface.js.map +1 -0
- package/dist/types/lpr/lpr-job.type.d.ts +3 -0
- package/dist/types/lpr/lpr-job.type.js +3 -0
- package/dist/types/lpr/lpr-job.type.js.map +1 -0
- package/dist/types/platesmart/event.dto.d.ts +50 -0
- package/dist/types/platesmart/event.dto.js +31 -0
- package/dist/types/platesmart/event.dto.js.map +1 -0
- package/dist/types/platesmart/index.d.ts +2 -0
- package/dist/types/platesmart/index.js +15 -0
- package/dist/types/platesmart/index.js.map +1 -0
- package/dist/types/platesmart/job.d.ts +10 -0
- package/dist/types/platesmart/job.js +10 -0
- package/dist/types/platesmart/job.js.map +1 -0
- package/dist/types/platesmart/orientation.enum.d.ts +0 -0
- package/dist/types/platesmart/orientation.enum.js +1 -0
- package/dist/types/platesmart/orientation.enum.js.map +1 -0
- package/dist/types/rekor/event.dto.d.ts +97 -0
- package/dist/types/rekor/event.dto.js +3 -0
- package/dist/types/rekor/event.dto.js.map +1 -0
- package/dist/types/rekor/index.d.ts +2 -0
- package/dist/types/rekor/index.js +15 -0
- package/dist/types/rekor/index.js.map +1 -0
- package/dist/types/rekor/job.d.ts +13 -0
- package/dist/types/rekor/job.js +7 -0
- package/dist/types/rekor/job.js.map +1 -0
- package/jest.config.js +8 -0
- package/package.json +36 -0
- package/src/decorators/index.ts +1 -0
- package/src/decorators/is-base64-or-na/index.ts +1 -0
- package/src/decorators/is-base64-or-na/is-base64-or-na-validation.decorator.ts +12 -0
- package/src/decorators/is-base64-or-na/is-base64-or-na.validation.decorator.spec.ts +60 -0
- package/src/index.ts +1 -0
- package/src/types/adaptive/einar/event.dto.ts +77 -0
- package/src/types/adaptive/einar/index.ts +2 -0
- package/src/types/adaptive/einar/job.dto.ts +9 -0
- package/src/types/adaptive/index.ts +4 -0
- package/src/types/adaptive/micro/README.md +32 -0
- package/src/types/adaptive/micro/index.ts +1 -0
- package/src/types/adaptive/micro/micro-job.dto.ts +5 -0
- package/src/types/adaptive/vidar/event.dto.ts +23 -0
- package/src/types/adaptive/vidar/filenames.tmpl +1 -0
- package/src/types/adaptive/vidar/index.ts +3 -0
- package/src/types/adaptive/vidar/job.dto.ts +9 -0
- package/src/types/adaptive/vidar/vidar-direction.enum.ts +5 -0
- package/src/types/adaptive/vidar/vidar.json.tmpl +8 -0
- package/src/types/adaptive/vidar-new/README.md +23 -0
- package/src/types/adaptive/vidar-new/index.ts +4 -0
- package/src/types/adaptive/vidar-new/vidar-new-job-base.dto.ts +19 -0
- package/src/types/adaptive/vidar-new/vidar-new-job.dto.ts +5 -0
- package/src/types/adaptive/vidar-new/vidar-new-job.type.ts +4 -0
- package/src/types/adaptive/vidar-new/vidar-new.event.dto.ts +40 -0
- package/src/types/adaptive/vidar-new/vidar-new.json.tmpl +12 -0
- package/src/types/index.ts +4 -0
- package/src/types/lpr/camera-type.ts +1 -0
- package/src/types/lpr/index.ts +4 -0
- package/src/types/lpr/lpr-direction.enum.ts +5 -0
- package/src/types/lpr/lpr-job.interface.ts +29 -0
- package/src/types/lpr/lpr-job.type.ts +4 -0
- package/src/types/platesmart/event.dto.ts +58 -0
- package/src/types/platesmart/index.ts +3 -0
- package/src/types/platesmart/job.ts +11 -0
- package/src/types/platesmart/orientation.enum.ts +5 -0
- package/src/types/rekor/event.dto.ts +108 -0
- package/src/types/rekor/index.ts +2 -0
- package/src/types/rekor/job.ts +13 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Validate, validateSync } from 'class-validator';
|
|
2
|
+
import { IsBase64OrNA } from './is-base64-or-na-validation.decorator';
|
|
3
|
+
|
|
4
|
+
describe('IsBase64OrNA', () => {
|
|
5
|
+
const validator = new IsBase64OrNA();
|
|
6
|
+
|
|
7
|
+
describe('validate', () => {
|
|
8
|
+
describe(`not base 64 or 'n.a.'`, () => {
|
|
9
|
+
it('should return false', () => {
|
|
10
|
+
const text = 'not?base!&64';
|
|
11
|
+
expect(validator.validate(text, undefined)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe(`'n.a.'`, () => {
|
|
16
|
+
it('should return true', () => {
|
|
17
|
+
const text = 'n.a.';
|
|
18
|
+
expect(validator.validate(text, undefined)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('base64', () => {
|
|
23
|
+
it('should return true', () => {
|
|
24
|
+
const text = 'SGVsbG8sIFdvcmxkLg=='; // "Hello, World."
|
|
25
|
+
expect(validator.validate(text, undefined)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('in use', () => {
|
|
31
|
+
class A {
|
|
32
|
+
@Validate(IsBase64OrNA)
|
|
33
|
+
text: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('invalid', () => {
|
|
37
|
+
it('should return an error', () => {
|
|
38
|
+
const a = new A();
|
|
39
|
+
a.text = 'not!base!64!&';
|
|
40
|
+
expect(validateSync(a)).toHaveLength(1);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('base64', () => {
|
|
45
|
+
it('should not return any errors', () => {
|
|
46
|
+
const a = new A();
|
|
47
|
+
a.text = 'SGVsbG8sIFdvcmxkLg==';
|
|
48
|
+
expect(validateSync(a)).toHaveLength(0);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe(`'n.a.'`, () => {
|
|
53
|
+
it('should not return any errors', () => {
|
|
54
|
+
const a = new A();
|
|
55
|
+
a.text = 'n.a.';
|
|
56
|
+
expect(validateSync(a)).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export class AdaptiveEventDto {
|
|
2
|
+
DetectorVersion: number;
|
|
3
|
+
DetectorID: string;
|
|
4
|
+
DetectorClassID: number;
|
|
5
|
+
DetectorClass: string;
|
|
6
|
+
EventTime: string; // timestamp (windows)
|
|
7
|
+
EventTriggerTime: string; // ditto
|
|
8
|
+
State: string;
|
|
9
|
+
EventCode: 114;
|
|
10
|
+
EventInfo: EventInfo;
|
|
11
|
+
EventID: string;
|
|
12
|
+
DetectorEventType: string;
|
|
13
|
+
Config: DetectorConfig;
|
|
14
|
+
Device?: DeviceInfo;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class EventInfo {
|
|
18
|
+
Text: string;
|
|
19
|
+
Confidence: number;
|
|
20
|
+
Country: string; // 'USA/LA'
|
|
21
|
+
CountryCode: number;
|
|
22
|
+
Coords: number[]; // of found lpn
|
|
23
|
+
BackgroundColor: string;
|
|
24
|
+
DedicatedAreaColor: string;
|
|
25
|
+
TextColor: string;
|
|
26
|
+
CharacterSize: number;
|
|
27
|
+
Direction: 'Approaching' | 'Moving away' | 'Unknown';
|
|
28
|
+
TriggerSource: TriggerSource;
|
|
29
|
+
MMR: MMR;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class TriggerSource {
|
|
33
|
+
Name: string;
|
|
34
|
+
Source: string;
|
|
35
|
+
Timestamp: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class MMR {
|
|
39
|
+
Category: string;
|
|
40
|
+
Make: string;
|
|
41
|
+
Model: string;
|
|
42
|
+
Color: string;
|
|
43
|
+
CategoryConfidence: number;
|
|
44
|
+
MakeAndModelConfidence: number;
|
|
45
|
+
ColorConfidence: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class DetectorConfig {
|
|
49
|
+
Class: string;
|
|
50
|
+
DetectorClass: string;
|
|
51
|
+
Version: number;
|
|
52
|
+
DetectorClassID: number;
|
|
53
|
+
BuiltIn: boolean;
|
|
54
|
+
DetectorID: string;
|
|
55
|
+
DisplayName: string;
|
|
56
|
+
Description: string;
|
|
57
|
+
ViolationTimeMs: number;
|
|
58
|
+
RestoreDelayMs: number;
|
|
59
|
+
FpsLimit: number;
|
|
60
|
+
Enabled: boolean;
|
|
61
|
+
Mode: string;
|
|
62
|
+
Filter: string;
|
|
63
|
+
Whitelist: boolean;
|
|
64
|
+
Masks: object;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class DeviceInfo {
|
|
68
|
+
Name: string;
|
|
69
|
+
Description: string;
|
|
70
|
+
Location: {
|
|
71
|
+
GPS: {
|
|
72
|
+
Latitude: number;
|
|
73
|
+
Longitude: number;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
Serial: string;
|
|
77
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Micro Cam
|
|
2
|
+
|
|
3
|
+
The Micro Cam is almost identical in it's interface to the Vidar, and also in it's configuration. The JSON template file can be found in the `vidar-new` folder, and the filename template file is in `vidar`.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## GPS
|
|
7
|
+
|
|
8
|
+
This is specific to Micro Cams, so it's the most important to be documented here. The Peplink routers that we use have an open socket at port `60660` that continuously produces GPS data. You can try `telnet 192.168.50.1 60660` in your bash shell to verify (assuming the router is at that IP --- it usually is). If the output does not contian lat/long, make sure the antenna is properly connected and able to receive GPS signal. You must be aboveground to receive GPS data.
|
|
9
|
+
In the camera, go to `http://{CAMERA_IP}/#plainconfig`. There you will set the following settings:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/default/cff/gps/enabled = 1
|
|
13
|
+
|
|
14
|
+
/default/cfs/gps/type = 5
|
|
15
|
+
/default/cfs/gps/destination = tcp://192.168.50.1:60660
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
You can then trigger an event using the software trigger and expect to the see the GPS data in the event upload. For fast feedback when testing, you can edit the line editor of the camera by appending the following: `GPS: $A, $O` to see it in the black bar at the bottom of each image.
|
|
19
|
+
|
|
20
|
+
If you don't see the GPS data right away, give it a few minutes, sometimes it takes a little while for the camera to integrate the data flow. If it's still not working, give Adaptive a call.
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
The Micro Cam is under the umbrella of `VidarNew`, because
|
|
25
|
+
the Micro Cam is the same as the Vidar. The new way to process Vidar uploads was developed when integrating the Micro Cam (see `../vidar-new/README.md` for more details).
|
|
26
|
+
|
|
27
|
+
In general, the Camera will upload a result file containing the pertinent data points and the images, encoded in base64 format. The controller will grab the file and pass it to the service, which will in turn upload the images to the S3 bucket and pass the event data to the message queue. The images will be converted from base64 to binary once in the bucket by a connected Lambda function.
|
|
28
|
+
|
|
29
|
+
## Camera Configuration
|
|
30
|
+
|
|
31
|
+
Upload `../vidar-new/vidar.json.tmpl` to the camera and set it as the result upload file format. Set `../vidar/filenames.tmpl` as the filename template. Point the camera to `https://lpr.vanguardparking.co/vidar/micro?source={CAMERA_NAME}`. De-select plate image for the upload, so only "Result Upload" should be checked.
|
|
32
|
+
Additionally, you want to make sure that connection attempts is set between 3-5, and connection timeout to `5000ms`. That's something we are currently experimenting with.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './micro-job.dto';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IsIn, IsNumberString, IsString, Length } from 'class-validator';
|
|
2
|
+
import { VidarDirection } from './vidar-direction.enum';
|
|
3
|
+
|
|
4
|
+
export class VidarEventDto {
|
|
5
|
+
@IsString()
|
|
6
|
+
cameraId: string;
|
|
7
|
+
|
|
8
|
+
@IsNumberString()
|
|
9
|
+
vidarEventId: string;
|
|
10
|
+
|
|
11
|
+
@IsNumberString()
|
|
12
|
+
eventTimestamp: string;
|
|
13
|
+
|
|
14
|
+
@IsString()
|
|
15
|
+
@Length(0, 3)
|
|
16
|
+
state: string;
|
|
17
|
+
|
|
18
|
+
@IsString()
|
|
19
|
+
text: string;
|
|
20
|
+
|
|
21
|
+
@IsIn(['0', '1', '2'])
|
|
22
|
+
direction: VidarDirection;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$(cameraid);-$(ID);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Vidar New
|
|
2
|
+
|
|
3
|
+
This is the updated version of the vidar uploads. As of the time of this writing (3/5/24), the newer method has not yet been deployed on the existing vidars. It will be soon. It is currently live on the Micro Cams.
|
|
4
|
+
|
|
5
|
+
The main advantage of this method is twofold:
|
|
6
|
+
|
|
7
|
+
1. All the data comes in one request: JSON and images
|
|
8
|
+
2. The images are compressed using base64
|
|
9
|
+
|
|
10
|
+
Because all the data comes in one request, we have a greater guarantee of catching everything. If we got the JSON, we can be reasonably certain that we got the images. We are having issues with the current method, in which the JSON and two images each come in separately, so that's 3 separate requests per event, and we were dropping some images, but getting the events. Furthermore, the compressed payload size should help improve general performance.
|
|
11
|
+
|
|
12
|
+
## Important
|
|
13
|
+
|
|
14
|
+
In the Vidar settings, go to `{VIDAR_IP}/#plainconfig` and set `/default/cfs/uplm/http/content` to 4. By unchecking the boxes titled `Image` and `Plate Image` in the result upload page, that should do the trick, but make sure anyways, because it once happened that it didn't. The image was being sent to the server and not handled properly throwing an error.
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
The data file comes in and is parsed. The base64 images get sent up to the cloud, where they are converted and compressed, and the event data is passed on to the message queue. That's it.
|
|
19
|
+
|
|
20
|
+
## Camera Configuration
|
|
21
|
+
|
|
22
|
+
Upload `../vidar-new/vidar.json.tmpl` to the camera and set it as the result upload file format. Set `../vidar/filenames.tmpl` as the filename template. Point the camera to `https://lpr.vanguardparking.co/vidar/micro?source={CAMERA_NAME}`. De-select plate image for the upload, so only "Result Upload" should be checked.
|
|
23
|
+
Additionally, you want to make sure that connection attempts is set between 3-5, and connection timeout to `5000ms`. That's something we are currently experimenting with.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { VidarDirection } from '../vidar/vidar-direction.enum';
|
|
2
|
+
|
|
3
|
+
export class VidarNewJobBase {
|
|
4
|
+
cameraId: string;
|
|
5
|
+
vidarEventId: string;
|
|
6
|
+
eventTimestamp: string;
|
|
7
|
+
state: string;
|
|
8
|
+
text: string;
|
|
9
|
+
direction: VidarDirection;
|
|
10
|
+
latitude: string;
|
|
11
|
+
longitude: string;
|
|
12
|
+
// // everything up until here is in VidarNewEventDto,
|
|
13
|
+
// // needed to copy because want it to be a class, but can't omit base64 images
|
|
14
|
+
|
|
15
|
+
eventId: string;
|
|
16
|
+
payloadTimestamp: number;
|
|
17
|
+
vehicleImageUrl: string;
|
|
18
|
+
plateImageUrl: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IsBase64, IsIn, IsLatitude, IsLongitude, IsNumberString, IsString, Length, Validate } from 'class-validator';
|
|
2
|
+
import { VidarDirection } from '../vidar/vidar-direction.enum';
|
|
3
|
+
import { IsBase64OrNA } from '../../../decorators';
|
|
4
|
+
|
|
5
|
+
export class VidarNewEventDto {
|
|
6
|
+
@IsString()
|
|
7
|
+
cameraId: string;
|
|
8
|
+
|
|
9
|
+
@IsNumberString()
|
|
10
|
+
vidarEventId: string;
|
|
11
|
+
|
|
12
|
+
@IsNumberString()
|
|
13
|
+
eventTimestamp: string;
|
|
14
|
+
|
|
15
|
+
@IsString()
|
|
16
|
+
@Length(0, 3)
|
|
17
|
+
state: string;
|
|
18
|
+
|
|
19
|
+
@IsString()
|
|
20
|
+
text: string;
|
|
21
|
+
|
|
22
|
+
@IsIn(['0', '1', '2'])
|
|
23
|
+
direction: VidarDirection;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Plate Image
|
|
27
|
+
* If Vidar is sending a motion capture - i.e. plate text = 'n.a.' - plateImage will be 'n.a.' as well
|
|
28
|
+
*/
|
|
29
|
+
@Validate(IsBase64OrNA)
|
|
30
|
+
plateImage: string;
|
|
31
|
+
|
|
32
|
+
@IsBase64()
|
|
33
|
+
vehicleImage: string;
|
|
34
|
+
|
|
35
|
+
@IsLatitude()
|
|
36
|
+
latitude: string;
|
|
37
|
+
|
|
38
|
+
@IsLongitude()
|
|
39
|
+
longitude: string;
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cameraId": "$(cameraid);",
|
|
3
|
+
"vidarEventId": "$(ID);",
|
|
4
|
+
"eventTimestamp": "$(FRAMETIMEMS);",
|
|
5
|
+
"state": "$(STATE_SHORT);",
|
|
6
|
+
"text": "$DB2JSON($(ANPR_TEXT));",
|
|
7
|
+
"direction": "$(TRIGGER_DIRECTION);",
|
|
8
|
+
"plateImage": "$(lp_img);",
|
|
9
|
+
"vehicleImage": "$(normal_img);",
|
|
10
|
+
"latitude": "$(MISC_GPS_LAT);",
|
|
11
|
+
"longitude": "$(MISC_GPS_LON);"
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type CameraType = 'einar' | 'vidar' | 'rekor';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Orientation } from '../platesmart';
|
|
2
|
+
import { CameraType } from './camera-type';
|
|
3
|
+
import { LprDirectionEnum } from './lpr-direction.enum';
|
|
4
|
+
|
|
5
|
+
export interface ILprJob {
|
|
6
|
+
type: CameraType;
|
|
7
|
+
lpn: string;
|
|
8
|
+
eventId: string;
|
|
9
|
+
orientation?: Orientation;
|
|
10
|
+
direction?: LprDirectionEnum;
|
|
11
|
+
cameraId: string;
|
|
12
|
+
twoLetterState: string;
|
|
13
|
+
eventTimestamp: number | Date;
|
|
14
|
+
payloadTimestamp: number | Date;
|
|
15
|
+
plateRegion: string;
|
|
16
|
+
vehicleImageURL: string;
|
|
17
|
+
plateImageURL: string;
|
|
18
|
+
confidence: number;
|
|
19
|
+
/**
|
|
20
|
+
* Informal identifying information
|
|
21
|
+
*/
|
|
22
|
+
labels?: {
|
|
23
|
+
/**
|
|
24
|
+
* 'source' query param
|
|
25
|
+
*/
|
|
26
|
+
reqSource?: string;
|
|
27
|
+
cameraName?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export class PlatesmartEventDto {
|
|
2
|
+
image: Image;
|
|
3
|
+
plate: Plate;
|
|
4
|
+
source: Source;
|
|
5
|
+
vehicle?: Vehicle;
|
|
6
|
+
id: string;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
type: string;
|
|
9
|
+
version: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class Image {
|
|
13
|
+
height: number;
|
|
14
|
+
id: string;
|
|
15
|
+
width: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Plate {
|
|
19
|
+
code?: string;
|
|
20
|
+
region: Region;
|
|
21
|
+
tag: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class Region {
|
|
25
|
+
height: number;
|
|
26
|
+
width: number;
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class Source {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
type: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Vehicle {
|
|
38
|
+
color?: Color;
|
|
39
|
+
make?: Make;
|
|
40
|
+
orientation?: Orientation;
|
|
41
|
+
type?: Make;
|
|
42
|
+
bearing?: number;
|
|
43
|
+
occlusion?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class Color {
|
|
47
|
+
code: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class Make {
|
|
51
|
+
code: string;
|
|
52
|
+
name: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class Orientation {
|
|
56
|
+
code: 'rear' | 'front' | 'side';
|
|
57
|
+
name: 'Rear' | 'Front' | 'Side';
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PlatesmartEventDto } from './event.dto';
|
|
2
|
+
|
|
3
|
+
class PlatesmartJobForQueue extends PlatesmartEventDto {
|
|
4
|
+
payloadTimestamp: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class PlatesmartJob extends PlatesmartJobForQueue {
|
|
8
|
+
saved: boolean;
|
|
9
|
+
plateImageURL: string;
|
|
10
|
+
vehicleImageURL: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// made using quicktype.io on a rekor webhook test
|
|
2
|
+
|
|
3
|
+
export interface RekorEvent {
|
|
4
|
+
data_type: string;
|
|
5
|
+
version: number;
|
|
6
|
+
epoch_start: number;
|
|
7
|
+
epoch_end: number;
|
|
8
|
+
frame_start: number;
|
|
9
|
+
frame_end: number;
|
|
10
|
+
company_id: string;
|
|
11
|
+
agent_uid: string;
|
|
12
|
+
agent_version: string;
|
|
13
|
+
agent_type: string;
|
|
14
|
+
camera_id: number;
|
|
15
|
+
gps_latitude: number;
|
|
16
|
+
gps_longitude: number;
|
|
17
|
+
country: string;
|
|
18
|
+
uuids: string[];
|
|
19
|
+
vehicle_path: EPath[];
|
|
20
|
+
plate_indexes: number[];
|
|
21
|
+
candidates: Candidate[];
|
|
22
|
+
best_plate: BestPlate;
|
|
23
|
+
best_confidence: number;
|
|
24
|
+
best_plate_number: string;
|
|
25
|
+
best_region: string;
|
|
26
|
+
best_region_confidence: number;
|
|
27
|
+
matches_template: boolean;
|
|
28
|
+
plate_path: EPath[];
|
|
29
|
+
vehicle_crop_jpeg: string;
|
|
30
|
+
overview_jpeg: string;
|
|
31
|
+
best_uuid: string;
|
|
32
|
+
best_uuid_epoch_ms: number;
|
|
33
|
+
best_image_width: number;
|
|
34
|
+
best_image_height: number;
|
|
35
|
+
travel_direction: number;
|
|
36
|
+
is_parked: boolean;
|
|
37
|
+
is_preview: boolean;
|
|
38
|
+
vehicle_signature: string;
|
|
39
|
+
vehicle: RekorVehicleType;
|
|
40
|
+
web_server_config: WebServerConfig;
|
|
41
|
+
direction_of_travel_id: number;
|
|
42
|
+
custom_data: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface BestPlate {
|
|
46
|
+
plate: string;
|
|
47
|
+
confidence: number;
|
|
48
|
+
matches_template: number;
|
|
49
|
+
plate_index: number;
|
|
50
|
+
region: string;
|
|
51
|
+
region_confidence: number;
|
|
52
|
+
processing_time_ms: number;
|
|
53
|
+
requested_topn: number;
|
|
54
|
+
coordinates: Coordinate[];
|
|
55
|
+
plate_crop_jpeg: string;
|
|
56
|
+
vehicle_region: VehicleRegion;
|
|
57
|
+
vehicle_detected: boolean;
|
|
58
|
+
candidates: Candidate[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Candidate {
|
|
62
|
+
plate: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
matches_template: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface Coordinate {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface VehicleRegion {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface EPath {
|
|
80
|
+
x: number;
|
|
81
|
+
y: number;
|
|
82
|
+
w: number;
|
|
83
|
+
h: number;
|
|
84
|
+
t: number;
|
|
85
|
+
f: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// name conflict w/ Platesmart
|
|
89
|
+
export interface RekorVehicleType {
|
|
90
|
+
color: BodyType[];
|
|
91
|
+
make: BodyType[];
|
|
92
|
+
make_model: BodyType[];
|
|
93
|
+
body_type: BodyType[];
|
|
94
|
+
year: BodyType[];
|
|
95
|
+
orientation: BodyType[];
|
|
96
|
+
missing_plate: BodyType[];
|
|
97
|
+
is_vehicle: BodyType[];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface BodyType {
|
|
101
|
+
name: string;
|
|
102
|
+
confidence: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface WebServerConfig {
|
|
106
|
+
camera_label: string;
|
|
107
|
+
agent_label: string;
|
|
108
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class RekorJob {
|
|
2
|
+
type: 'rekor';
|
|
3
|
+
uuid: string;
|
|
4
|
+
lpn: string;
|
|
5
|
+
state: string;
|
|
6
|
+
cameraId: string;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
payloadTimestamp: number;
|
|
9
|
+
plateImageURL: string;
|
|
10
|
+
vehicleImageURL: string;
|
|
11
|
+
travelDirection: number;
|
|
12
|
+
directionOfTravelId: number;
|
|
13
|
+
}
|