Skip to content

Commit 9c8b559

Browse files
committed
res_alarmsystem: Add ability to spawn 2nd channel when sensor triggered.
Add the ability to spawn a channel that runs concurrently while a sensor is triggered. This can be used to sound an audible alarm (e.g. by ringing a bell chime or loud ringer) that stops when the sensor is restored to normal.
1 parent 240a5a5 commit 9c8b559

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

configs/samples/res_alarmsystem.conf.sample

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@
8080
;device = DAHDI/24
8181
;disarm_delay = 0 ; Do not require the system to be disarmed when this sensor is triggered (reporting is informational only)
8282

83+
;[waterpump] ; Section defining a water pump overflow relay, which closes when an overflow could occur
84+
;type = sensor
85+
;sensor_id = 3
86+
;clientid = myclient
87+
;device = DAHDI/25
88+
;disarm_delay = 1 ; Immediately trigger alarm when this sensor is triggered, since an inoperational pump could result in flooding
89+
;concurrent_device = DAHDI/44r8 ; Dial a bell chime with cadence 8 and keep ringing it (sounding alarm) while this sensor is triggered
90+
8391
;[keypad] ; Section defining alarm keypad settings. An alarm keypad can be instantiated by using AlarmKeypad()
8492
;type = keypad
8593
;client = myclient ; Client associated with these keypad settings

res/res_alarmsystem.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@
273273
<para>Consequently, to have a sensor that always triggers a breach alarm immediately, set this option to 1 second.</para>
274274
</description>
275275
</configOption>
276+
<configOption name="concurrent_device">
277+
<synopsis>Device to dial concurrently when the sensor is triggered</synopsis>
278+
<description>
279+
<para>An additional device that will be dialed simultaneously when the sensor is triggered.
280+
This device will be disconnected when the sensor is restored to normal.</para>
281+
<para>This can be used to sound an audible alarm while this sensor is triggered. For example, if a bell chime is connected to a specific
282+
channel, specifying that device for this setting will ensure that whenever this sensor is off-normal, the bell chime will be activated.</para>
283+
</description>
284+
</configOption>
276285
</configObject>
277286
<configObject name="keypad">
278287
<synopsis>Configuration section for a keypad</synopsis>
@@ -532,6 +541,7 @@ struct alarm_sensor {
532541
char sensor_id[AST_MAX_EXTENSION];
533542
int disarm_delay;
534543
const char *device;
544+
char *concurrent_device;
535545
AST_LIST_ENTRY(alarm_sensor) entry;
536546
unsigned int triggered:1; /* Sensor triggered? */
537547
char data[];
@@ -665,6 +675,9 @@ static void cleanup_server(struct alarm_server *s)
665675

666676
static void cleanup_sensor(struct alarm_sensor *s)
667677
{
678+
if (s->concurrent_device) {
679+
ast_free(s->concurrent_device);
680+
}
668681
ast_free(s);
669682
}
670683

@@ -2136,6 +2149,8 @@ static int load_config(void)
21362149
ast_copy_string(s->sensor_id, var->value, sizeof(s->sensor_id));
21372150
} else if (!strcasecmp(var->name, "disarm_delay") && !ast_strlen_zero(var->value)) {
21382151
s->disarm_delay = atoi(var->value);
2152+
} else if (!strcasecmp(var->name, "concurrent_device") && !ast_strlen_zero(var->value)) {
2153+
s->concurrent_device = ast_strdup(var->value);
21392154
} else {
21402155
ast_log(LOG_WARNING, "Unknown keyword in section '%s': %s at line %d of %s\n", cat, var->name, var->lineno, CONFIG_FILE);
21412156
}
@@ -2211,6 +2226,7 @@ static int alarmsensor_exec(struct ast_channel *chan, const char *data)
22112226
struct alarm_sensor *s;
22122227
time_t breach_time;
22132228
int is_egress;
2229+
struct ast_channel *concurrent_chan = NULL;
22142230

22152231
AST_DECLARE_APP_ARGS(args,
22162232
AST_APP_ARG(client);
@@ -2298,6 +2314,27 @@ static int alarmsensor_exec(struct ast_channel *chan, const char *data)
22982314
orig_app_device(c->keypad_device, NULL, "AlarmKeypad", c->name, c->cid_num, c->cid_name);
22992315
}
23002316

2317+
if (s->concurrent_device) {
2318+
int res;
2319+
char *tech, *resource = ast_strdupa(s->concurrent_device);
2320+
tech = strsep(&resource, "/");
2321+
concurrent_chan = new_channel(tech, resource);
2322+
if (!concurrent_chan) {
2323+
ast_log(LOG_ERROR, "Failed to set up concurrent channel\n");
2324+
} else {
2325+
/* Place the call, but don't wait on the answer */
2326+
res = ast_call(concurrent_chan, resource, 0);
2327+
if (res) {
2328+
ast_log(LOG_ERROR, "Failed to call on %s\n", ast_channel_name(concurrent_chan));
2329+
ast_hangup(concurrent_chan);
2330+
concurrent_chan = NULL;
2331+
} else {
2332+
ast_verb(3, "Called %s/%s\n", tech, resource);
2333+
ast_autoservice_start(concurrent_chan);
2334+
}
2335+
}
2336+
}
2337+
23012338
/* Now, wait for the sensor to be restored. This could be soon, it could not be. */
23022339
while (ast_safe_sleep(chan, 60000) != -1);
23032340

@@ -2310,6 +2347,9 @@ static int alarmsensor_exec(struct ast_channel *chan, const char *data)
23102347

23112348
cleanup:
23122349
AST_RWLIST_UNLOCK(&clients);
2350+
if (concurrent_chan) {
2351+
ast_hangup(concurrent_chan);
2352+
}
23132353
return -1; /* Never continue executing dialplan */
23142354
}
23152355

0 commit comments

Comments
 (0)