Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
D
domotikad
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
domotika
domotikad
Commits
fe2abe43
Commit
fe2abe43
authored
Mar 03, 2014
by
nextime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Thermostats backend complete
parent
c5044b85
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
410 additions
and
8 deletions
+410
-8
99_clima2.sql
Databases/createdb/99_clima2.sql
+168
-0
thermostat.php
Web/htdocs/gui/panels/footjs/thermostat.php
+1
-0
boardtype.py
domotika/boards/boardtype.py
+3
-0
dmdb.py
domotika/db/dmdb.py
+13
-0
domotika.py
domotika/domotika.py
+225
-8
No files found.
Databases/createdb/99_clima2.sql
0 → 100644
View file @
fe2abe43
DROP
table
thermostats
;
DROP
table
thermostats_progs
;
DROP
table
thermostats_actions
;
CREATE
TABLE
IF
NOT
EXISTS
`thermostats`
(
`id`
bigint
(
20
)
unsigned
NOT
NULL
AUTO_INCREMENT
,
`name`
varchar
(
32
)
NOT
NULL
,
`button_name`
varchar
(
255
)
NOT
NULL
,
`position`
int
(
10
)
unsigned
NOT
NULL
,
`sensor_type`
enum
(
'analog'
,
'digital'
,
'statuses'
,
'uniques'
)
NOT
NULL
DEFAULT
'analog'
,
`sensor_domain`
varchar
(
32
)
NOT
NULL
DEFAULT
'*'
,
`function`
enum
(
'manual'
,
'program'
)
NOT
NULL
DEFAULT
'manual'
,
`minslide`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'14.5'
,
`maxslide`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'40.0'
,
`active`
enum
(
'yes'
,
'no'
)
NOT
NULL
DEFAULT
'yes'
,
`setval`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`lastcheck`
decimal
(
13
,
2
)
NOT
NULL
DEFAULT
'0.00'
,
`lastchange`
decimal
(
13
,
2
)
NOT
NULL
DEFAULT
'0.00'
,
`temp_changed`
tinyint
(
1
)
NOT
NULL
DEFAULT
'0'
,
`function_changed`
tinyint
(
11
)
NOT
NULL
DEFAULT
'0'
,
`status_changed`
tinyint
(
1
)
NOT
NULL
DEFAULT
'0'
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`name`
(
`name`
),
KEY
`active`
(
`active`
),
KEY
`button_name`
(
`button_name`
,
`position`
),
KEY
`function`
(
`function`
),
KEY
`temp_changed`
(
`temp_changed`
,
`function_changed`
,
`status_changed`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
latin1
AUTO_INCREMENT
=
1
;
CREATE
TABLE
IF
NOT
EXISTS
`thermostats_actions`
(
`id`
bigint
(
20
)
unsigned
NOT
NULL
AUTO_INCREMENT
,
`thermostat_name`
varchar
(
32
)
DEFAULT
NULL
,
`active`
tinyint
(
1
)
NOT
NULL
DEFAULT
'1'
,
`change_trigger`
enum
(
'any'
,
'function_change'
,
'status_change'
,
'temp_change'
)
NOT
NULL
DEFAULT
'any'
,
`thermostat_function`
enum
(
'any'
,
'manual'
,
'program'
)
NOT
NULL
DEFAULT
'any'
,
`clima_status`
varchar
(
32
)
NOT
NULL
DEFAULT
'*'
,
`min_time`
decimal
(
13
,
2
)
NOT
NULL
DEFAULT
'0.00'
,
`lastrun`
decimal
(
13
,
2
)
NOT
NULL
DEFAULT
'0.00'
,
`launch_sequence`
enum
(
'yes'
,
'no'
)
NOT
NULL
DEFAULT
'no'
,
`launch_sequence_name`
varchar
(
255
)
DEFAULT
NULL
,
`use_command`
enum
(
'yes'
,
'no'
)
NOT
NULL
DEFAULT
'no'
,
`command`
varchar
(
1024
)
NOT
NULL
,
`ikapacket`
tinyint
(
1
)
NOT
NULL
DEFAULT
'0'
,
`ikap_src`
varchar
(
32
)
DEFAULT
'Q.CLIMA'
,
`ikap_dst`
varchar
(
32
)
DEFAULT
NULL
,
`ikap_msgtype`
int
(
11
)
DEFAULT
NULL
,
`ikap_ctx`
int
(
11
)
DEFAULT
NULL
,
`ikap_act`
int
(
11
)
DEFAULT
NULL
,
`ikap_arg`
varchar
(
1024
)
DEFAULT
NULL
,
`ipdest`
varchar
(
15
)
DEFAULT
'255.255.255.255'
,
`min`
varchar
(
255
)
NOT
NULL
DEFAULT
'*'
,
`hour`
varchar
(
255
)
NOT
NULL
DEFAULT
'*'
,
`day`
varchar
(
255
)
NOT
NULL
DEFAULT
'*'
,
`month`
varchar
(
255
)
NOT
NULL
DEFAULT
'*'
,
`dayofweek`
varchar
(
255
)
NOT
NULL
DEFAULT
'*'
,
`comment`
varchar
(
1024
)
NOT
NULL
,
PRIMARY
KEY
(
`id`
),
KEY
`status_name`
(
`thermostat_name`
),
KEY
`active`
(
`active`
),
KEY
`launch_sequence_name`
(
`launch_sequence_name`
),
KEY
`clima_status`
(
`clima_status`
),
KEY
`thermostat_function`
(
`thermostat_function`
),
KEY
`trigger`
(
`change_trigger`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
latin1
AUTO_INCREMENT
=
1
;
CREATE
TABLE
IF
NOT
EXISTS
`thermostats_progs`
(
`id`
bigint
(
20
)
NOT
NULL
AUTO_INCREMENT
,
`thermostat_name`
varchar
(
32
)
NOT
NULL
,
`clima_status`
varchar
(
32
)
NOT
NULL
,
`day`
enum
(
'mon'
,
'tue'
,
'wed'
,
'thu'
,
'fri'
,
'sat'
,
'sun'
)
NOT
NULL
DEFAULT
'mon'
,
`position`
int
(
11
)
unsigned
NOT
NULL
DEFAULT
'0'
,
`h00`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h01`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h02`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h03`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h04`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h05`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h06`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h07`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h08`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h09`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h10`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h11`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h12`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h13`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h14`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h15`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h16`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h17`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h18`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h19`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h20`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h21`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h22`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
`h23`
decimal
(
3
,
1
)
NOT
NULL
DEFAULT
'20.0'
,
PRIMARY
KEY
(
`id`
),
KEY
`thermostat_name`
(
`thermostat_name`
),
KEY
`clima_status`
(
`clima_status`
,
`day`
),
KEY
`position`
(
`position`
),
KEY
`active`
(
`day`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
latin1
AUTO_INCREMENT
=
1
;
ALTER
TABLE
`thermostats_actions`
ADD
CONSTRAINT
`thermostats_actions_ibfk_1`
FOREIGN
KEY
(
`thermostat_name`
)
REFERENCES
`thermostats`
(
`name`
)
ON
DELETE
CASCADE
ON
UPDATE
CASCADE
;
ALTER
TABLE
`thermostats_progs`
ADD
CONSTRAINT
`thermostats_progs_ibfk_1`
FOREIGN
KEY
(
`thermostat_name`
)
REFERENCES
`thermostats`
(
`name`
)
ON
DELETE
CASCADE
ON
UPDATE
CASCADE
;
DELIMITER
;;
CREATE
TRIGGER
thermostat_lastchange
BEFORE
UPDATE
ON
thermostats
FOR
EACH
ROW
BEGIN
IF
NOT
(
NEW
.
setval
<=>
OLD
.
setval
AND
NEW
.
function
<=>
OLD
.
function
)
THEN
IF
NEW
.
setval
<>
OLD
.
setval
THEN
SET
NEW
.
temp_changed
=
1
;
END
IF
;
IF
NEW
.
function
<>
OLD
.
function
THEN
SET
NEW
.
function_changed
=
1
;
END
IF
;
IF
EXISTS
(
SELECT
1
FROM
mysql
.
func
where
name
=
'microsecnow'
)
THEN
SET
NEW
.
lastchange
=
MICROSECNOW
()
/
1000000
;
ELSE
SET
NEW
.
lastchange
=
TIMESTAMPDIFF
(
second
,
'1970-01-01 01:00:00'
,
NOW
());
END
IF
;
END
IF
;
END
;;
CREATE
TRIGGER
thermostatinsert_lastchange
BEFORE
INSERT
ON
thermostats
FOR
EACH
ROW
BEGIN
SET
NEW
.
temp_changed
=
1
;
SET
NEW
.
function_changed
=
1
;
SET
NEW
.
status_changed
=
1
;
IF
EXISTS
(
SELECT
1
FROM
mysql
.
func
where
name
=
'microsecnow'
)
THEN
SET
NEW
.
lastchange
=
MICROSECNOW
()
/
1000000
;
ELSE
SET
NEW
.
lastchange
=
TIMESTAMPDIFF
(
second
,
'1970-01-01 01:00:00'
,
NOW
());
END
IF
;
END
;;
DELIMITER
;
DROP
TRIGGER
config_lastchange
;
DROP
TRIGGER
configinsert_lastchange
;
DELIMITER
;;
CREATE
TRIGGER
config_lastchange
BEFORE
UPDATE
ON
daemon_config
FOR
EACH
ROW
BEGIN
IF
EXISTS
(
SELECT
1
FROM
mysql
.
func
where
name
=
'microsecnow'
)
THEN
SET
NEW
.
lastchange
=
MICROSECNOW
()
/
1000000
;
ELSE
SET
NEW
.
lastchange
=
TIMESTAMPDIFF
(
second
,
'1970-01-01 01:00:00'
,
NOW
());
END
IF
;
END
;;
CREATE
TRIGGER
configinsert_lastchange
BEFORE
INSERT
ON
daemon_config
FOR
EACH
ROW
BEGIN
IF
EXISTS
(
SELECT
1
FROM
mysql
.
func
where
name
=
'microsecnow'
)
THEN
SET
NEW
.
lastchange
=
MICROSECNOW
()
/
1000000
;
ELSE
SET
NEW
.
lastchange
=
TIMESTAMPDIFF
(
second
,
'1970-01-01 01:00:00'
,
NOW
());
END
IF
;
END
;;
DELIMITER
;
ALTER
TABLE
`ioconf_analogs`
ADD
`ananame`
VARCHAR
(
32
)
NOT
NULL
AFTER
`ananum`
,
ADD
INDEX
(
`ananame`
)
;
ALTER
TABLE
`ioconf_inputs`
ADD
`inpname`
VARCHAR
(
32
)
NOT
NULL
AFTER
`inpnum`
,
ADD
INDEX
(
`inpname`
)
;
ALTER
TABLE
`ioconf_outputs`
ADD
`outname`
VARCHAR
(
32
)
NOT
NULL
AFTER
`outnum`
,
ADD
INDEX
(
`outname`
)
;
ALTER
TABLE
`status_actions`
CHANGE
`ikap_act`
`ikap_act`
INT
(
11
)
NULL
;
ALTER
TABLE
`voip_actions`
CHANGE
`ikap_act`
`ikap_act`
INT
(
10
)
UNSIGNED
NULL
;
Web/htdocs/gui/panels/footjs/thermostat.php
View file @
fe2abe43
...
...
@@ -193,6 +193,7 @@ var thermostatEvent = function(event) {
var
parts
=
$
(
this
).
attr
(
'id'
).
split
(
"-"
);
var
slide
=
$
(
"#thermo-level-"
+
parts
[
2
]
+
'-'
+
parts
[
3
]);
slide
.
val
(
parseFloat
(
data
.
data
.
val
));
slider
.
data
(
'oldval'
,
slider
.
val
());
$
(
'#thermo-showset-'
+
parts
[
2
]
+
'-'
+
parts
[
3
]).
text
(
parseFloat
(
data
.
data
.
val
).
toFixed
(
1
));
}
);
...
...
domotika/boards/boardtype.py
View file @
fe2abe43
...
...
@@ -52,6 +52,7 @@ except:
# i_[idx]_[ananum+totinp]_[statusnum]_[act]
ANAINDEX
=
{
'ananame'
:
[
'08'
,
'00'
],
'status_name'
:
[
'09'
,
'00'
],
'enabled'
:
[
'05'
,
'00'
],
'anatype'
:
[
'11'
,
'00'
],
...
...
@@ -85,6 +86,7 @@ ANAINDEX={
}
def
context2section
(
ctx
):
if
int
(
ctx
)
in
C
.
SECTIONS
.
keys
():
section
=
C
.
SECTIONS
[
int
(
ctx
)]
...
...
@@ -269,6 +271,7 @@ class ANABoard(object):
d
.
boardname
=
boardname
d
.
boardip
=
boardip
d
.
ananum
=
i
-
self
.
firstAna
+
1
d
.
ananame
=
aname
d
.
status_num
=
n
d
.
status_name
=
sconf
[
0
]
d
.
enabled
=
'yes'
if
sconf
[
2
]
==
'1'
else
'no'
...
...
domotika/db/dmdb.py
View file @
fe2abe43
...
...
@@ -242,6 +242,9 @@ class Thermostats(DBObject):
class
ThermostatsProgs
(
DBObject
):
TABLENAME
=
"thermostats_progs"
class
ThermostatsActions
(
DBObject
):
TABLENAME
=
"thermostats_actions"
def
updateStatusRealtime
(
stname
,
status
,
changed
=
False
):
querystr
=
"INSERT INTO statusrealtime (status_name,value,lastupdate"
...
...
@@ -643,6 +646,13 @@ def getNetStatus():
def
getClimaStatus
():
return
Uniques
.
find
(
where
=
[
"name='climastatus'"
],
limit
=
1
)
.
addCallback
(
_retValueQuery
,
'OFF'
)
def
setClimaStatus
(
newstatus
):
def
_updateThermoInSetClima
(
res
):
runQuery
(
"UPDATE thermostats SET lastchange='
%
s',status_changed=1"
%
str
(
time
.
time
()))
return
res
return
setUnique
(
'climastatus'
,
newstatus
)
.
addCallback
(
_updateThermoInSetClima
)
def
getStatusRealtime
(
stname
):
return
StatusRealtime
.
find
(
where
=
[
"status_name=?"
,
stname
],
limit
=
1
)
.
addCallback
(
_retValueQuery
,
False
)
...
...
@@ -699,6 +709,9 @@ def setThermostatProgsDict(thermostat, climastatus, r):
_setThermostatProgsDict
,
thermostat
,
climastatus
,
r
)
def
getThermostatsChanged
():
return
Thermostats
.
find
(
where
=
[
"active='yes' AND lastchange=0.00 or lastchange>lastcheck"
])
def
checkMotionDetectionEvent
(
camera
,
zone
,
estatus
,
etype
):
qstr
=
"""active>0 AND (event_status=
%
d OR event_status=255)
...
...
domotika/domotika.py
View file @
fe2abe43
...
...
@@ -76,7 +76,6 @@ ACTION_STATUS={}
log
=
logging
.
getLogger
(
'Core'
)
def
converWday
(
wday
):
wday
=
wday
+
1
if
wday
==
7
:
...
...
@@ -136,6 +135,12 @@ class domotikaService(service.Service):
self
.
notifytimer
.
start
(
60
)
self
.
clienttimer
=
task
.
LoopingCall
(
self
.
expireClients
)
self
.
clienttimer
.
start
(
60
)
self
.
thermostattimer
=
task
.
LoopingCall
(
self
.
thermostatsLoop
)
self
.
thermostattimer
.
start
(
10
)
self
.
thermoProgramLoop
()
self
.
thermoprgloop
=
txcron
.
ScheduledCall
(
self
.
thermoProgramLoop
)
self
.
thermoprgloop
.
start
(
CronSchedule
(
'00 * * * *'
))
self
.
actiontimer
.
start
(
int
(
self
.
config
.
get
(
"general"
,
"action_status_timer"
)))
self
.
timer
.
start
(
int
(
self
.
config
.
get
(
"ikapserver"
,
"timeupdates"
)))
...
...
@@ -223,6 +228,80 @@ class domotikaService(service.Service):
t
=
task
.
LoopingCall
(
self
.
refreshActionLoops
)
t
.
start
(
60
)
def
thermoProgramLoop
(
self
):
wd
=
[
'sun'
,
'mon'
,
'tue'
,
'wed'
,
'thu'
,
'fri'
,
'sat'
]
def
_setTemp
(
res
,
thermostat
):
if
res
:
try
:
t
=
res
[
0
][
0
]
dmdb
.
setThermostat
(
thermostat
,
func
=
'program'
,
setval
=
t
)
self
.
clientSend
(
'thermostat'
,
{
'action'
:
'setval'
,
'val'
:
t
,
'thermostat'
:
thermostat
})
except
:
pass
def
_setThermoPrg
(
res
,
cs
):
d
=
wd
[
int
(
time
.
strftime
(
'
%
w'
,
time
.
localtime
()))]
for
thermo
in
res
:
sqlquery
=
"SELECT h"
+
time
.
strftime
(
'
%
H'
,
time
.
localtime
())
+
" FROM thermostats_progs WHERE"
sqlquery
+=
" thermostat_name='"
+
thermo
.
name
+
"' AND clima_status='"
+
cs
+
"' AND day='"
+
d
+
"' LIMIT 1"
dmdb
.
runQuery
(
sqlquery
)
.
addCallback
(
_setTemp
,
thermo
.
name
)
def
getThermo
(
cs
):
dmdb
.
Thermostats
.
find
(
where
=
[
"active=1 AND function='program'"
])
.
addCallback
(
_setThermoPrg
,
cs
)
dmdb
.
getClimaStatus
()
.
addCallback
(
getThermo
)
def
thermostatsLoop
(
self
):
def
manageClimaActions
(
thermoacts
):
for
res
in
thermoacts
:
if
genutils
.
isTrue
(
res
.
active
):
try
:
timedict
=
parseCronLine
(
" "
.
join
(
[
res
.
min
,
res
.
hour
,
res
.
day
,
res
.
month
,
res
.
dayofweek
]))
except
:
continue
loctime
=
time
.
localtime
()
if
(
loctime
.
tm_mon
in
timedict
[
"months"
]
and
loctime
.
tm_mday
in
timedict
[
"doms"
]
and
converWday
(
loctime
.
tm_wday
)
in
timedict
[
"dows"
]
and
loctime
.
tm_hour
in
timedict
[
"hours"
]
and
loctime
.
tm_min
in
timedict
[
"minutes"
]):
if
time
.
time
()
-
float
(
res
.
lastrun
)
<
float
(
res
.
min_time
):
continue
res
.
lastrun
=
time
.
time
()
log
.
info
(
'Execute Thermostat Action ID '
+
str
(
res
.
id
)
+
' for thermostat '
+
str
(
res
.
thermostat_name
)
+
' trigger '
+
str
(
res
.
change_trigger
))
res
.
save
()
if
genutils
.
isTrue
(
res
.
ikapacket
):
self
.
sendCommand
(
res
.
ikap_dst
,
act
=
res
.
ikap_act
,
ctx
=
res
.
ikap_ctx
,
msgtype
=
res
.
ikap_msgtype
,
arg
=
res
.
ikap_arg
,
src
=
res
.
ikap_src
,
ipdst
=
str
(
res
.
ipdest
))
if
genutils
.
isTrue
(
res
.
use_command
):
self
.
executeAction
(
res
.
command
)
if
genutils
.
isTrue
(
res
.
launch_sequence
)
and
res
.
launch_sequence_name
!=
None
:
dmdb
.
getSequence
(
res
.
launch_sequence_name
)
.
addCallback
(
self
.
manageSequence
,
'thermostat'
)
def
checkThermo
(
res
,
cs
):
for
thermo
in
res
:
wh
=
"thermostat_name='
%
s' AND (thermostat_function='
%
s' OR thermostat_function='any')"
%
(
thermo
.
name
,
thermo
.
function
)
wh
+=
" AND active=1 AND DMDOMAIN('
%
s', clima_status)=1"
%
(
str
(
cs
))
if
genutils
.
isTrue
(
thermo
.
status_changed
):
dmdb
.
ThermostatsActions
.
find
(
where
=
[
wh
+
" AND change_trigger='status_change'"
])
.
addCallback
(
manageClimaActions
)
if
genutils
.
isTrue
(
thermo
.
function_changed
):
dmdb
.
ThermostatsActions
.
find
(
where
=
[
wh
+
" AND change_trigger='function_change'"
])
.
addCallback
(
manageClimaActions
)
if
genutils
.
isTrue
(
thermo
.
temp_changed
):
dmdb
.
ThermostatsActions
.
find
(
where
=
[
wh
+
" AND change_trigger='temp_change'"
])
.
addCallback
(
manageClimaActions
)
dmdb
.
ThermostatsActions
.
find
(
where
=
[
wh
+
" AND change_trigger='any'"
])
.
addCallback
(
manageClimaActions
)
thermo
.
status_changed
=
0
thermo
.
function_changed
=
0
thermo
.
temp_changed
=
0
thermo
.
lastcheck
=
time
.
time
()
thermo
.
save
()
def
getThermo
(
cs
):
dmdb
.
getThermostatsChanged
()
.
addCallback
(
checkThermo
,
cs
)
dmdb
.
getClimaStatus
()
.
addCallback
(
getThermo
)
def
actionLoopTasks
(
self
,
res
):
log
.
debug
(
"ACTION LOOP TASKS"
)
IDS
=
{}
...
...
@@ -482,7 +561,12 @@ class domotikaService(service.Service):
def
syncBoards
(
self
,
bid
=
False
,
*
a
,
**
kw
):
if
not
bid
:
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1'
])
.
addCallback
(
self
.
_syncBoards
)
if
genutils
.
is_number
(
bid
):
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and id="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_syncBoards
)
elif
genutils
.
isIp
(
bid
):
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and ip="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_syncBoards
)
elif
type
(
bid
)
.
__name__
==
'str'
:
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and name="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_syncBoards
)
def
_pushBoards
(
self
,
res
,
analogs
=
False
,
inputs
=
False
,
outputs
=
False
,
pwms
=
False
):
# XXX Make which i/o/a is pushed selectively
if
res
:
...
...
@@ -490,7 +574,7 @@ class domotikaService(service.Service):
p
=
pluggableBoards
.
getBoardPlugin
(
b
.
type
,
ConvenienceCaller
(
lambda
c
:
self
.
_callback
(
'board'
,
c
)))
if
b
:
pboard
=
p
.
getBoard
(
b
.
ip
,
b
.
webport
,
self
.
boardsyspwd
,
str
(
self
.
config
.
get
(
'general'
,
'language'
)))
log
.
info
(
'_PushBoards '
+
str
(
pboard
))
if
analogs
and
analogs
==
'*'
:
pboard
.
pushAnalogs
()
elif
type
(
analogs
)
.
__name__
in
[
'list'
,
'tuple'
]:
...
...
@@ -533,7 +617,12 @@ class domotikaService(service.Service):
def
pushBoards
(
self
,
bid
=
False
,
analogs
=
False
,
inputs
=
False
,
outputs
=
False
,
pwms
=
False
,
*
a
,
**
kw
):
if
not
bid
:
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1'
])
.
addCallback
(
self
.
_pushBoards
,
analogs
,
inputs
,
outputs
,
pwms
)
if
genutils
.
is_number
(
bid
):
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and id="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_pushBoards
,
analogs
,
inputs
,
outputs
,
pwms
)
elif
genutils
.
isIp
(
bid
):
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and ip="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_pushBoards
,
analogs
,
inputs
,
outputs
,
pwms
)
elif
type
(
bid
)
.
__name__
==
'str'
:
return
dmdb
.
DMBoards
.
find
(
where
=
[
'online=1 and name="
%
s"'
%
str
(
bid
)])
.
addCallback
(
self
.
_pushBoards
,
analogs
,
inputs
,
outputs
,
pwms
)
def
autoDetectBoards
(
self
,
*
a
,
**
kw
):
log
.
info
(
"Start building boardlist"
)
...
...
@@ -983,6 +1072,97 @@ class domotikaService(service.Service):
except
:
pass
def
thermoSet
(
self
,
thermo
,
*
a
,
**
kw
):
def
_push
(
res
,
ret
):
status
=
'*'
if
'status'
in
kw
.
keys
()
and
kw
[
'status'
]
is
not
False
:
status
=
kw
[
'status'
]
for
r
in
ret
:
self
.
pushBoards
(
bid
=
r
.
board_name
,
analogs
=
[{
'num'
:
r
.
ananum
,
'status'
:
status
}])
log
.
info
(
'THERMOSET PUSHBOARD '
+
str
(
r
.
board_name
)
+
str
({
'num'
:
r
.
ananum
,
'status'
:
status
}))
def
_analogs
(
res
,
sqld
):
ors
=
[]
for
r
in
res
:
sql
=
"boardname='
%
s' AND boardip='
%
s' AND ananum='
%
s' AND ananame='
%
s'"
%
(
r
.
board_name
,
r
.
board_ip
,
r
.
ananum
,
r
.
ananame
)
if
'status'
in
kw
.
keys
()
and
kw
[
'status'
]
is
not
False
:
if
genutils
.
is_number
(
kw
[
'status'
])
and
int
(
kw
[
'status'
])
in
[
1
,
2
]:
sql
+=
" AND status_num='
%
s'"
%
str
(
kw
[
'status'
])
else
:
sql
+=
" AND DMDOMAIN(status_name, '
%
s')=1"
%
str
(
kw
[
'status'
])
ors
+=
[
sql
]
sql
=
"UPDATE ioconf_analogs SET "
started
=
False
for
s
in
sqld
.
keys
():
if
started
:
sql
+=
','
else
:
started
=
True
if
s
==
'min_level'
and
sqld
[
'min_level'
]
is
None
:
sql
+=
"min_level=minval"
elif
s
==
'min_level'
:
sql
+=
"min_level=
%
s"
%
str
(
float
(
sqld
[
'min_level'
])
*
float
(
r
.
divider
))
elif
s
==
'max_level'
and
sqld
[
'max_level'
]
is
None
:
sql
+=
"max_level=maxval"
elif
s
==
'max_level'
:
sql
+=
"max_level=
%
s"
%
str
(
float
(
sqld
[
'max_level'
])
*
float
(
r
.
divider
))
else
:
sql
+=
s
+
"='"
+
sqld
[
s
]
+
"'"
sql
+=
" WHERE "
started
=
False
for
s
in
ors
:
if
started
:
sql
+=
" OR "
else
:
started
=
True
sql
+=
"("
+
s
+
")"
dmdb
.
runOperation
(
sql
)
.
addCallback
(
_push
,
res
)
def
_thermoSet
(
res
):
for
r
in
res
:
sqld
=
{}
if
'mindomain'
in
kw
.
keys
()
and
kw
[
'mindomain'
]
is
not
False
:
sqld
[
'min_domain'
]
=
str
(
kw
[
'mindomain'
])
if
'minmsgtype'
in
kw
.
keys
()
and
kw
[
'minmsgtype'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'minmsgtype'
]):
sqld
[
'min_msg'
]
=
str
(
kw
[
'minmsgtype'
])
if
'minval'
in
kw
.
keys
()
and
kw
[
'minval'
]
is
not
False
:
if
genutils
.
is_number
(
kw
[
'minval'
]):
sqld
[
'min_level'
]
=
str
(
kw
[
'minval'
])
elif
kw
[
'minval'
]
==
'fromthermo'
:
sqld
[
'min_level'
]
=
str
(
r
.
setval
)
elif
kw
[
'minval'
]
==
'unset'
:
sqld
[
'min_level'
]
=
None
if
'minact'
in
kw
.
keys
()
and
kw
[
'minact'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'minact'
]):
sqld
[
'min_act'
]
=
str
(
kw
[
'minact'
])
if
'minctx'
in
kw
.
keys
()
and
kw
[
'minctx'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'minctx'
]):
sqld
[
'min_ctx'
]
=
str
(
kw
[
'min_ctx'
])
if
'maxdomain'
in
kw
.
keys
()
and
kw
[
'maxdomain'
]
is
not
False
:
sqld
[
'max_domain'
]
=
str
(
kw
[
'maxdomain'
])
if
'maxmsgtype'
in
kw
.
keys
()
and
kw
[
'maxmsgtype'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'maxmsgtype'
]):
sqld
[
'max_msg'
]
=
str
(
kw
[
'maxmsgtype'
])
if
'maxval'
in
kw
.
keys
()
and
kw
[
'maxval'
]
is
not
False
:
if
genutils
.
is_number
(
kw
[
'maxval'
]):
sqld
[
'max_level'
]
=
str
(
kw
[
'maxval'
])
elif
kw
[
'maxval'
]
==
'fromthermo'
:
sqld
[
'max_level'
]
=
str
(
r
.
setval
)
elif
kw
[
'maxval'
]
==
'unset'
:
sqld
[
'max_level'
]
=
None
if
'maxact'
in
kw
.
keys
()
and
kw
[
'maxact'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'maxact'
]):
sqld
[
'max_act'
]
=
str
(
kw
[
'maxact'
])
if
'maxctx'
in
kw
.
keys
()
and
kw
[
'maxctx'
]
is
not
False
and
genutils
.
is_number
(
kw
[
'maxctx'
]):
sqld
[
'max_ctx'
]
=
str
(
kw
[
'max_ctx'
])
if
'enabled'
in
kw
.
keys
()
and
kw
[
'enabled'
]
is
not
False
and
kw
[
'enabled'
]
in
[
'yes'
,
'no'
]:
sqld
[
'enabled'
]
=
kw
[
'enabled'
]
if
r
.
sensor_type
==
'analog'
:
whe
=
"websection='clima' AND DMDOMAIN(ananame, '
%
s')=1"
%
str
(
r
.
sensor_domain
)
dmdb
.
Analog
.
find
(
where
=
[
whe
])
.
addCallback
(
_analogs
,
sqld
)
return
defer
.
succeed
(
True
)
log
.
info
(
"SET THERMOSTAT "
+
thermo
)
return
dmdb
.
Thermostats
.
find
(
where
=
[
"DMDOMAIN(name, '"
+
thermo
+
"')=1"
])
.
addCallback
(
_thermoSet
)
def
ioConfig
(
what
,
act
,
who
,
**
args
):
what
=
what
.
lower
()
act
=
act
.
lower
()
...
...
@@ -1136,6 +1316,39 @@ class domotikaService(service.Service):
preq
=
sp
.
join
(
pc
[
1
:])
self
.
plugins
.
push_request
(
pname
,
preq
)
elif
command
.
startswith
(
"THERMOSET "
)
or
command
.
startswith
(
"THERMOSET:"
):
if
':'
in
command
:
command
=
command
[
10
:]
.
split
(
':'
)
else
:
command
=
command
[
10
:]
.
split
()
if
len
(
command
)
>
0
:
thermo
=
command
[
0
]
topt
=
{
'enabled'
:
'yes'
,
'minval'
:
'fromthermo'
,
'maxval'
:
'unset'
,
'mindomain'
:
False
,
'maxdomain'
:
False
,
'minctx'
:
False
,
'maxctx'
:
False
,
'minact'
:
False
,
'maxact'
:
False
,
'minmsgtype'
:
False
,
'maxmsgtype'
:
False
,
'status'
:
'*'
}
if
(
len
(
command
)
>
1
):
opts
=
command
[
1
]
for
opt
in
opts
.
split
(
','
):
optp
=
opt
.
split
(
'='
)[
0
]
if
len
(
optp
)
>
1
and
optp
[
0
]
in
topt
.
keys
():
optk
=
optp
[
0
]
optv
=
optp
[
1
]
topt
[
optk
]
=
optv
self
.
thermoSet
(
thermo
,
**
topt
)
elif
command
.
startswith
(
"PHONECALL "
)
or
command
.
startswith
(
"PHONECALL:"
):
if
':'
in
command
:
command
=
command
[
10
:]
.
split
(
':'
)
...
...
@@ -1416,7 +1629,7 @@ class domotikaService(service.Service):
events
.
postEvent
(
events
.
SequenceEvent
(
"REQUESTED"
,
res
.
name
,
res
.
type
,
cmdsrc
))
if
res
.
type
==
C
.
SEQUENCE_TYPE_CONTINUE
:
if
res
.
running
:
if
cmdsrc
not
in
[
'cron'
,
'motion'
,
'restart'
,
'sequence'
,
'statuses'
]:
#, 'voip']:
if
cmdsrc
not
in
[
'cron'
,
'motion'
,
'restart'
,
'sequence'
,
'statuses'
,
'thermostat'
]:
#, 'voip']:
self
.
stopSequence
(
res
)
return
else
:
...
...
@@ -2196,6 +2409,11 @@ class domotikaService(service.Service):
return
d
def
setClimaStatus
(
self
,
newstatus
):
self
.
clientSend
(
'thermostat'
,
{
'action'
:
'climastatus'
,
'status'
:
newstatus
})
return
dmdb
.
setClimaStatus
(
newstatus
);
def
getChartData
(
self
,
resdata
,
chartname
):
if
resdata
and
len
(
resdata
)
>
0
:
return
dmdb
.
getChartSeries
(
chartname
)
.
addCallback
(
self
.
parseChartSeries
,
resdata
,
chartname
)
...
...
@@ -2359,8 +2577,7 @@ class domotikaService(service.Service):
return
dmdb
.
getClimaStatus
()
def
web_on_setClimaStatus
(
self
,
newstatus
):
self
.
clientSend
(
'thermostat'
,
{
'action'
:
'climastatus'
,
'status'
:
newstatus
})
return
dmdb
.
setUnique
(
'climastatus'
,
newstatus
);
return
self
.
setClimaStatus
(
newstatus
)
def
web_on_getThermostat
(
self
,
thermostat
):
return
dmdb
.
Thermostats
.
find
(
where
=
[
"name=?"
,
thermostat
],
limit
=
1
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment