-
Notifications
You must be signed in to change notification settings - Fork 1
THC Core functions
The THC main program provides a set of core functions that are listed below. These functions are completed with additional ones provided by modules.
THC provides continuously information about ongoing activities activities, scheduled and executed jobs, and eventually encountered failures. The level of detail as well as the log destination is specified with the command thc::DefineLog. The command thc::Log is available to log a message. It is used by THC itself and by the provided extension modules, but it can also be used inside the user scripts and jobs.
The level of detail is defined by the log level which is specified in the following way:
Description | |
---|---|
0 | Everything is logged (every executed job, scheduled jobs, execution and states of commands provided by THC and its modules, etc) |
1 | Log jobs not executed every heartbeat, scheduled jobs, execution of many commands provided by THC and its modules, errors |
2 | Log jobs not executed every heartbeat, execution of main commands provided by THC and its modules, errors |
3 | Logs only important commands and errors |
Configures the activity logging. DefineLog opens the log file and specifies the level of details that will be logged. By default THC uses a log level of 2 and logs information to the standard output. Since the configuration file is loaded not on the beginning of the THC startup, some information will always be sent to the standard output, before the new log destination is specified inside the configuration file.
Parameters | Description |
---|---|
<LogFile> | Log file name. If the provided log file 'LogFile' is an empty string ('') or 'stdout', the log stream is routed to stdout. |
[<LogLevel>] | Log level, default: 2 |
-
thc::DefineLog stdout 1
thc::DefineLog "/var/thc/thc_server.log"
Log a message.
Parameters | Description |
---|---|
<Text> | Text to log, command, variable and backslash substitution will be performed in the context of the calling scope. |
[<Level>] | Log level, default: 3 |
-
thc::Log {Switch light on: $Device} 2
The following group of commands allows controlling the different devices.
Registers a device. This command registers a device with all the information relevant for the device. Once the device is registered its state is recorded and set via the global commands thc::Update and thc::Set, which call the commands specified respectively with the -get and -set command definition parameters.
A command definition is a list with a first element that specifies the target module and with one or multiple additional elements that specify the device details.
The state of a registered device is by default updated automatically each heartbeat. A slower update rate can be selected via the option -update. The provided update time interval uses the same time syntax as the absolute time definitions of the thc::DefineJob command. It is recommended to use reasonable slow update rates to reduce the interactions with the target devices (e.g. "1h" for battery updates, "10m" for weather data updates, etc.).
Devices can be defined that have neither a -get nor a -set command. These device are called dummy devices. They have no state, and they are not considered by the THC state update mechanism and by most THC modules. But dummy devices are devices shown by the web access. They allow adding to the website non state based elements like links, images, etc.
Parameters | Description |
---|---|
<Device> | Device identifier |
[-get <GetCommandDefinition>] | 'Get' command specification |
[-set <SetCommandDefinition>] | 'Set' command specification |
[-update <UpdateInterval>] | Update interval, same syntax as for <DefineJob>, default: 0 (continuous update) |
[-sticky 0|1] | Defines sticky behavior, default: 0 |
[-range <Range>] | Valid range specification. This is a list of a min and of a max value. Data outside of the specified range will be set to unknown (""). |
[-step <Step>] | Step size (used by the modules: thc_Web) |
[-inverse 0|1] | Performs logic state inversion, '' is defined if state is not numerical. |
[-gexpr <GetExpr>] | Performs an expression evaluation with the obtained value. The originally obtained value is accessed via the variable 'Value' (e.g. $Value-2.0). |
[-name <Name>] | Nice device name (used by the modules: thc_Rrd, thc_Web) |
[-type <Type>] | Device type (used by the modules: thc_Web) |
[-group <Group>] | Device group (used by the modules: thc_Web) |
[-format <Format>] | Value format, default: %s (used by the modules: thc_Web) |
[-data <Data>] | Associated data information (used by the modules: thc_Web) |
-
### Devices linked to a physical target ###
thc::DefineDevice Sirene,state \
-get {thc_zWay "SwitchBinary 16.0"} \
-set {thc_zWay "SwitchBinary 16.0"} \
-type switch
thc::DefineDevice Dimmer,state \
-get {thc_zWay "SwitchMultilevel 16.0"} \
-set {thc_zWay "SwitchMultilevel 16.0"} \
-type level -range {0 100}
thc::DefineDevice Sirene,battery -range {0 100} -update 1h \
-get {thc_zWay "Battery 16.0"} -gexpr {$Value-0.3}
### Device that acts on multiple physical targets ###
thc::DefineDevice DoubleSwitch,state \
-get {thc_zWay "SwitchBinary 8.0"} \
-set {thc_zWay "SwitchBinary 8.0" "SwitchBinary 8.1" "SwitchBinary 8.2"} \
-type switch
### Virtual device, stores a scenario ###
thc::DefineDevice Surveillance,state \
-name Surveillance -group Scenes -type switch \
-get {thc_Virtual "Surveillance"} \
-set {thc_Virtual "Surveillance"}
### Dummy devices that add elements to the website ###
thc::DefineDevice zWay,Links \
-type link -data http://192.168.1.21:8083
thc::DefineDevice Environment,1_day \
-name Environment -group "Graphs 1 day" \
-type image -data $::LogDir/thc_env_1d.png
thc::Update, thc::Set, thc::ResetStickyStates
Update device states. The device states will be stored inside the State array variable. A new state will be set to '' if getting the device state fails, or if the device state is not within a specified range.
Update has usually not to be called by a user script, since it is automatically called for each device in the device specific update interval.
Parameters | Description |
---|---|
<DeviceList> | Device list |
-
thc::Update {LightCorridor,state Siren,state}
Set device states. This command sets the state for one or multiple devices. The updated effective states will be stored inside the NextState array variable. The state change will be applied beginning of the next heartbeat cycle (e.g. the State array variable will be updated).
Parameters | Description |
---|---|
<DeviceList> | Device list |
<NewState> | New state |
-
thc::Set {LightCorridor,state LightCellar,state} 1
Get device states. This command returns the state for one or multiple devices.
Parameters | Description |
---|---|
<DeviceList> | Device list |
-
thc::Get {LightCorridor,state LightCellar,state}
{1 0}
Reset sticky states. Performs a reset of the registered sticky states.
-
thc::ResetStickyStates
The following commands allow defining and deleting jobs.
Registers a new job. A job is a command sequence that is executed either at a certain moment or in a certain interval. If a job with the same tag already exists it will be replaced by the new job.
Parameters | Description |
---|---|
[-tag <Tag>] | 8-character tag. A long string is reduced to 8 characters. Default: 'j<JobCounter>' |
[-time <Time>] | Job execution time. Absolute and relative time definitions are accepted (see 'Time definitions'). Default: "+0" (immediate execution) |
[-repeat <Repeat>] | Job repetition. Absolute time definitions are accepted. If a job needs to be continuously run the repeat time has to be set to 0. By default a job is not repeated. |
[-init_time <Initial time>] | Optional additional initial job execution. Absolute and relative time definitions are accepted. |
[-min_interval <MinimumInterval> | Minimal interval. A job will not be executed if the interval from the last execution is smaller than the specified one. By default there is not minimum interval constraint. Absolute time definitions are accepted. |
[-condition <Condition>] | Condition to execute the job. By default the jobs are executed unconditionally. The condition is evaluated at the top-level in the global namespace. |
[-description <Description>] | Job description for logging purposes. |
<Command> | Command sequence that is executed at the top-level in the global namespace. |
-
DefineJob accepts the following time definition formats :
Time definitions | Description |
---|---|
<integer> | The provided integer value is interpreted as number of seconds from the epoch time. This is the native manner Tcl handles time, e.g. 'clock scan' returns the time in this format. Examples: 1428751103 (this corresponds to: Apr 11 13:18:23 CEST 2015) |
[<h>h][<m>m][<s>s] | Specification of a day time in hours, minutes and seconds. Each unit can be omitted if its attributed value is 0. A value can have one or multiple digits (e.g. '5' or '05'). If the provided time is in the past in the current day the corresponding time in the next day is selected. Examples: 01h, 02h35m, 03h74m12s, 09M01D01h, 05W01h30m |
<Time/Date string> | Any time/date strings supported by the Tcl command 'clock scan' can be used. Examples: "13:30", "02/25/2015 13:30" |
+<RelativeTime> | By prefixing a time definition with '+' the time can be specified relative to the current time. Any formats supported for the interval definitions are also supported for the relative time definitions (see the next section). A job with a relative time of '+0' is executed during the next heartbeat. Example: +01h, +02h35m, +03h74m12s, +5, +0 |
If the evaluated time is in the past and an interval is defined then the time is moved to the next interval occurrence (see also 'Interval updates'). Otherwise the defined job will be executed immediately during the next heartbeat.
DefineJob accepts the following interval and relative time definition formats :
Interval definitions (also used for relative time definitions) | Description |
---|---|
<integer> | The interval corresponds to the provided integer value in seconds. The value '0' corresponds to the heartbeat period (e.g. the job is executed each heartbeat). Examples: 0, 1, 60, 360 |
[<Y>Y][<M>M][<W>W][<D>D][<h>h][<m>m][<s>s] | Time interval defined in years, months, weeks, days, hours, minutes and seconds. Each unit can be omitted if its attributed value is 0. A value can have one or multiple digits. Examples: 1D, 1M, 2W, 1D15h, 01h, 02h35m, 03h74m12s, 09M01D01h, 05W01h30m |
<'Clock add' string> | Time increment definition list accepted by the Tcl command 'clock add'. Examples: {1 minutes}, {1 days}, {1 hours 30 minutes} |
Interval updates are performed by respecting if necessary months lengths and daylight saving time changes. The updates follow the following rules :
Interval update arithmetic | Description |
---|---|
[<h>h][<m>m][<s>s] | An interval defined in hours, minutes and seconds is an absolute interval; the next occurrence happens exactly the specified interval later. A 24 hour interval (e.g. '24h') may therefore lead to different day time if a daylight saving time adjustment is happening. |
[<Y>Y][<M>M][<W>W][<D>D] | For interval definitions in years, months, weeks and days it is assured that each occurrence falls on the same day time as the original occurrence. If necessary the interval is extended or reduced by 1 hour to take into account daylight saving time changes. |
[<Y>Y][<M>M] | For interval definitions in years or months each occurrence falls respectively on the same day and same month day as the original occurrence. If a day doesn't exist (e.g. Feb 31) the last existing day is selected (e.g. Feb 28). |
# Some definitions
set AlarmSireneOffT 3m; # Defines how long the sirens have to run after an intrusion
set AlarmRetriggerT 5m; # Defines minimum alarm retrigger interval
set AlertMailRetriggerT 45m; # Minimum alert mail retrigger interval
# Check if any of the specified intrusion detection devices detected an activity:
proc GetSensorEvent {} {
foreach Sensor $SensorDeviceList {
if {$thc::Event($Sensor)==1} {return 1}
}
return 0
}
# Disable surveillance: Disable a running siren, disable alert related jobs
thc::DefineJob -tag SurvDis -description "Surveillance disabling" -repeat 0 -condition {$Event(Surveillance,state)==0} {
Set $SireneDeviceList 0
KillJob AlarmOn AlrtMail SirenOff
}
# Intrusion detection
thc::DefineJob -tag Intrusion -description "Intrusion detection" \
-repeat 0 -min_interval $AlarmRetriggerT \
-condition {$thc::State(Surveillance,state)==1 && [GetSensorEvent]} {
# An intrusion has been detected: Run new jobs to initiate the alarm and to send alert mails/SMS
# Run the sirens (next heartbeat)
DefineJob -tag AlarmOn -description "Start the alarm" {
Set $SireneDeviceList 1
}
# Send alert mails (2 seconds later)
DefineJob -tag AlrtMail -description "Send alert mail" -min_interval $AlertMailRetriggerT -time +2s {
thc_MailAlert::Send \
-to MyAlertMail@MyHome.home \
-from MySecuritySystem@MyHome.home \
-title "Intrusion detected" \
"Intrusion detected, [clock format $Time]"
}
# Stop running sirens automatically after a while
DefineJob -tag SirenOff -description "Stop the alarm siren" -time +$AlarmSireneOffT {
Set $SireneDeviceList 0
}
}
Kill one or multiple jobs.
Parameters | Description |
---|---|
<JobTag> | Jobs specified via its tags. This argument can be repeated to kill multiple jobs. |
-
thc::KillJob AlarmOn AlrtMail SirenOff LightOff RdmLight
Returns the currently scheduled jobs in form of a formatted string. Useful for debugging.
Parameters | Description |
---|---|
[WithPermanentJobs] | Adds permanent jobs to the generated string if set to 1. Default: 0. |
-
thc::JobsString
Assert a condition. This procedure assert that a condition is satisfied. If the provided condition is not true an error is raised.
Parameters | Description |
---|---|
<Condition> | Logic condition that needs to be satisfied |
<Message> | Error message |
-
thc::Assert {$Value<=1.0} "Define: The maximum allowed value is 1.0"
Defines the heart beat. This procedure defines the heart beat rate that is the interval in which THC updates the device states.
Parameters | Description |
---|---|
<HeartBeat> | Heart beat value |
[Unit] | Unit, accepted units are S and MS, default=MS |
-
thc::DefineHeartBeat 1000 ms
Performs HTTP transactions. This command performs HTTP transactions using the http::geturl command that is extended by following features:
- The URL query string is URL encoded
- Multiple trials are performed in case of timeouts (10 trials per default)
- Errors can optionally be caught
GetUrl performs by default non-persistent HTTP 1.1 GET requests using a timeout time of 5s, but these settings can be changed via the options.
Parameters | Description |
---|---|
<URL> | Uniform resource locator/web address |
[-noerror 0|1] | If set to 1 (default) no error is generated in case of a connection error. |
[-nbrtrials <NbrTrials>] | Defines the number of trials in case of connection timeouts. Default is 10. |
[-timeout <TimeoutMS>] | Option forwarded to http::geturl. Default is 5000. Allows defining the timeout in milliseconds. |
All other options defined with key-value pairs are forwarded to the http::geturl command.
List of the following 3 elements :
Returns | Description |
---|---|
Status code | HTTP status code (e.g. 200, 400, ...) |
Status text | HTTP status text (e.g. OK, Bad Request, ...) |
Response body | HTTP response body |
thc::GetUrl "http://ipecho.net/plain"
-> {200 OK 188.60.11.219}
thc::GetUrl "http://www.google.com/hello"
-> {404 {Not Found} {<html><body><h1>404 Not Found</h1></body></html>}}
State backup and restore mechanism. THC allows setting up a backup/restore mechanism that allows restoring important device states, variables, etc after a crash once THC is restarted. To use this mechanism a backup file needs to be specified first with thc::ConfigureRecoveryFile. Then, devices whose states should be restored can be declared with thc::DefineRecoveryDeviceStates. The restoration of custom settings and variables is defined with thc::DefineRecoveryCommand.
Defines the recovery file. This file needs to be specified before a recovery command or device is defined.
Parameters | Description |
---|---|
<RecoverFile> | Recovery file that stores the device states |
-
thc::ConfigureRecoveryFile "/var/thc/thc_server.state"
Defines a recovery command. The defined command will be added to the recovery file that is executed if THC restarts. Variables can be recovered by using 'set' as command. command.
Parameters | Description |
---|---|
<RecoveryId> | Recovery identifier |
[Command] | Recovery command. If omitted a previously defined recovery command will be deleted from the recovery file. |
-
thc::DefineRecoveryCommand DeviceState {Set Surveillance,state 0}
thc::DefineRecoveryCommand VariableState {set MyVar 123}
Defines device states that have to be backed up. The provided arguments are the devices whose states need to be backed up, and recovered during a restart of THC. Instead of providing as arguments multiple devices this command can also be executed once per device.
Parameters | Description |
---|---|
<Device>, [<Device>, ...] | List of devices whose states has to be backed up |
-
thc::DefineRecoveryDeviceStates Surveillance,state
THC, Tight Home Control - See THC index register - THC repository on github.com/Drolla/thc