mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-12 22:56:34 +00:00
98_weekprofile: new module to manage week profiles
git-svn-id: https://svn.fhem.de/fhem/trunk@10244 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ce92adc00a
commit
905fb5b73f
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- feature: 98_weekprofile: new module to manage week profiles
|
||||
- feature: 49_SSCam: function "enable" and "disable" for SS-Cams added
|
||||
- change: 49_SSCam: changed timout of Http-calls to a higher value,
|
||||
commandref enhanced
|
||||
|
750
fhem/FHEM/98_weekprofile.pm
Normal file
750
fhem/FHEM/98_weekprofile.pm
Normal file
@ -0,0 +1,750 @@
|
||||
##############################################
|
||||
# $Id: 98_weekprofile.pm 0.01 2015-12-23 Risiko $
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
# define <name> weekprofile <device>
|
||||
#
|
||||
# Changelog
|
||||
#
|
||||
# V 0.01 2015-12-23 - first version
|
||||
##############################################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON; #libjson-perl
|
||||
|
||||
use vars qw(%defs);
|
||||
use vars qw($FW_ME);
|
||||
use vars qw($FW_wname);
|
||||
use vars qw($FW_subdir);
|
||||
|
||||
my @shortDays = ("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
|
||||
|
||||
my %DEV_READINGS;
|
||||
# MAX
|
||||
$DEV_READINGS{"Mon"}{"MAX"} = "weekprofile-2-Mon";
|
||||
$DEV_READINGS{"Tue"}{"MAX"} = "weekprofile-3-Tue";
|
||||
$DEV_READINGS{"Wed"}{"MAX"} = "weekprofile-4-Wed";
|
||||
$DEV_READINGS{"Thu"}{"MAX"} = "weekprofile-5-Thu";
|
||||
$DEV_READINGS{"Fri"}{"MAX"} = "weekprofile-6-Fri";
|
||||
$DEV_READINGS{"Sat"}{"MAX"} = "weekprofile-0-Sat";
|
||||
$DEV_READINGS{"Sun"}{"MAX"} = "weekprofile-1-Sun";
|
||||
|
||||
# HM-CC-RT-DN
|
||||
$DEV_READINGS{"Mon"}{"HM-CC-RT-DN"} = "R_2_tempListMon";
|
||||
$DEV_READINGS{"Tue"}{"HM-CC-RT-DN"} = "R_3_tempListTue";
|
||||
$DEV_READINGS{"Wed"}{"HM-CC-RT-DN"} = "R_4_tempListWed";
|
||||
$DEV_READINGS{"Thu"}{"HM-CC-RT-DN"} = "R_5_tempListThu";
|
||||
$DEV_READINGS{"Fri"}{"HM-CC-RT-DN"} = "R_6_tempListFri";
|
||||
$DEV_READINGS{"Sat"}{"HM-CC-RT-DN"} = "R_0_tempListSat";
|
||||
$DEV_READINGS{"Sun"}{"HM-CC-RT-DN"} = "R_1_tempListSun";
|
||||
|
||||
# HM-CC-TC
|
||||
$DEV_READINGS{"Mon"}{"HM-CC-TC"} = "R_2_tempListMon";
|
||||
$DEV_READINGS{"Tue"}{"HM-CC-TC"} = "R_3_tempListTue";
|
||||
$DEV_READINGS{"Wed"}{"HM-CC-TC"} = "R_4_tempListWed";
|
||||
$DEV_READINGS{"Thu"}{"HM-CC-TC"} = "R_5_tempListThu";
|
||||
$DEV_READINGS{"Fri"}{"HM-CC-TC"} = "R_6_tempListFri";
|
||||
$DEV_READINGS{"Sat"}{"HM-CC-TC"} = "R_0_tempListSat";
|
||||
$DEV_READINGS{"Sun"}{"HM-CC-TC"} = "R_1_tempListSun";
|
||||
|
||||
# HM-TC-IT-WM-W-EU
|
||||
$DEV_READINGS{"Mon"}{"HM-TC-IT-WM-W-EU"} = "R_P1_2_tempListMon";
|
||||
$DEV_READINGS{"Tue"}{"HM-TC-IT-WM-W-EU"} = "R_P1_3_tempListTue";
|
||||
$DEV_READINGS{"Wed"}{"HM-TC-IT-WM-W-EU"} = "R_P1_4_tempListWed";
|
||||
$DEV_READINGS{"Thu"}{"HM-TC-IT-WM-W-EU"} = "R_P1_5_tempListThu";
|
||||
$DEV_READINGS{"Fri"}{"HM-TC-IT-WM-W-EU"} = "R_P1_6_tempListFri";
|
||||
$DEV_READINGS{"Sat"}{"HM-TC-IT-WM-W-EU"} = "R_P1_0_tempListSat";
|
||||
$DEV_READINGS{"Sun"}{"HM-TC-IT-WM-W-EU"} = "R_P1_1_tempListSun";
|
||||
|
||||
##############################################
|
||||
sub weekprofile_getDeviceType($)
|
||||
{
|
||||
my ($device) = @_;
|
||||
|
||||
# determine device type
|
||||
my $devHash = $main::defs{$device};
|
||||
|
||||
my $type = undef;
|
||||
|
||||
if ($devHash->{TYPE} =~ /CUL_HM/){
|
||||
$type = AttrVal($device,"model","");
|
||||
}
|
||||
elsif ($devHash->{TYPE} =~ /MAX/){
|
||||
$type = "MAX";
|
||||
}
|
||||
elsif ($devHash->{TYPE} =~ /dummy/){
|
||||
$type = "MAX" if ($device =~ /.*MAX.*/); #dummy (FAKE WT) with name MAX inside for testing
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
|
||||
##############################################
|
||||
sub weekprofile_readDayProfile($@)
|
||||
{
|
||||
my ($device,$day,$type,$me) = @_;
|
||||
|
||||
my @times;
|
||||
my @temps;
|
||||
|
||||
$type = weekprofile_getDeviceType($device) if (!defined($type));
|
||||
return if (!defined($type));
|
||||
|
||||
my $reading = $DEV_READINGS{$day}{$type};
|
||||
|
||||
#Log3 $me, 5, "$me(ReadDayProfile): $reading";
|
||||
|
||||
if($type eq "MAX") {
|
||||
@temps = split('/',ReadingsVal($device,"$reading-temp",""));
|
||||
@times = split('/',ReadingsVal($device,"$reading-time",""));
|
||||
# only use to to interval 'from-to'
|
||||
for(my $i = 0; $i < scalar(@times); $i+=1){
|
||||
my $interval = $times[$i];
|
||||
my @parts = split('-',$interval);
|
||||
$times[$i] = ($parts[1] ne "00:00") ? $parts[1] : "24:00";
|
||||
}
|
||||
} else {
|
||||
# Homatic
|
||||
# get temp list for the day
|
||||
my $prf = ReadingsVal($device,$reading,"");
|
||||
# split into time temp time temp etc.
|
||||
# 06:00 17.0 22:00 21.0 24:00 17.0
|
||||
my @timeTemp = split(' ', $prf);
|
||||
|
||||
for(my $i = 0; $i < scalar(@timeTemp); $i += 2) {
|
||||
push(@times, $timeTemp[$i]);
|
||||
push(@temps, $timeTemp[$i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
for(my $i = 0; $i < scalar(@temps); $i+=1){
|
||||
$temps[$i] =~s/[^\d.]//g; #only numbers
|
||||
}
|
||||
|
||||
for(my $i = 0; $i < scalar(@times); $i+=1){
|
||||
$times[$i] =~ s/^\s+|\s+$//g; #trim whitespace both ends
|
||||
}
|
||||
return (\@times, \@temps);
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_readDevProfile(@)
|
||||
{
|
||||
my ($device,$type,$me) = @_;
|
||||
$type = weekprofile_getDeviceType($device) if (!defined($type));
|
||||
return "" if (!defined ($type));
|
||||
|
||||
my $prf = {};
|
||||
foreach my $day (@shortDays){
|
||||
my ($dayTimes, $dayTemps) = weekprofile_readDayProfile($device,$day,$type,$me);
|
||||
$prf->{$day}->{"temp"} = $dayTemps;
|
||||
$prf->{$day}->{"time"} = $dayTimes;
|
||||
}
|
||||
return $prf;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_createDefaultPofile(@)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $prf = {};
|
||||
|
||||
foreach my $day (@shortDays){
|
||||
my @times; push(@times, "24:00");
|
||||
my @temps; push(@temps, "18.0");
|
||||
|
||||
$prf->{$day}->{"temp"} = \@temps;
|
||||
$prf->{$day}->{"time"} = \@times;
|
||||
}
|
||||
return $prf;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_sendDevProfile(@)
|
||||
{
|
||||
my ($device,$prf,$me) = @_;
|
||||
my $type = weekprofile_getDeviceType($device);
|
||||
return "Error device type not supported" if (!defined ($type));
|
||||
|
||||
my $devPrf = weekprofile_readDevProfile($device,$type,$me);
|
||||
|
||||
# only send changed days
|
||||
my @dayToTransfer = ();
|
||||
foreach my $day (@shortDays){
|
||||
my $tmpCnt = scalar(@{$prf->{$day}->{"temp"}});
|
||||
next if ($tmpCnt <= 0);
|
||||
|
||||
if ($tmpCnt != scalar(@{$devPrf->{$day}->{"temp"}})) {
|
||||
push @dayToTransfer , $day;
|
||||
next;
|
||||
}
|
||||
|
||||
my $equal = 1;
|
||||
for (my $i = 0; $i < $tmpCnt; $i++) {
|
||||
if ( ($prf->{$day}->{"temp"}[$i] ne $devPrf->{$day}->{"temp"}[$i] ) ||
|
||||
$prf->{$day}->{"time"}[$i] ne $devPrf->{$day}->{"time"}[$i] ) {
|
||||
$equal = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ($equal == 0) {
|
||||
push @dayToTransfer , $day;
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar(@dayToTransfer) <=0) {
|
||||
Log3 $me, 4, "$me(sendDevProfile): nothing to do";
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $cmd;
|
||||
if($type eq "MAX") {
|
||||
$cmd = "set $device weekProfile ";
|
||||
foreach my $day (@dayToTransfer){
|
||||
my $tmpCnt = scalar(@{$prf->{$day}->{"temp"}});
|
||||
|
||||
$cmd.=$day.' ';
|
||||
|
||||
for (my $i = 0; $i < $tmpCnt; $i++) {
|
||||
my $endTime = $prf->{$day}->{"time"}[$i];
|
||||
|
||||
$endTime = ($endTime eq "24:00") ? ' ' : ','.$endTime.',';
|
||||
$cmd.=$prf->{$day}->{"temp"}[$i].$endTime;
|
||||
}
|
||||
}
|
||||
} else { #Homatic
|
||||
my $k=0;
|
||||
my $dayCnt = scalar(@dayToTransfer);
|
||||
foreach my $day (@dayToTransfer){
|
||||
$cmd .= "set $device tempList";
|
||||
$cmd .= $day;
|
||||
$cmd .= ($k < $dayCnt-1) ? " prep": " exec";
|
||||
|
||||
my $tmpCnt = scalar(@{$prf->{$day}->{"temp"}});
|
||||
for (my $i = 0; $i < $tmpCnt; $i++) {
|
||||
$cmd .= " ".$prf->{$day}->{"time"}[$i]." ".$prf->{$day}->{"temp"}[$i];
|
||||
}
|
||||
$cmd .= ($k < $dayCnt-1) ? ";;": "";
|
||||
$k++;
|
||||
}
|
||||
}
|
||||
$cmd =~ s/^\s+|\s+$//g;
|
||||
Log3 $me, 4, "$me(sendDevProfile): $cmd";
|
||||
fhem($cmd);
|
||||
return undef;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_assignDev($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $me = $hash->{NAME};
|
||||
|
||||
my $prf = undef;
|
||||
if ($hash->{MASTERDEV}->{NAME}) {
|
||||
my $type = weekprofile_getDeviceType($hash->{MASTERDEV}->{NAME});
|
||||
return if (!defined($type));
|
||||
|
||||
$hash->{MASTERDEV}->{TYPE} = $type;
|
||||
|
||||
my $prfDev = weekprofile_readDevProfile($hash->{MASTERDEV}->{NAME},$type, $me);
|
||||
|
||||
if(defined($prfDev)) {
|
||||
$prf = {};
|
||||
$prf->{DATA} = $prfDev;
|
||||
$prf->{NAME} = 'master';
|
||||
}
|
||||
$hash->{STATE} = "assigned";
|
||||
} else {
|
||||
my $prfDev = weekprofile_createDefaultPofile($hash);
|
||||
if(defined($prfDev)) {
|
||||
$prf = {};
|
||||
$prf->{DATA} = $prfDev;
|
||||
$prf->{NAME} = 'default';
|
||||
}
|
||||
$hash->{STATE} = "created";
|
||||
}
|
||||
|
||||
if(defined($prf)) {
|
||||
push @{$hash->{PROFILES}} , $prf;
|
||||
}
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash,"state",$hash->{STATE});
|
||||
readingsEndUpdate($hash, 1);
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_updateReadings($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
my $prfCnt = scalar(@{$hash->{PROFILES}});
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash,"profile_count",$prfCnt);
|
||||
|
||||
#readings with profile names???
|
||||
#my $idx = 1;
|
||||
#foreach my $prf (@{$hash->{PROFILES}}){
|
||||
#my $str = sprintf("profile_name_%02d",$idx);
|
||||
#readingsBulkUpdate($hash,$str,$prf->{NAME});
|
||||
#$idx++;
|
||||
#}
|
||||
readingsEndUpdate($hash, 1);
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{DefFn} = "weekprofile_Define";
|
||||
$hash->{SetFn} = "weekprofile_Set";
|
||||
$hash->{GetFn} = "weekprofile_Get";
|
||||
$hash->{SetFn} = "weekprofile_Set";
|
||||
$hash->{StateFn} = "weekprofile_State";
|
||||
$hash->{NotifyFn} = "weekprofile_Notify";
|
||||
$hash->{AttrList} = "widgetWeekdays configFile".$readingFnAttributes;
|
||||
|
||||
$hash->{FW_summaryFn} = "weekprofile_SummaryFn";
|
||||
|
||||
$hash->{FW_atPageEnd} = 1;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
|
||||
if(@a < 1) {
|
||||
my $msg = "wrong syntax: define <name> weekprofile [device]";
|
||||
Log3 undef, 2, $msg;
|
||||
return $msg;
|
||||
}
|
||||
|
||||
my $me = $a[0];
|
||||
|
||||
$hash->{MASTERDEV}->{NAME} = undef;
|
||||
$hash->{MASTERDEV}->{NAME} = $a[2] if (@a > 1);
|
||||
|
||||
$hash->{STATE} = "defined";
|
||||
my @profiles = ();
|
||||
$hash->{PROFILES} = \@profiles;
|
||||
|
||||
#$attr{$me}{verbose} = 5;
|
||||
return undef;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_Get($$@)
|
||||
{
|
||||
my ($hash, $name, $cmd, @params) = @_;
|
||||
|
||||
my $list = '';
|
||||
|
||||
my $prfCnt = scalar(@{$hash->{PROFILES}});
|
||||
$list.= 'profile_data:' if ($prfCnt > 0);
|
||||
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
$list.= $prf->{NAME}.",";
|
||||
}
|
||||
|
||||
$list = substr($list, 0, -1) if ($prfCnt > 0);
|
||||
|
||||
if($cmd eq "profile_data") {
|
||||
return "no profile" if ($prfCnt <= 0);
|
||||
|
||||
my $prf = undef;
|
||||
my $idx=0;
|
||||
if($params[0]){
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
last if ( $prf->{NAME} eq $params[0]);
|
||||
$idx++;
|
||||
}
|
||||
return "profile $params[0] not found" if ($idx >= $prfCnt);
|
||||
}
|
||||
$prf = $hash->{PROFILES}[$idx];
|
||||
|
||||
my $json = JSON->new;
|
||||
my $json_text = $json->encode($prf->{DATA});
|
||||
return $json_text;
|
||||
}
|
||||
|
||||
$list.= ' profile_names:noArg';
|
||||
if($cmd eq "profile_names") {
|
||||
my $names = '';
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
$names .=$prf->{NAME}.",";
|
||||
}
|
||||
$names = substr($names, 0, -1);
|
||||
return $names;
|
||||
}
|
||||
|
||||
|
||||
$list =~ s/ $//;
|
||||
return "Unknown argument $cmd choose one of $list";
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_Set($$@)
|
||||
{
|
||||
my ($hash, $me, $cmd, @params) = @_;
|
||||
|
||||
my $prfCnt = scalar(@{$hash->{PROFILES}});
|
||||
my $list = '';
|
||||
|
||||
$list.= "profile_data";
|
||||
if ($cmd eq 'profile_data') {
|
||||
return 'usage: profile_data <name> <json data>' if(@params < 2);
|
||||
|
||||
my $json = JSON->new;
|
||||
my $data = undef;
|
||||
eval { $data = $json->decode($params[1]); };
|
||||
if ($@) {
|
||||
Log3 $me, 1, "$me(Set): Error parsing profile data.";
|
||||
return "Error parsing profile data. No valid json format";
|
||||
};
|
||||
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
if ( $prf->{NAME} eq $params[0]){
|
||||
$prf->{DATA} = $data;
|
||||
# automatic we send master profile to master device
|
||||
if ($params[0] eq "master"){
|
||||
weekprofile_sendDevProfile($hash->{MASTERDEV}->{NAME},$prf->{DATA},$me);
|
||||
} else {
|
||||
weekprofile_writeProfilesToFile($hash);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
my $prfNew = {};
|
||||
$prfNew->{NAME} = $params[0];
|
||||
$prfNew->{DATA} = $data;
|
||||
push @{$hash->{PROFILES}}, $prfNew;
|
||||
weekprofile_updateReadings($hash);
|
||||
weekprofile_writeProfilesToFile($hash);
|
||||
return undef;
|
||||
}
|
||||
#----------------------------------------------------------
|
||||
$list.= ' send_to_device' if ($prfCnt > 0);
|
||||
|
||||
if ($cmd eq 'send_to_device') {
|
||||
return 'usage: send_to_device <profile name> [device]' if(@params < 1);
|
||||
|
||||
my $profile = $params[0];
|
||||
my $device = $hash->{MASTERDEV}->{NAME};
|
||||
|
||||
if (@params == 2){
|
||||
$device = $params[1];
|
||||
}
|
||||
|
||||
return "Error no master device" unless (defined($device));
|
||||
|
||||
my $found = undef;
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
if ( $prf->{NAME} eq $profile){
|
||||
$found = $prf;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
Log3 $me, 1, "$me(Set): Error unknown profile $profile";
|
||||
return "Error unknown profile $profile";
|
||||
}
|
||||
|
||||
my $ret = weekprofile_sendDevProfile($device,$found->{DATA},$me);
|
||||
Log3 $me, 1, "$me(Set): $ret" if ($ret);
|
||||
return $ret;
|
||||
}
|
||||
#----------------------------------------------------------
|
||||
$list.= " copy_profile";
|
||||
if ($cmd eq 'copy_profile') {
|
||||
return 'usage: copy_profile <source> <target>' if(@params < 2);
|
||||
|
||||
my $srcName = $params[0];
|
||||
my $destName= $params[1];
|
||||
my $prfSrc = undef;
|
||||
my $prfDest = undef;
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
$prfSrc = $prf if ($prf->{NAME} eq $srcName);
|
||||
$prfDest = $prf if ($prf->{NAME} eq $destName);
|
||||
}
|
||||
return "Error unknown profile $srcName" unless($prfSrc);
|
||||
Log3 $me, 4, "$me(Set): override profile $destName" if ($prfDest);
|
||||
|
||||
if ($prfDest){
|
||||
$prfDest->{DATA} = $prfSrc->{DATA}
|
||||
} else {
|
||||
$prfDest = {};
|
||||
$prfDest->{NAME} = $destName;
|
||||
$prfDest->{DATA} = $prfSrc->{DATA};
|
||||
push @{$hash->{PROFILES}}, $prfDest;
|
||||
}
|
||||
weekprofile_writeProfilesToFile($hash);
|
||||
weekprofile_updateReadings($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------
|
||||
$list.= " remove_profile";
|
||||
if ($cmd eq 'remove_profile') {
|
||||
return 'usage: remove_profile <name>' if(@params < 1);
|
||||
return 'Error master profile can not removed' if($params[0] eq "master");
|
||||
|
||||
my $delprf = undef;
|
||||
my $idx = 0;
|
||||
foreach my $prf (@{$hash->{PROFILES}}){
|
||||
if ( $prf->{NAME} eq $params[0]){
|
||||
$delprf = $prf;
|
||||
last;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
return "Error unknown profile $params[0]" unless($delprf);
|
||||
|
||||
splice(@{$hash->{PROFILES}},$idx, 1);
|
||||
weekprofile_writeProfilesToFile($hash);
|
||||
weekprofile_updateReadings($hash);
|
||||
return undef;
|
||||
}
|
||||
$list =~ s/ $//;
|
||||
return "Unknown argument $cmd, choose one of $list";
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_State($$$$)
|
||||
{
|
||||
my ($hash, $time, $name, $val) = @_;
|
||||
my $me = $hash->{NAME};
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_Notify($$)
|
||||
{
|
||||
my ($own, $dev) = @_;
|
||||
my $me = $own->{NAME}; # own name / hash
|
||||
my $devName = $dev->{NAME}; # Device that created the events
|
||||
|
||||
return undef if ($devName ne "global");
|
||||
|
||||
my $max = int(@{$dev->{CHANGED}}); # number of events / changes
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
my $s = $dev->{CHANGED}[$i];
|
||||
|
||||
next if(!defined($s));
|
||||
my ($what,$who) = split(' ',$s);
|
||||
|
||||
if ($what =~ m/INITIALIZED/) {
|
||||
Log3 $me, 5, "$me(Notify): assign to device $own->{MASTERDEV}->{NAME}" if (defined($own->{MASTERDEV}->{NAME}));
|
||||
weekprofile_assignDev($own);
|
||||
weekprofile_readProfilesFromFile($own);
|
||||
weekprofile_updateReadings($own);
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_writeProfilesToFile(@)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $me = $hash->{NAME};
|
||||
|
||||
my $filename = "./log/weekprofile-$me.cfg";
|
||||
$filename = AttrVal($me,"configFile",$filename);
|
||||
|
||||
Log3 $me, 5, "$me(writeProfileToFile): write profiles to $filename";
|
||||
my $ret = open(my $fh, '>', $filename);
|
||||
if (!$ret){
|
||||
Log3 $me, 1, "Could not open file '$filename' $!";
|
||||
return;
|
||||
}
|
||||
|
||||
my $json = JSON->new;
|
||||
my $start = (defined($hash->{MASTERDEV}->{NAME})) ? 1:0;
|
||||
my $prfCnt = scalar(@{$hash->{PROFILES}});
|
||||
for (my $i = $start; $i < $prfCnt; $i++) {
|
||||
print $fh $hash->{PROFILES}[$i]->{NAME}."=".$json->encode($hash->{PROFILES}[$i]->{DATA})."\n";
|
||||
}
|
||||
close $fh;
|
||||
}
|
||||
##############################################
|
||||
sub weekprofile_readProfilesFromFile(@)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $me = $hash->{NAME};
|
||||
|
||||
my $filename = "./log/weekprofile-$me.cfg";
|
||||
$filename = AttrVal($me,"configFile",$filename);
|
||||
|
||||
Log3 $me, 5, "$me(readProfilesFromFile): read profiles from $filename";
|
||||
|
||||
unless (-e $filename) {
|
||||
Log3 $me, 5, "$me(readProfilesFromFile): file do not exist '$filename'";
|
||||
return;
|
||||
}
|
||||
|
||||
my $ret = open(my $fh, '<:encoding(UTF-8)', $filename);
|
||||
if (!$ret){
|
||||
Log3 $me, 1, "$me(readProfilesFromFile): Could not open file '$filename' $!";
|
||||
return;
|
||||
}
|
||||
my $json = JSON->new;
|
||||
my $rowCnt = 0;
|
||||
while (my $row = <$fh>) {
|
||||
chomp $row;
|
||||
Log3 $me, 5, "$me(readProfilesFromFile): data row $row";
|
||||
my @data = split('=',$row);
|
||||
if(@data<2){
|
||||
Log3 $me, 1, "$me(readProfilesFromFile): incorrect data row";
|
||||
next;
|
||||
}
|
||||
my $prfData=undef;
|
||||
eval { $prfData = $json->decode($data[1]); };
|
||||
if ($@) {
|
||||
Log3 $me, 1, "$me(readProfilesFromFile): Error parsing profile data $data[1]";
|
||||
next;
|
||||
};
|
||||
|
||||
my $prfNew = {};
|
||||
$prfNew->{NAME} = $data[0];
|
||||
$prfNew->{DATA} = $prfData;
|
||||
|
||||
if (!$hash->{MASTERDEV}->{NAME} && $rowCnt == 0) {
|
||||
$hash->{PROFILES}[0] = $prfNew; # replace default
|
||||
} else {
|
||||
push @{$hash->{PROFILES}}, $prfNew;
|
||||
}
|
||||
$rowCnt++;
|
||||
}
|
||||
close $fh;
|
||||
}
|
||||
|
||||
##############################################
|
||||
sub weekprofile_SummaryFn()
|
||||
{
|
||||
my ($FW_wname, $d, $room, $extPage) = @_;
|
||||
my $hash = $defs{$d};
|
||||
|
||||
my $show_links = 1;
|
||||
$show_links = 0 if($FW_hiddenroom{detail});
|
||||
|
||||
my $html;
|
||||
|
||||
my $iconName = AttrVal($d, "icon", "edit_settings");
|
||||
my $icon = FW_iconName($iconName) ? FW_makeImage($iconName,$iconName,"icon") : "";
|
||||
$icon = "<a name=\"$d.edit\" onclick=\"weekprofile_DoEditWeek('$d')\" href=\"javascript:void(0)\">$icon</a>";
|
||||
|
||||
my $lnk = AttrVal($d, "alias", $d);
|
||||
$lnk = "<a name=\"$d.detail\" href=\"$FW_ME$FW_subdir?detail=$d\">$lnk</a>" if($show_links);
|
||||
|
||||
my $args = "weekprofile";
|
||||
my $curr = $hash->{PROFILES}[0]->{NAME};
|
||||
|
||||
$html .= "<table>";
|
||||
$html .= "<tr><td>";
|
||||
$html .= "<div class=\"devType\" id=\"weekprofile.$d.header\">";
|
||||
$html .= "<div class=\"devType\" id=\"weekprofile.menu.base\">";
|
||||
$html .= $icon." ".$lnk;
|
||||
$html .= "</di></div></td></tr>";
|
||||
$html .= "<tr><td>";
|
||||
$html .= "<div class=\"fhemWidget\" informId=\"$d\" cmd=\"\" arg=\"$args\" current=\"$curr\" dev=\"$d\">"; # div tag to support inform updates
|
||||
$html .= "</div>";
|
||||
$html .= "</td></tr>";
|
||||
$html .= "</table>";
|
||||
return $html;
|
||||
}
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=begin html
|
||||
|
||||
<a name="weekprofile"></a>
|
||||
<h3>weekprofile</h3>
|
||||
<ul>
|
||||
<b>ToDo: Übersetzung</b><br>
|
||||
|
||||
Mit dem Modul 'weekprofile' können mehrere Wochenprofile verwaltet und an unterschiedliche Geräte
|
||||
übertragen werden. Aktuell werden folgende Hardware unterstützt:
|
||||
<li>alle MAX Thermostate</li>
|
||||
<li>Homatic HM-CC-RT-DN </li>
|
||||
<li>Homatic HM-CC-TC </li>
|
||||
<li>Homatic HM-TC-IT-WM-W-EU</li>
|
||||
|
||||
Im Standardfall wird das Modul mit einem Geräte = 'Master-Gerät' assoziiert,
|
||||
um das Wochenprofil vom Gerät grafisch bearbeiten zu können und andere Profile auf das Gerät zu bringen.
|
||||
<br>
|
||||
<b>Achtung:</b> Das Übertragen von Wochenprofilen erfordet eine Menge an Credits.
|
||||
Dies wird vom Modul nicht berücksichtigt. So kann es sein, dass nach dem
|
||||
Setzen\Aktualisieren eines Profils das Proil im Modul nicht mit dem Profil im Gerät
|
||||
übereinstimmt.
|
||||
<br><br>
|
||||
<a name="weekprofiledefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> weekprofile [master device]</code><br>
|
||||
<br>
|
||||
Aktiviert das Modul. Bei der Angabe eines 'Master-Gerätes' wird das Profil 'master'
|
||||
entprechende dem Wochenrofil vom Gerät angelegt.
|
||||
Sonderbehandlung des 'master' Profils:
|
||||
<li>Kann nicht gelöscht werden</li>
|
||||
<li>Bei Ändern\Setzen des Proils wird es automatisch an das 'Master-Geräte' gesendet</li>
|
||||
<li>Es wird sind mit abgespeicht</li>
|
||||
<br>
|
||||
Wird kein 'Master-Gerätes' angegeben, wird ein 'default' Profil angelegt.
|
||||
</ul>
|
||||
|
||||
<a name="weekprofileset"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
<li>profile_data<br>
|
||||
<code>set <name> profile_data <profilname> <json data> </code><br>
|
||||
Es wird das Profil 'profilname' geändert. Die Profildaten müssen im json-Format übergeben werden.
|
||||
</li>
|
||||
<li>send_to_device<br>
|
||||
<code>set <name> send_to_device <profilname> [device] </code><br>
|
||||
Das Profil wird an ein Gerät übertragen. Wird kein Gerät angegeben, wird das 'Master-Gerät' verwendet.
|
||||
</li>
|
||||
<li>copy_profile<br>
|
||||
<code>set <name> copy_profile <quelle> <ziel> </code><br>
|
||||
Kopiert das Profil 'quelle' auf 'ziel'. 'ziel' wird überschrieben oder neu angelegt.
|
||||
</li>
|
||||
<li>remove_profile<br>
|
||||
<code>set <name> remove_profile <profilname> </code><br>
|
||||
Das Profil 'profilname' wird gelöscht.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<a name="weekprofileget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<li>profile_data<br>
|
||||
<code>get <name> profile_data <profilname> </code><br>
|
||||
Liefert die Profildaten von 'profilname' im json-Format
|
||||
</li>
|
||||
<li>profile_names<br>
|
||||
<code>set <name> profile_names</code><br>
|
||||
Liefert alle Profilnamen getrennt durch ','
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<a name="weekprofileattr"></a>
|
||||
<b>Attribute</b>
|
||||
<ul>
|
||||
<li>widgetWeekdays<br>
|
||||
Liste von Wochentagen getrennt durch ',' welche im Widget angzeigt werden.
|
||||
Beginnend bei Montag. z.B.
|
||||
<code>attr name widgetWeekdays Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag</code>
|
||||
</li>
|
||||
<li>configFile<br>
|
||||
Pfad und Dateiname wo die Profile gespeichert werden sollen.
|
||||
Default: ./log/weekprofile-<name>.cfg
|
||||
</li>
|
||||
<li>icon<br>
|
||||
Änders des Icons zum Bearbeiten
|
||||
Default: edit_settings
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
=end html
|
||||
|
||||
=cut
|
@ -664,3 +664,6 @@
|
||||
- added new function for running terms
|
||||
- improved commandref
|
||||
|
||||
- Wed Dec 23 2015 (risiko)
|
||||
- added new module 98_weekprofile to manage week profiles
|
||||
|
||||
|
@ -329,6 +329,7 @@ FHEM/98_structure.pm rudolfkoenig http://forum.fhem.de Automatis
|
||||
FHEM/98_telnet.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_update.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_weblink.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHME/98_weekprofile.pm risiko http://forum.fhem.de Frontends
|
||||
FHEM/99_SUNRISE_EL.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/99_Utils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/Blocking.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
@ -380,6 +381,7 @@ www/pgm2/fhemweb_readingsHistory.js justme1968 http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_sortable.js markusbloch http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_fbcalllist.js markusbloch http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_uzsu.js justme1968 http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_weekprofile.js risiko http://forum.fhem.de Frontends
|
||||
www/pgm2/* rudolfkoenig http://forum.fhem.de Frontends
|
||||
www/jscolor/* justme1968 http://forum.fhem.de Frontends
|
||||
www/frontend/* johannnes http://forum.fhem.de Frontends
|
||||
|
466
fhem/www/pgm2/fhemweb_weekprofile.js
Normal file
466
fhem/www/pgm2/fhemweb_weekprofile.js
Normal file
@ -0,0 +1,466 @@
|
||||
//fhemweb_weekprofile.js 0.01 2015-12-23 Risiko
|
||||
|
||||
//for tooltip
|
||||
$(document).ready(function(){
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
var shortDays = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
|
||||
|
||||
function FW_weekprofileInputDialog(title,inp,parent, callback)
|
||||
{
|
||||
var div = $("<div id='FW_weekprofileInputDiolog'>");
|
||||
var content = $('<input type="'+inp+'">').get(0);
|
||||
$(div).append(title);
|
||||
$(div).append(content);
|
||||
$("body").append(div);
|
||||
$(div).dialog({
|
||||
dialogClass:"no-close",modal:true, width:"auto", closeOnEscape:true,
|
||||
maxWidth:$(window).width()*0.9, maxHeight:$(window).height()*0.9,
|
||||
title: title,
|
||||
buttons: [{text:"OK", click:function(){
|
||||
$(this).dialog("close");
|
||||
$(div).remove();
|
||||
if(callback)
|
||||
callback(content.value,1);
|
||||
}},{text:"CANCEL", click:function(){
|
||||
$(this).dialog("close");
|
||||
$(div).remove();
|
||||
content.value = null;
|
||||
if(callback)
|
||||
callback(content.value,0);
|
||||
}}]
|
||||
});
|
||||
|
||||
if(parent)
|
||||
$(div).dialog( "option", "position", {
|
||||
my: "left top", at: "right bottom",
|
||||
of: parent, collision: "flipfit"
|
||||
});
|
||||
}
|
||||
|
||||
function weekprofile_DoEditWeek(devName)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
widget.MODE = 'EDIT';
|
||||
|
||||
$(widget.MENU.BASE).hide();
|
||||
|
||||
widget.setValueFn("REUSEPRF");
|
||||
}
|
||||
|
||||
function FW_weekprofilePRFCached(devName,select)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0)
|
||||
|
||||
var prfName = select.options[select.selectedIndex].value;
|
||||
|
||||
widget.CURPRF = prfName;
|
||||
widget.PROFILE = null;
|
||||
FW_queryValue('get '+devName+' profile_data '+prfName, widget);
|
||||
}
|
||||
|
||||
function FW_weekprofileSendToDev(devName,lnk)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0)
|
||||
|
||||
FW_weekprofileInputDialog("<span>Device:</span>","text",lnk,function(device,ok){
|
||||
if (!device || device.length <=0)
|
||||
return;
|
||||
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" send_to_device "+widget.CURPRF+" "+device+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
|
||||
});
|
||||
}
|
||||
|
||||
function FW_weekprofileCopyPrf(devName,lnk)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0)
|
||||
|
||||
FW_weekprofileInputDialog("<span>Name:</span>","text",lnk,function(name,ok){
|
||||
if (!name || name.length <=0)
|
||||
return;
|
||||
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" copy_profile "+widget.CURPRF+" "+name+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
|
||||
});
|
||||
}
|
||||
|
||||
function FW_weekprofileRemovePrf(devName,lnk)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0)
|
||||
|
||||
FW_weekprofileInputDialog("<p>Delete Profile: '"+widget.CURPRF+"' ?</p>","hidden",lnk,function(name,ok){
|
||||
if (ok < 1)
|
||||
return;
|
||||
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" remove_profile "+widget.CURPRF+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function FW_weekprofileShow(widget)
|
||||
{
|
||||
$(widget.MENU.BASE).show();
|
||||
$(widget.MENU.CONTENT).empty();
|
||||
|
||||
var html='';
|
||||
|
||||
if (widget.PROFILENAMES) {
|
||||
html += " "
|
||||
html += "<select name=\"PROFILES\" onchange=\"FW_weekprofilePRFCached('"+widget.DEVICE+"',this)\">";
|
||||
for (var k=0; k < widget.PROFILENAMES.length; k++)
|
||||
{
|
||||
var selected = (widget.CURPRF == widget.PROFILENAMES[k]) ? "selected " : "";
|
||||
html += "<option "+selected+"value=\""+widget.PROFILENAMES[k]+"\">"+widget.PROFILENAMES[k]+"</option>";
|
||||
}
|
||||
html += "</select>";
|
||||
|
||||
html += " "
|
||||
html += "<button type=\"button\"onclick=\"FW_weekprofileCopyPrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"copy profile\">+</button>";
|
||||
|
||||
html += " "
|
||||
html += "<button type=\"button\" onclick=\"FW_weekprofileRemovePrf('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"remove profile\">-</button>";
|
||||
|
||||
html += " "
|
||||
html += "<button type=\"button\" onclick=\"FW_weekprofileSendToDev('"+widget.DEVICE+"',this)\" data-toggle=\"tooltip\" title=\"send to device\">--></button>";
|
||||
|
||||
$(widget.MENU.CONTENT).append(html);
|
||||
}
|
||||
|
||||
if (!widget.PROFILE) {
|
||||
return;
|
||||
}
|
||||
|
||||
var table = widget.CONTENT;
|
||||
for (var i = 0; i < shortDays.length; ++i) {
|
||||
$(table).append('<tr class="'+ ( (i+1)%2==0 ? 'even':'odd')+ '"><td>'+shortDays[i]+'</td></tr>');
|
||||
|
||||
var tr = $(table).find("tr").get(i);
|
||||
|
||||
for (var k = 0; k < widget.PROFILE[shortDays[i]]['temp'].length; ++k) {
|
||||
|
||||
var str = '';
|
||||
k>0 ? str = widget.PROFILE[shortDays[i]]['time'][k-1] : str = '00:00';
|
||||
str = str + '-' + widget.PROFILE[shortDays[i]]['time'][k];
|
||||
|
||||
$(tr).append('<td>'+str+ '</td>');
|
||||
|
||||
str = widget.PROFILE[shortDays[i]]['temp'][k]+' °C';
|
||||
$(tr).append('<td>'+str+ '</td>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function FW_weekprofileEditTimeChanged(inp)
|
||||
{
|
||||
if (inp == null) {return;}
|
||||
var times = inp.value.split(':');
|
||||
if (times.length == 0)
|
||||
return;
|
||||
|
||||
var hour = parseInt(times[0]);
|
||||
var min = (times.length==2) ? parseInt(times[1]): 0;
|
||||
|
||||
inp.value = ((hour<10)?("0"+hour):hour) +":"+ ((min<10)?("0"+min):min);
|
||||
|
||||
//set new end time as new start time for the next interval
|
||||
var nexttr = inp.parentNode.parentNode.nextSibling;
|
||||
if (nexttr!=null){
|
||||
nexttr.firstChild.firstChild.innerHTML=inp.value;
|
||||
}
|
||||
}
|
||||
|
||||
function FW_weekprofileEditRowStyle(table)
|
||||
{
|
||||
var alltr = $(table).find("tr");
|
||||
for (var i = 0; i < alltr.length; ++i){
|
||||
var delButton = $(alltr[i]).find('input[name="DEL"]');
|
||||
var addButton = $(alltr[i]).find('input[name="ADD"]');
|
||||
var inp = $(alltr[i]).find('input[name="ENDTIME"]');
|
||||
|
||||
$(alltr[i]).attr('class',(i%2==0)? "odd":"even");
|
||||
delButton.attr('type',"button");
|
||||
addButton.attr('type',"button");
|
||||
inp.removeAttr('style');
|
||||
inp.removeAttr('readonly');
|
||||
|
||||
FW_weekprofileEditTimeChanged(inp.get(0));
|
||||
|
||||
if (i==0){
|
||||
$(alltr[i]).find('span[name="STARTTIME"]').get(0).innerHTML = "00:00";
|
||||
if (alltr.length == 1){
|
||||
delButton.attr('type',"hidden");
|
||||
}
|
||||
}
|
||||
|
||||
if (i==alltr.length-1){
|
||||
if (alltr.length > 1){
|
||||
addButton.attr('type',"hidden");
|
||||
}
|
||||
inp.attr('style',"border:none;background:transparent;box-shadow:none");
|
||||
inp.get(0).value = "24:00";
|
||||
inp.attr('readonly',true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function FW_weekprofileEditAddInterval(tr)
|
||||
{
|
||||
var newtr = $(tr).clone(true);
|
||||
|
||||
var alltr = $(tr).parent().children();
|
||||
for (var i = 0; i < alltr.length; ++i) {
|
||||
if ( $(alltr[i]).is($(tr))) {
|
||||
newtr.insertAfter($(alltr[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FW_weekprofileEditRowStyle($(tr).parent());
|
||||
|
||||
var timSel = newtr.find('input[name="ENDTIME"]');
|
||||
|
||||
if (alltr.length == 1)
|
||||
timSel = $(tr).find('input[name="ENDTIME"]');
|
||||
|
||||
timSel.focus();
|
||||
timSel.select();
|
||||
}
|
||||
|
||||
function FW_weekprofileEditDelInterval(tr)
|
||||
{
|
||||
var parent = $(tr).parent();
|
||||
$(tr).remove();
|
||||
FW_weekprofileEditRowStyle(parent)
|
||||
}
|
||||
|
||||
function FW_weekprofileEditDay(widget,day)
|
||||
{
|
||||
var div = $("<div>").get(0);
|
||||
$(div).append("<div style=\"margin-left:10px;margin:5px\">"+widget.WEEKDAYS[day]+"</div>");
|
||||
|
||||
var table = $("<table>").get(0);
|
||||
$(table).attr('id',"weekprofile."+widget.DEVICE+"."+shortDays[day]);
|
||||
$(table).attr('class',"block wide weekprofile");
|
||||
|
||||
var html;
|
||||
var times = widget.PROFILE[shortDays[day]]['time'];
|
||||
var temps = widget.PROFILE[shortDays[day]]['temp'];
|
||||
|
||||
for (var i = 0; i < times.length; ++i) {
|
||||
var startTime = (i>0) ? times[i-1] : "00:00";
|
||||
var endTime = (i<times.length-1) ? times[i] : "24:00";
|
||||
|
||||
html += "<tr>";
|
||||
//from
|
||||
html += "<td><span name=\"STARTTIME\">"+startTime+"</span></td>";
|
||||
|
||||
html += "<td>-</td>";
|
||||
//to
|
||||
html += "<td><input type=\"text\" name=\"ENDTIME\" size=\"5\" maxlength=\"5\" align=\"center\" value=\""+endTime+"\" onblur=\"FW_weekprofileEditTimeChanged(this)\"/></td>";
|
||||
|
||||
//temp
|
||||
html += "<td><select name=\"TEMP\" size=\"1\">";
|
||||
for (var k=5; k <= 30; k+=.5)
|
||||
{
|
||||
var selected = (k == temps[i]) ? "selected " : "";
|
||||
html += "<option "+selected+"value=\""+k.toFixed(1)+"\">"+k.toFixed(1)+"</option>";
|
||||
}
|
||||
html += "</select></td>";
|
||||
//ADD-Button
|
||||
html += "<td><input type=\"button\" name=\"ADD\" value=\"+\" onclick=\"FW_weekprofileEditAddInterval(this.parentNode.parentNode)\"></td>";
|
||||
//DEL-Button
|
||||
html += "<td><input type=\"button\" name=\"DEL\" value=\"-\" onclick=\"FW_weekprofileEditDelInterval(this.parentNode.parentNode)\"></td>";
|
||||
html += "</tr>";
|
||||
}
|
||||
$(table).append(html);
|
||||
$(div).append(table);
|
||||
FW_weekprofileEditRowStyle(table);
|
||||
return div;
|
||||
}
|
||||
|
||||
function FW_weekprofileEditWeek(widget)
|
||||
{
|
||||
var table = widget.CONTENT;
|
||||
var daysInRow = 2;
|
||||
|
||||
$(table).append('<tr>');
|
||||
var tr = $(table).find("tr:last");
|
||||
|
||||
for (var i = 0; i < shortDays.length; ++i) {
|
||||
tr.append('<td>');
|
||||
tr.find('td:last').append(FW_weekprofileEditDay(widget,i));
|
||||
|
||||
if ((i+1)%daysInRow == 0){
|
||||
$('<tr>').insertAfter(tr);
|
||||
tr = $(table).find("tr:last");
|
||||
}
|
||||
}
|
||||
|
||||
tr.append("<td><table><tr>");
|
||||
tr = tr.find("tr:last");
|
||||
tr.append("<td><input type=\"button\" value=\"Speichern\" onclick=\"FW_weekprofilePrepAndSendProf('"+widget.DEVICE+"')\">");
|
||||
tr.append("<td><input type=\"button\" value=\"Abbrechen\" onclick=\"FW_weekprofileEditAbort('"+widget.DEVICE+"')\">");
|
||||
}
|
||||
|
||||
function FW_weekprofileSendCallback(devName, data)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
if(!data.match(/^[\r\n]*$/)) // ignore empty answers
|
||||
FW_okDialog('<pre>'+data+'</pre>',widget);
|
||||
}
|
||||
|
||||
function FW_weekprofilePrepAndSendProf(devName)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
|
||||
var tableDay = $(widget).find("table[id*=\"weekprofile."+devName+"\"]");
|
||||
|
||||
if (tableDay.length == 0){
|
||||
FW_errmsg(widget.DEVICE+" internal error ",10000);
|
||||
return;
|
||||
}
|
||||
|
||||
var prf=new Object();
|
||||
for (var i = 0; i < tableDay.length; ++i) {
|
||||
var timeEL = $(tableDay[i]).find('input[name="ENDTIME"]');
|
||||
var tempEL = $(tableDay[i]).find('select[name="TEMP"]');
|
||||
|
||||
if (timeEL.length != tempEL.length){
|
||||
FW_errmsg(widget.DEVICE+" internal error ",10000);
|
||||
return;
|
||||
}
|
||||
|
||||
var id = $(tableDay[i]).attr('id').split('.');
|
||||
var day = id[2];
|
||||
|
||||
prf[day] = new Object();
|
||||
prf[day]['time'] = new Array();
|
||||
prf[day]['temp'] = new Array();
|
||||
|
||||
for (var k = 0; k < timeEL.length; ++k) {
|
||||
prf[day]['time'].push(timeEL[k].value);
|
||||
prf[day]['temp'].push(tempEL[k].value);
|
||||
}
|
||||
}
|
||||
try {
|
||||
var data=JSON.stringify(prf);
|
||||
FW_cmd(FW_root+"?cmd=set "+widget.DEVICE+" profile_data "+widget.CURPRF+" "+data+"&XHR=1",function(arg) {FW_weekprofileSendCallback(widget.DEVICE,arg);});
|
||||
} catch(e){
|
||||
FW_errmsg(devName+" Parameter "+e,5000);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < shortDays.length; ++i) {
|
||||
var day = shortDays[i];
|
||||
if (prf[day] != null){
|
||||
widget.PROFILE[day] = prf[day];
|
||||
}
|
||||
}
|
||||
widget.MODE = "SHOW";
|
||||
widget.setValueFn("REUSEPRF");
|
||||
}
|
||||
|
||||
function FW_weekprofileEditAbort(devName)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
widget.MODE = "SHOW";
|
||||
widget.setValueFn("REUSEPRF");
|
||||
}
|
||||
|
||||
function FW_weekprofileSetValue(devName,data)
|
||||
{
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
$(widget.CONTENT).empty();
|
||||
|
||||
var prf={};
|
||||
try {
|
||||
(data == "REUSEPRF") ? prf = widget.PROFILE : prf=JSON.parse(data);
|
||||
} catch(e){
|
||||
console.log(devName+" error parsing json '" +data+"'");
|
||||
FW_errmsg(devName+" Parameter "+e,5000);
|
||||
return;
|
||||
}
|
||||
|
||||
widget.PROFILE = prf;
|
||||
if (widget.MODE == 'SHOW' || widget.MODE == 'CREATE')
|
||||
{
|
||||
FW_weekprofileShow(widget);
|
||||
}
|
||||
else if (widget.MODE == 'EDIT')
|
||||
{
|
||||
FW_weekprofileEditWeek(widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
FW_errmsg(devName+" unknown Mode",10000);
|
||||
}
|
||||
}
|
||||
|
||||
function FW_weekprofileGetValues(devName,what,data)
|
||||
{
|
||||
if(data.match(/^[\r\n]*$/)) {return;}
|
||||
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
|
||||
if (what == "WEEKDAYS"){
|
||||
widget.WEEKDAYS = data.split(',');
|
||||
} else if (what == "PROFILENAMES") {
|
||||
widget.PROFILENAMES = data.split(',');
|
||||
if (widget.MODE != 'EDIT') {
|
||||
widget.setValueFn("REUSEPRF");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
FW_weekprofileCreate(elName, devName, vArr, currVal, set, params, cmd)
|
||||
{
|
||||
if( 0 ) {
|
||||
console.log( "elName: "+elName );
|
||||
console.log( "devName: "+devName );
|
||||
console.log( "vArr: "+vArr );
|
||||
console.log( "currVal: "+currVal );
|
||||
console.log( "set: "+set );
|
||||
console.log( "params: "+params );
|
||||
console.log( "cmd: "+cmd );
|
||||
}
|
||||
|
||||
if(!vArr.length || vArr[0] != "weekprofile")
|
||||
return undefined;
|
||||
|
||||
var widget = $('div[informid="'+devName+'"]').get(0);
|
||||
|
||||
var content = $('<table class="block wide weekprofile" id="weekprofile_content">').get(0);
|
||||
$(widget).append(content);
|
||||
|
||||
widget.CONTENT = content;
|
||||
widget.HEADER = $('div[id="weekprofile.'+devName+'.header"]').get(0);
|
||||
|
||||
widget.MENU = new Object();
|
||||
widget.MENU.BASE = $(widget.HEADER).find('div[id*="menu.base"]').get(0);
|
||||
|
||||
var menu = $('<div class="devType" id="weekprofile.menu.content" style="display:inline;padding:0px;margin:0px;">').get(0);
|
||||
$(widget.MENU.BASE).append(menu);
|
||||
widget.MENU.CONTENT = menu;
|
||||
|
||||
//inform profile_count changed
|
||||
var prfCnt = $('<div informid="'+devName+'-profile_count" style="display:none">').get(0);
|
||||
prfCnt.setValueFn = function(arg){
|
||||
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
|
||||
}
|
||||
$(widget.HEADER).append(prfCnt);
|
||||
|
||||
widget.MODE = 'CREATE';
|
||||
widget.DEVICE = devName;
|
||||
widget.WEEKDAYS = shortDays.slice();
|
||||
widget.CURPRF = currVal;
|
||||
|
||||
widget.setValueFn = function(arg){FW_weekprofileSetValue(devName,arg);}
|
||||
widget.activateFn = function(arg){
|
||||
FW_queryValue('get '+devName+' profile_data '+widget.CURPRF, widget);
|
||||
FW_cmd(FW_root+'?cmd={AttrVal("'+devName+'","widgetWeekdays","")}&XHR=1',function(data){FW_weekprofileGetValues(devName,"WEEKDAYS",data);});
|
||||
FW_cmd(FW_root+'?cmd=get '+devName+' profile_names&XHR=1',function(data){FW_weekprofileGetValues(devName,"PROFILENAMES",data);});
|
||||
};
|
||||
return widget;
|
||||
}
|
||||
|
||||
FW_widgets['weekprofile'] = {
|
||||
createFn:FW_weekprofileCreate,
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user