Recurrence
A recurrence object allows to define series of recordings that recur regularly. For example if a program should be recorded that is sent every Monday and Tuesday at 8 p.m., a recurrence can be defined for that. Based on this recurrence a recording is planned automatically for each instance and no manual action for each recording is necessary.
Object Structure
The recurrence itself is part of a BookingDefinition. A Booking is attached on this BookingDefinition for each recording that contains all Chunks for this recording.
These bookings and chunks are either automatically generated in the backend a defined timespan before the recording should take place or because of changes a user made to a specific recording that is part of the recurrence. Otherwise they only exist as virtual chunks, which do not exist in the database and are not already properly scheduled.
If a problem is detected either when instanciating a virtual chunk or when doing pre checks some time before actually instanciating it, this problem is saved as Action object. This allows users to see and solve the problem before the recording should take place.
Attention: if the recording is initiated by the system or manually, the state of the recording is persisted and loses the dependency on the repeat pattern. A subsequent change of the recurrence rule does not change an initiated recording.
Automatic Instanciation of Virtual Chunks and Collision Detection
When a recurring is defined, real chunks are only created and scheduled for recordings in a defined range from now (e.g. in the next 24h). For each planned recording of the recurrence after that, no real chunk in the database is created, but so called virtual chunks are calculated for them if needed. This is for example needed to show the recordings in the frontend and by this allow the user to change single instances. If that is done, a chunk is created from a virtual chunk, no matter how long in the future the recording will be.
Besides this instanciation mechanism there is also an automatic pre check, that checks, if any problems are expected when instanciating virtual chunks in the near future. This is the case, if a needed device is offline, other chunks are blocking the recording etc. The pre check basically consists of a simulated scheduling of the virtual chunk. If any problem is found, it is saved as Action object. This is shown in the frontend and can be resolved there. Actions, that are resolved by e.g. moving blocking chunks, activating devices, adding devices to pools etc. are updated in the next run of the collision detector.
Note, that a passed pre check doesn’t guarantee a successful instanciation, as other possibly blocking virtual chunks are not taken into the simulated scheduling. Also other actions can lead to new blocking chunks, deactivated devices and so on.
Four values can be defined system wide, to control the automatic instanciation and collision detection:
Config Key | Description | Default Value |
---|---|---|
RecurringInstantiatorIntervalInMinutes | Defines how often virtual chunks for shortly imminent recordings should be instanciated automatically | 10 |
RecurringInstantiatorOffsetInMinutes | Defines the timespan from now in which virtual chunks are instanciated automatically (e.g. every recording not longer that 24h from now) | 1440 (24h) |
VirtualChunkCollisionDetectorIntervalInMinutes | Defines how often virtual chunks for shortly imminient recordings are pre checked | 60 |
VirtualChunkCollisionDetectorOffsetInMinutes | Defines the timespan from now in which virtual chunks are pre checked (e.g. every recording not longer that 48h from now) | 2880 (48h) |
Manual Instanciation and Resolving Collisions
Sometimes a single recording of a recurrence has to be changed. For example, sometimes a program is delayed or cancelled due to current events or a user wants to record the program with a different recorder on a specific date. To do this, changes can be done to virtual chunks. If that is the case, the virtual chunk is instanciated with the changes. If a virtual chunk is deleted, it is not instanciated but no longer calculated. Changes and deletions are both saved as RecurrenceException to handle them in the backend.
If a problem is detected during the pre checks or during the automatic instanciation, this mechanisms to delete and change single recordings of a recurrence can be used to solve that problem.
Properties
Property | Possible Values | Example | Description |
---|---|---|---|
id | String | 0B | External ID of the recurrence |
frequency | Integer | 2 | Defines how frequently the recurrence takes place. E.g. if set to 2, the recordings defined by the recurrence are executed every second week, if set to 1 every week. |
monday - sunday | Boolean | true | There is a parameter for each day of the week that defines, weather to do a recording on that weekday or not. |
startDate | DateTime | 2023-03-16T23:00:00Z | Defines the day the recurrence should start. Only the date is relevant here, not the time. |
endDate | DateTime | 2023-03-17T23:00:00Z | Defines the last day of the recurrence. Alternatively occurrences can be set. Only the date is relevant here, not the time. |
occurrences | Integer | 12 | Defines how many times the recurrence should take place / how often the recording should be performed. Alternatively endDate can be set. |
bookingContent |
JSON
| Specifies the recordings that should be executed for every instance of the recurrence |
Example JSON Snippet
{
"recurrence": {
"frequency": 1,
"sunday": false,
"monday": true,
"tuesday": true,
"wednesday": true,
"thursday": true,
"friday": true,
"saturday": false,
"startDate": "2023-05-09T20:13:11.320175Z",
"endDate": "2023-05-10T20:13:11.320175Z",
"bookingContent": {
"chunkList":
[{
"commandList": [
{
"capabilityId": "wl",
"deviceId": "0B",
"executionTime": "2023-05-09T20:13:11.320175Z",
"index": 0,
"handling": "WaitForResult",
"content": "{\"action\":\"Switch\",\"input\":{}}",
"commandType": "CapabilityRouter"
},
{
"capabilityId": "0B",
"poolId": "0B",
"executionTime": "2023-05-09T20:13:11.320175Z",
"duration": 3600,
"index": 1,
"handling": "WaitForResult",
"content": "{\"action\":\"Record\",\"input\":{}}",
"commandType": "CapabilityRecorder"
}
],
"title": "ItemTitle1"
}]
}
}
}