-
Notifications
You must be signed in to change notification settings - Fork 1
/
99_attrT_z2m_thermostat_Utils.pm
195 lines (166 loc) · 6.62 KB
/
99_attrT_z2m_thermostat_Utils.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
##############################################
# $Id: 99_attrT_z2m_thermostat_Utils.pm 24890 mod 2021-08-30 Beta-User $
#
package FHEM::attrT_z2m_thermostat_Utils; ## no critic 'Package declaration'
use strict;
use warnings;
use JSON qw(decode_json);
use Carp qw(carp);
use Scalar::Util qw(looks_like_number);
#use POSIX qw(strftime);
#use List::Util qw( min max );
#use Scalar::Util qw(looks_like_number);
#use Time::HiRes qw( gettimeofday );
use GPUtils qw(GP_Import);
## Import der FHEM Funktionen
#-- Run before package compilation
BEGIN {
# Import from main context
GP_Import(
qw(
AttrVal
InternalVal
ReadingsVal
ReadingsNum
ReadingsAge
CommandGet
CommandSet
readingsSingleUpdate
json2nameValue
defs
Log3
IsWe
)
);
}
sub ::attrT_z2m_thermostat_Utils_Initialize { goto &Initialize }
# initialize ##################################################################
sub Initialize {
my $hash = shift;
return;
}
# Enter you functions below _this_ line.
my %jsonmap = (
);
sub z2t_send_weekprofile {
my $name = shift // carp q[No device name provided!] && return;
my $wp_name = shift // carp q[No weekprofile device name provided!] && return;
my $wp_profile = shift // carp q[No weekprofile profile name provided!] && return;
my $model = shift // ReadingsVal($name,'week','5+2');
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
my $hash = $defs{$name};
$topic .= ' ';
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
Log3( $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available" );
return;
}
my @D = qw(Sun Mon Tue Wed Thu Fri Sat); # eqals to my @D = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
my $payload;
my @days = (0..6);
my $decoded;
if ( !eval { $decoded = decode_json($wp_profile_data) ; 1 } ) {
Log3($name, 1, "JSON decoding error in $wp_profile provided by $wp_name: $@");
return;
}
if ( $model eq '5+2' || $model eq '6+1') {
@days = (0,1);
} elsif ($model eq '7') {
@days = (1);
}
for my $i (@days) {
$payload = '{';
for my $j (0..7) {
if (defined $decoded->{$D[$i]}{'time'}[$j]) {
my $time = $decoded->{$D[$i]}{'time'}[$j-1] // "00:00";
my ($hour,$minute) = split m{:}xms, $time;
$hour = 0 if $hour == 24;
$payload .= '"hour":' . abs($hour) .',"minute":'. abs($minute) .',"temperature":'.$decoded->{$D[$i]}{'temp'}[$j];
$payload .= '},{' if defined $decoded->{$D[$i]}{'time'}[$j+1];
}
}
$payload .='}';
if ( $i == 0 && ( $model eq '5+2' || $model eq '6+1') ) {
CommandSet($hash,"$name holidays $payload");
$payload = '{';
}
CommandSet($hash,"$name workdays $payload") if $model eq '5+2' || $model eq '6+1' || $model eq '7';
}
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
return;
}
sub z2t_send_Beca_weekprofile {
my $name = shift // carp q[No device name provided!] && return;
my $wp_name = shift // carp q[No weekprofile device name provided!] && return;
my $wp_profile = shift // carp q[No weekprofile profile name provided!] && return;
my $topic = shift // carp q[No topic to send to provided!] && return;
my $hash = $defs{$name};
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
Log3( $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available" );
return;
}
my @D = qw(Sun Mon Tue Wed Thu Fri Sat); # eqals to my @D = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
my $payload;
my @days = (0,1,6);
my $decoded;
if ( !eval { $decoded = decode_json($wp_profile_data) ; 1 } ) {
Log3($name, 1, "JSON decoding error in $wp_profile provided by $wp_name: $@");
return;
}
for my $i (@days) {
my $sd = $i == 0 ? 'u' : $i == 6 ? 'a' : 'w';
for my $j (0..5) {
my $time = $decoded->{$D[$i]}{'time'}[$j];
last if !defined $time;
my $tmp = $decoded->{$D[$i]}{'temp'}[$j];
my $k = $j+1;
next if !looks_like_number($tmp);
$payload .= defined $payload ? ',' : '{';
$payload .= qq("${sd}${k}h":"$time","${sd}${k}t":$tmp);
}
}
Log3($hash,3,"$payload");
return if !defined $payload;
$payload .='}';
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
return qq{$topic $payload};
}
1;
__END__
=pod
=item summary helper functions needed for zigbee2mqtt thermostats in MQTT2_DEVICE
=item summary_DE Hilfsfunktionen für zigbee2mqtt MQTT2_DEVICE-Thermostate
=begin html
<a id="attrT_z2m_thermostat_Utils"></a>
There may be room for improvement, please adress any issues in https://forum.fhem.de/index.php/topic,116535.0.html.
<h3>attrT_z2m_thermostat_Utils</h3>
<ul>
<b>z2t_send_weekprofile</b>
<br>
This is a special function to request temperature list data from <i>weekprofile</i> and convert and send it out via MQTT<br>
<br>
General requirements and prerequisites:<br>
<ul>
<li>existing <i>weekprofile</i> device with activated <i>useTopic</i> feature</li>
<li>weekprofile attribute set at calling MQTT2_DEVICE</li>
</ul>
<br>
Special remarks for usage with attrTemplate <i>zigbee2mqtt_thermostat_with_weekrofile</i>:<br>
<ul>
<li>existing <i>setList</i> entries required (<i>workdays</i> and <i>holidays</i>)</li>
<li>for conversion from <i>weekprofile</i> data to entries <i>workdays</i> and <i>holidays</i> only monday and sunday data will be used, other days will be ignored</li>
<li>as parameters, <i>$name</i> (name of the calling MQTT2_DEVICE), <i>$wp_name</i> (name of the weekprofile device) and $wp_profile (in "topic:entity" format) have to be used, when topic changes are done via weekprofile, the relevent data will be sent to the MQTT2_DEVICE instances with suitable <i>weekprofile</i> attribute automatically.<br>
Additionally you may force sending holiday data by adding a forth parameter ($model) and set that to '5+2'.<br>
So entire Perl command for <i>zigbee2mqtt_thermostat_with_weekrofile</i> should look like:
<ul>
<code>FHEM::attrT_z2m_thermostat_Utils::z2t_send_weekprofile($NAME, $EVTPART1, $EVTPART2)</code><br>
</ul><br>or
<ul>
<code>FHEM::attrT_z2m_thermostat_Utils::z2t_send_weekprofile($NAME, $EVTPART1, $EVTPART2, '5+2')</code><br>
</ul>
</li>
</ul>
</ul>
=end html
=cut