This commit is contained in:
parent
e794d406f2
commit
c5f092fc72
3 changed files with 88 additions and 101 deletions
|
@ -35,6 +35,7 @@ Feel free to improve the program.
|
||||||
|
|
||||||
Revision history
|
Revision history
|
||||||
=================
|
=================
|
||||||
|
2008-02-11 0.1.4 Completely new switch logic, hopefully more robust with fewer bugs.
|
||||||
2008-02-10 0.1.3 Modified switch logic. When dawn is before on-time, lights are not switched on. If dusk time is after off time, lights are not switched on.
|
2008-02-10 0.1.3 Modified switch logic. When dawn is before on-time, lights are not switched on. If dusk time is after off time, lights are not switched on.
|
||||||
2008-01-30 0.1.2 Corrected a bug regarding datetimelocal.
|
2008-01-30 0.1.2 Corrected a bug regarding datetimelocal.
|
||||||
2008-01-15 0.1.1 Fixed some bugs. Added logfile capability.
|
2008-01-15 0.1.1 Fixed some bugs. Added logfile capability.
|
||||||
|
|
|
@ -16,7 +16,7 @@ $LOG_FILE = "/var/log/tellstickd";
|
||||||
# After this point you really shouldn't need to go
|
# After this point you really shouldn't need to go
|
||||||
$AUTHOR = "Magnus Juntti, juntti\@mail.com";
|
$AUTHOR = "Magnus Juntti, juntti\@mail.com";
|
||||||
$PROGRAM_NAME = "tellstickd";
|
$PROGRAM_NAME = "tellstickd";
|
||||||
$VERSION = "0.1.3";
|
$VERSION = "0.1.4";
|
||||||
|
|
||||||
|
|
||||||
# Structure of the configurations to be read;
|
# Structure of the configurations to be read;
|
||||||
|
@ -25,11 +25,12 @@ $VERSION = "0.1.3";
|
||||||
# $device_cfg[$i][2]; # Channel 1-3
|
# $device_cfg[$i][2]; # Channel 1-3
|
||||||
# $device_cfg[$i][3]; # On time
|
# $device_cfg[$i][3]; # On time
|
||||||
# $device_cfg[$i][4]; # Off time
|
# $device_cfg[$i][4]; # Off time
|
||||||
# $device_cfg[$i][5]; # Off when bright
|
# $device_cfg[$i][5]; # Off when bright, 0 = no, 1 = yes
|
||||||
# $device_cfg[$i][6]; # Off when bright delay
|
# $device_cfg[$i][6]; # Off when bright delay
|
||||||
# $device_cfg[$i][7]; # Time in advance when getting dark
|
# $device_cfg[$i][7]; # Time in advance when getting dark
|
||||||
# $device_cfg[$i][20]; # Sunrise off time, calculated in this program and stored here
|
# $device_cfg[$i][20]; # Sunrise off time, calculated in this program and stored here
|
||||||
# $device_cfg[$i][21]; # Sunset on time, calculated in this program and stored here
|
# $device_cfg[$i][21]; # Sunset on time, calculated in this program and stored here
|
||||||
|
# $device_cfg[$i][22]; # Switch state, 0 = off, 1 = on
|
||||||
|
|
||||||
sub daemonize {
|
sub daemonize {
|
||||||
chdir '/' or die "$PROGRAM_NAME: Can't chdir to /: $!";
|
chdir '/' or die "$PROGRAM_NAME: Can't chdir to /: $!";
|
||||||
|
@ -76,30 +77,67 @@ sub get_sunset_time
|
||||||
return $sunset_time;
|
return $sunset_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub is_sun_up
|
# Checks if $current_time is inbetween argument 1 ($time1) and argument 2 ($time2)
|
||||||
|
sub is_inbetween_times
|
||||||
{
|
{
|
||||||
$sunrise_time = get_sunrise_time();
|
my $time1 = $_[0];
|
||||||
$sunset_time = get_sunset_time();
|
my $time2 = $_[1];
|
||||||
|
|
||||||
# printf("sunrise: $sunrise_time\nsunset: $sunset_time\n");
|
my $curr_time = $current_time;
|
||||||
|
$curr_time =~ s/://g;
|
||||||
my $curr_time = sprintf("%0d%02d", $Hour, $Minute);
|
$time1 =~ s/://g;
|
||||||
$sunrise_time =~ s/://g;
|
$time2 =~ s/://g;
|
||||||
$sunset_time =~ s/://g;
|
|
||||||
|
|
||||||
#Remove leading zeroes.
|
|
||||||
$curr_time =~ s/^0*//;
|
$curr_time =~ s/^0*//;
|
||||||
$sunrise_time =~ s/^0*//;
|
$sunrise_time =~ s/^0*//;
|
||||||
$sunset_time =~ s/^0*//;
|
$sunset_time =~ s/^0*//;
|
||||||
|
|
||||||
# printf("curr_time = $curr_time, sunrise_time = $sunrise_time, sunset_time = $sunset_time\n");
|
# If we pass midnight, the following has to be checked
|
||||||
|
if ($time2 <= $time1) {
|
||||||
|
$time2 += 2400;
|
||||||
|
}
|
||||||
|
|
||||||
if ($curr_time > $sunrise_time && $curr_time < $sunset_time) {
|
if ($curr_time >= $time1 && $curr_time <= $time2) {
|
||||||
return $YES;
|
return $YES;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return $NO;
|
return $NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub rfcmd_exec {
|
||||||
|
my $device_id = $_[0];
|
||||||
|
my $action = $_[1];
|
||||||
|
|
||||||
|
|
||||||
|
# Action = 1 means turn lamp on
|
||||||
|
if ($action == 1) {
|
||||||
|
# Only turn the device on if it is not already turned on to avoid flashing dimmers.
|
||||||
|
if ($device_cfg[$device_id][22] == 0) {
|
||||||
|
printf("$PROGRAM_NAME: Time is $current_time. Switching on $device_cfg[$device_id][0] device $device_cfg[$device_id][1]$device_cfg[$device_id][2].\n");
|
||||||
|
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$device_id][0] $device_cfg[$device_id][1] $device_cfg[$device_id][2] 1`;
|
||||||
|
$device_cfg[$device_id][22] = 1;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
elsif ($action == 0) {
|
||||||
|
if ($device_cfg[$device_id][22] == 1) {
|
||||||
|
printf("$PROGRAM_NAME: Time is $current_time. Switching off $device_cfg[$device_id][0] device $device_cfg[$device_id][1]$device_cfg[$device_id][2].\n");
|
||||||
|
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$device_id][0] $device_cfg[$device_id][1] $device_cfg[$device_id][2] 0`;
|
||||||
|
$device_cfg[$device_id][22] = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub add_time
|
sub add_time
|
||||||
|
@ -185,7 +223,7 @@ sub read_config
|
||||||
{
|
{
|
||||||
my $input_file = $_[0];
|
my $input_file = $_[0];
|
||||||
|
|
||||||
printf("$PROGRAM_NAME: Reading configuration file $conf_file...\n");
|
printf("$PROGRAM_NAME: Reading configuration file $conf_file\n");
|
||||||
|
|
||||||
open(CFG_FILE, "<$input_file") or die "$PROGRAM_NAME: Could not access config file: $conf_file\n";
|
open(CFG_FILE, "<$input_file") or die "$PROGRAM_NAME: Could not access config file: $conf_file\n";
|
||||||
|
|
||||||
|
@ -202,6 +240,7 @@ sub read_config
|
||||||
$device_cfg[$i][5] = $inrad[5]; # Off when bright
|
$device_cfg[$i][5] = $inrad[5]; # Off when bright
|
||||||
$device_cfg[$i][6] = $inrad[6]; # Off when bright delay
|
$device_cfg[$i][6] = $inrad[6]; # Off when bright delay
|
||||||
$device_cfg[$i][7] = $inrad[7]; # Time in advance when getting dark
|
$device_cfg[$i][7] = $inrad[7]; # Time in advance when getting dark
|
||||||
|
$device_cfg[$i][22] = 1; # Initial state set to so that they will be switched of at startup
|
||||||
|
|
||||||
|
|
||||||
# Some sanity checks
|
# Some sanity checks
|
||||||
|
@ -335,7 +374,7 @@ if (length($conf_file) < 1) {
|
||||||
$conf_file = $CONFIG_FILE;
|
$conf_file = $CONFIG_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("$PROGRAM_NAME: Starting $PROGRAM_NAME version $VERSION...\n");
|
printf("$PROGRAM_NAME: Starting $PROGRAM_NAME version $VERSION\n");
|
||||||
|
|
||||||
# Read the configuration file
|
# Read the configuration file
|
||||||
$number_of_devices = read_config($conf_file);
|
$number_of_devices = read_config($conf_file);
|
||||||
|
@ -360,7 +399,7 @@ while (1) {
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
# First, lets set the sunrise and sunset times for the devices that applies to, once a day, at 00:00.
|
# First, lets set the sunrise and sunset times for the devices that it applies to, once a day, at 00:00.
|
||||||
if ($first_loop == $YES || $current_time eq "00:00") {
|
if ($first_loop == $YES || $current_time eq "00:00") {
|
||||||
my $sunrise_time = get_sunrise_time();
|
my $sunrise_time = get_sunrise_time();
|
||||||
printf("$PROGRAM_NAME: Sunrise today is expected at $sunrise_time\n");
|
printf("$PROGRAM_NAME: Sunrise today is expected at $sunrise_time\n");
|
||||||
|
@ -368,111 +407,57 @@ while (1) {
|
||||||
my $sunset_time = get_sunset_time();
|
my $sunset_time = get_sunset_time();
|
||||||
printf("$PROGRAM_NAME: Sunset today is expected at $sunset_time\n");
|
printf("$PROGRAM_NAME: Sunset today is expected at $sunset_time\n");
|
||||||
|
|
||||||
my $i = 0;
|
for (my $i = 0; $i < $number_of_devices; $i++) {
|
||||||
while($i < $number_of_devices) {
|
# Initially all devices are switched off to get a known state
|
||||||
|
if ($first_loop == $YES) {
|
||||||
|
rfcmd_exec($i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# If the device is supposed to be off daytime, the following applies
|
# If the device is supposed to be off daytime, the following applies
|
||||||
|
|
||||||
# Sunrise time + requested offset
|
# Sunrise time + requested offset
|
||||||
if ($device_cfg[$i][5] == $YES) {
|
if ($device_cfg[$i][5] == $YES) {
|
||||||
$device_cfg[$i][20] = add_time($sunrise_time, $device_cfg[$i][6]);
|
$device_cfg[$i][20] = add_time($sunrise_time, $device_cfg[$i][6]);
|
||||||
printf("$PROGRAM_NAME: Device $device_cfg[$i][1]$device_cfg[$i][2] sunrise off time set to $device_cfg[$i][20].\n");
|
printf("$PROGRAM_NAME: Device $device_cfg[$i][1]$device_cfg[$i][2] sunrise off time set to $device_cfg[$i][20].\n");
|
||||||
}
|
|
||||||
|
|
||||||
# Sunset time - requested offset
|
# Sunset time - requested offset
|
||||||
if ($device_cfg[$i][5] == $YES) {
|
|
||||||
$device_cfg[$i][21] = subtract_time($sunset_time, $device_cfg[$i][7]);
|
$device_cfg[$i][21] = subtract_time($sunset_time, $device_cfg[$i][7]);
|
||||||
printf("$PROGRAM_NAME: Device $device_cfg[$i][1]$device_cfg[$i][2] sunset on time set to $device_cfg[$i][21].\n");
|
printf("$PROGRAM_NAME: Device $device_cfg[$i][1]$device_cfg[$i][2] sunset on time set to $device_cfg[$i][21].\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
$i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
# Below the required actions are performed for each device
|
# Below the required actions are performed for each device
|
||||||
my $i = 0;
|
for ($i = 0; $i < $number_of_devices; $i++) {
|
||||||
while($i < $number_of_devices) {
|
|
||||||
|
|
||||||
|
|
||||||
|
# First if we consider daytime off
|
||||||
# ON
|
|
||||||
# This is where we turn devices on depending on the state of the sun and the settings in daytime savings field $device_cfg[$i][5]
|
|
||||||
if ($device_cfg[$i][3] eq $current_time) {
|
|
||||||
# In case daytime turn off is activated, check if sun is up before turning on lamp
|
|
||||||
if ($device_cfg[$i][5] == $YES) {
|
|
||||||
if (is_sun_up() == $NO) {
|
|
||||||
printf("$PROGRAM_NAME: Time is $current_time and the sun is not yet up. Turning on $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2].\n");
|
|
||||||
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$i][0] $device_cfg[$i][1] $device_cfg[$i][2] 1`;
|
|
||||||
}
|
|
||||||
# This is where we end up when daytime saving is on and the sun is already up
|
|
||||||
else {
|
|
||||||
printf("$PROGRAM_NAME: Time is $current_time and the sun is up. $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2] not turned on.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# If daytime turn off is not activated, always turn on the lamps on.
|
|
||||||
else {
|
|
||||||
printf("$PROGRAM_NAME: Time is $current_time. Turning on $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2].\n");
|
|
||||||
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$i][0] $device_cfg[$i][1] $device_cfg[$i][2] 1`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# DAWN / DUSK ACTIONS
|
|
||||||
# If on when bright feature is 1 (yes) then do the following (i.e. if lights are supposed to be turned off daytime)
|
|
||||||
if ($device_cfg[$i][5] == $YES) {
|
if ($device_cfg[$i][5] == $YES) {
|
||||||
# Sunrise turn off
|
if (is_inbetween_times($device_cfg[$i][3], $device_cfg[$i][4]) == $YES && is_inbetween_times($device_cfg[$i][20], $device_cfg[$i][21]) == $NO) {
|
||||||
if ($device_cfg[$i][20] eq $current_time) {
|
rfcmd_exec($i, 1);
|
||||||
printf("$PROGRAM_NAME: Time is $current_time. Turning off $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2].\n");
|
|
||||||
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$i][0] $device_cfg[$i][1] $device_cfg[$i][2] 0`;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
# Sunset turn on if the sunset turn on time is before the desired turn off time
|
rfcmd_exec($i, 0);
|
||||||
if ($device_cfg[$i][21] eq $current_time) {
|
|
||||||
my $t_off = $device_cfg[$i][4];
|
|
||||||
my $ss_on = $device_cfg[$i][21];
|
|
||||||
$t_off =~ s/://g;
|
|
||||||
$ss_on =~ s/://g;
|
|
||||||
$t_off =~ s/^0*//;
|
|
||||||
$ss_on =~ s/^0*//;
|
|
||||||
|
|
||||||
# If sunset on time is before the desired off time then turn the device on.
|
|
||||||
if ($ss_on < $t_off) {
|
|
||||||
printf("$PROGRAM_NAME: Time is $current_time. Turning on $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2].\n");
|
|
||||||
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$i][0] $device_cfg[$i][1] $device_cfg[$i][2] 1`;
|
|
||||||
}
|
|
||||||
# If the sunset on time is after the desired off time then do nothing
|
|
||||||
else {
|
|
||||||
printf("$PROGRAM_NAME: Time is $current_time. Not turning on $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2] since the desired turn off time is already passed.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Then if daytime off is not considered
|
||||||
|
else {
|
||||||
|
if (is_inbetween_times($device_cfg[$i][3], $device_cfg[$i][4]) == $YES) {
|
||||||
|
rfcmd_exec($i, 1);
|
||||||
# OFF
|
}
|
||||||
# This is where we turn devices off, we do this regardless of any other settings.
|
else {
|
||||||
if ($device_cfg[$i][4] eq $current_time) {
|
rfcmd_exec($i, 0);
|
||||||
printf("$PROGRAM_NAME: Time is $current_time. Turning off $device_cfg[$i][0] device $device_cfg[$i][1]$device_cfg[$i][2].\n");
|
}
|
||||||
`$RFCMD $TELLSTICK_DEVICE $device_cfg[$i][0] $device_cfg[$i][1] $device_cfg[$i][2] 0`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Move on to next device
|
|
||||||
$i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$first_loop = $NO;
|
$first_loop = $NO;
|
||||||
sleep(60); # Wait a while until next round should be less than or equal to a minute, [seconds]
|
sleep(60); # Wait a while until next round should be less than or equal to a minute [seconds].
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
# Configuration file for control of remote switches
|
# Configuration file for control of remote switches
|
||||||
#
|
#
|
||||||
#<protocol> <housecode> <channel> <on time> <off time> <off when bright yes/no> <off when bright delay in morning> <prelight in afternoon>
|
#<protocol> <housecode> <channel> <on time> <off time> <daytime off yes/no> <off when bright delay in morning> <prelight in afternoon>
|
||||||
# (no = 0, yes = 1)
|
# (no = 0, yes = 1)
|
||||||
# Multiple definitions are possible for each device
|
# Multiple definitions are possible for each device
|
||||||
#
|
#
|
||||||
|
# Setting <on time> and <off time> to the same means that the device will always be switched on
|
||||||
|
#
|
||||||
# Time format xx:yy where xx is hour and yy is minute
|
# Time format xx:yy where xx is hour and yy is minute
|
||||||
# If no turn on time or turn off time should be used. Note this with -1. See the example line below. Only to be used on turn on or turn off times.
|
# If no turn on time or turn off time should be used. Note this with -1. See the example line below. Only to be used on turn on or turn off times.
|
||||||
# NEXA A 1 -1 22:45 1 00:30 00:30
|
# NEXA A 1 -1 22:45 1 00:30 00:30
|
||||||
|
|
||||||
|
# Sample to control NEXA device A 1. Turn on device 05:30 turn off 22:45. Turn off the device 30 minutes after sunrise, turn on again 15 minutes before sunset.
|
||||||
# Sample to control NEXA device A 1
|
NEXA A 1 05:30 22:45 1 00:30 00:15
|
||||||
NEXA A 1 05:30 22:45 1 00:30 00:30
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue