From d3ddabbb5b5f45bac3da8cb51d3e63810aa2d4ca Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 15 Nov 2017 23:46:30 +0100 Subject: 2017-11-15 22:14:00 --- doc/context/documents/general/qrcs/setup-cs.pdf | Bin 834405 -> 834423 bytes doc/context/documents/general/qrcs/setup-de.pdf | Bin 836187 -> 836226 bytes doc/context/documents/general/qrcs/setup-en.pdf | Bin 839516 -> 839570 bytes doc/context/documents/general/qrcs/setup-fr.pdf | Bin 832436 -> 832480 bytes doc/context/documents/general/qrcs/setup-it.pdf | Bin 836892 -> 836929 bytes doc/context/documents/general/qrcs/setup-nl.pdf | Bin 829774 -> 829841 bytes doc/context/documents/general/qrcs/setup-ro.pdf | Bin 830933 -> 830964 bytes .../sources/general/manuals/luatex/luatex-math.tex | 2 +- metapost/context/base/mpiv/mp-tres.mpiv | 22 +- scripts/context/lua/mtx-evohome.lua | 18 +- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/mult-pe.mkii | 2 + tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/math-fen.mkiv | 36 +- tex/context/base/mkiv/mult-sys.mkiv | 1 + tex/context/base/mkiv/publ-ini.mkiv | 5 + tex/context/base/mkiv/status-files.pdf | Bin 25841 -> 25817 bytes tex/context/base/mkiv/status-lua.pdf | Bin 249993 -> 248731 bytes tex/context/base/mkiv/util-evo.lua | 550 +++++++++++++++++++++ tex/context/interface/mkii/keys-pe.xml | 2 + tex/context/interface/mkiv/context-en.xml | 3 + tex/context/interface/mkiv/i-context.pdf | Bin 839516 -> 839570 bytes tex/context/interface/mkiv/i-mathfence.xml | 5 +- tex/context/interface/mkiv/i-readme.pdf | Bin 60775 -> 60776 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 27 files changed, 638 insertions(+), 18 deletions(-) create mode 100644 tex/context/base/mkiv/util-evo.lua diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf index 41a5ef848..3b3b7a33f 100644 Binary files a/doc/context/documents/general/qrcs/setup-cs.pdf and b/doc/context/documents/general/qrcs/setup-cs.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf index 9b404fa11..55c5a2bf2 100644 Binary files a/doc/context/documents/general/qrcs/setup-de.pdf and b/doc/context/documents/general/qrcs/setup-de.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf index 601963f61..8c8249219 100644 Binary files a/doc/context/documents/general/qrcs/setup-en.pdf and b/doc/context/documents/general/qrcs/setup-en.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf index b9d00c654..358285012 100644 Binary files a/doc/context/documents/general/qrcs/setup-fr.pdf and b/doc/context/documents/general/qrcs/setup-fr.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf index bd3b1490d..af879734a 100644 Binary files a/doc/context/documents/general/qrcs/setup-it.pdf and b/doc/context/documents/general/qrcs/setup-it.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf index b48666804..9495e9598 100644 Binary files a/doc/context/documents/general/qrcs/setup-nl.pdf and b/doc/context/documents/general/qrcs/setup-nl.pdf differ diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf index 5e59a2556..a913fa7e5 100644 Binary files a/doc/context/documents/general/qrcs/setup-ro.pdf and b/doc/context/documents/general/qrcs/setup-ro.pdf differ diff --git a/doc/context/sources/general/manuals/luatex/luatex-math.tex b/doc/context/sources/general/manuals/luatex/luatex-math.tex index cf5489641..f29a3aed0 100644 --- a/doc/context/sources/general/manuals/luatex/luatex-math.tex +++ b/doc/context/sources/general/manuals/luatex/luatex-math.tex @@ -1276,7 +1276,7 @@ still stepping through the successively larger variants. When no dimensions are given the \type {noaxis} command can be used to prevent shifting over the axis. You can influence the final class with the keyword \type {class} which will -influence the spacing. +influence the spacing. The numbers are the same as for character classes. \subsection{Fixed scripts} diff --git a/metapost/context/base/mpiv/mp-tres.mpiv b/metapost/context/base/mpiv/mp-tres.mpiv index bd8a085a7..335670a98 100644 --- a/metapost/context/base/mpiv/mp-tres.mpiv +++ b/metapost/context/base/mpiv/mp-tres.mpiv @@ -80,6 +80,22 @@ let Xpart = redpart ; let Ypart = greenpart ; let Zpart = bluepart ; +primarydef p Xscaled q = + (q*Xpart p, Ypart p, Zpart p) +enddef ; + +primarydef p Yscaled q = + (Xpart p, q*Ypart p, Zpart p) +enddef ; + +primarydef p Zscaled q = + (Xpart p, Ypart p, q*Zpart p) +enddef ; + +primarydef p XYZscaled q = + (q*Xpart p,q*Ypart p,q*Zpart p) +enddef ; + vardef projection expr t = if triplet t : (Xpart t, Ypart t) transformed Txy shifted (0,Zpart t) @@ -117,7 +133,7 @@ primarydef p rotatedaboutX q = mfun_three_yz := (Ypart p, Zpart p) ; mfun_three_yz := mfun_three_yz rotated q ; ) - (Xpart p, xpart yz, ypart yz) + (Xpart p, xpart mfun_three_yz, ypart mfun_three_yz) enddef ; primarydef p rotatedaboutY q = @@ -125,7 +141,7 @@ primarydef p rotatedaboutY q = mfun_three_zx := (Zpart p, Xpart p) ; mfun_three_zx := mfun_three_zx rotated q ; ) - (ypart zx, Ypart p, xpart zx) + (ypart mfun_three_zx, Ypart p, xpart mfun_three_zx) enddef ; primarydef p rotatedaboutZ q = @@ -133,7 +149,7 @@ primarydef p rotatedaboutZ q = mfun_three_xy := (Xpart p, Ypart p) ; mfun_three_xy := mfun_three_xy rotated q ; ) - (xpart xy, ypart xy, Zpart p) + (xpart mfun_three_xy, ypart mfun_three_xy, Zpart p) enddef ; %D We can use a rotation about an arbitrary direction t ... (easy) diff --git a/scripts/context/lua/mtx-evohome.lua b/scripts/context/lua/mtx-evohome.lua index 43479c072..671666493 100644 --- a/scripts/context/lua/mtx-evohome.lua +++ b/scripts/context/lua/mtx-evohome.lua @@ -56,8 +56,7 @@ local files = environment.files function scripts.evohome.collect() local presets = arguments.presets - local delay = tonumber(arguments.delay) or 12*60*60 - + local delay = tonumber(arguments.delay) or 15*60*60 if presets then presets = utilities.evohome.loadpresets(presets) end @@ -81,8 +80,23 @@ function scripts.evohome.collect() end end + +function scripts.evohome.update() + local presets = arguments.presets + if presets then + presets = utilities.evohome.loadpresets(presets) + end + if presets then + utilities.evohome.geteverything(presets) + else + report("invalid preset file") + end +end + if environment.argument("collect") then scripts.evohome.collect() +elseif environment.argument("update") then + scripts.evohome.update() elseif environment.argument("exporthelp") then application.export(environment.argument("exporthelp"),environment.files[1]) else diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 0aef69e34..2ae75dd8b 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.11.14 13:52} +\newcontextversion{2017.11.15 22:08} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index ef19769a8..6f3b9eb1b 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2017.11.14 13:52} +\edef\contextversion{2017.11.15 22:08} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index ecd45751a..8ac3113cf 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -796,6 +796,7 @@ \setinterfaceconstant{fieldoffset}{آفست‌میدان} \setinterfaceconstant{file}{پرونده} \setinterfaceconstant{filler}{filler} +\setinterfaceconstant{filter}{filter} \setinterfaceconstant{filtercommand}{filtercommand} \setinterfaceconstant{finalnamesep}{finalnamesep} \setinterfaceconstant{finalpagesep}{finalpagesep} @@ -1150,6 +1151,7 @@ \setinterfaceconstant{sidemethod}{روش‌کنار} \setinterfaceconstant{sidespaceafter}{فضای‌کناری‌بعد} \setinterfaceconstant{sidespacebefore}{فضای‌کناری‌قبل} +\setinterfaceconstant{sidethreshold}{sidethreshold} \setinterfaceconstant{sign}{علامت} \setinterfaceconstant{size}{اندازه} \setinterfaceconstant{slantedfeatures}{slantedfeatures} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 1f84e31ad..2710731e3 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.11.14 13:52} +\newcontextversion{2017.11.15 22:08} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 93e4df9b7..01921f8ff 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -41,7 +41,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2017.11.14 13:52} +\edef\contextversion{2017.11.15 22:08} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/math-fen.mkiv b/tex/context/base/mkiv/math-fen.mkiv index f65766a85..4ea2dd08a 100644 --- a/tex/context/base/mkiv/math-fen.mkiv +++ b/tex/context/base/mkiv/math-fen.mkiv @@ -45,6 +45,7 @@ \c!mathstyle=, \c!color=, \c!command=, + \c!mathclass=, \c!factor=\v!auto] \appendtoks @@ -62,17 +63,40 @@ {\ifx#1\empty #2.% \else + \edef\p_mathclass{\mathfenceparameter\c!mathclass}% \edef\p_factor{\mathfenceparameter\c!factor}% \ifx\p_factor\empty - #2% + \ifx\p_mathclass\empty + #2% + \else + #3% + \s!class\p_mathclass + \fi \else\ifx\p_factor\v!auto - #2% + \ifx\p_mathclass\empty + #2% + \else + #3% + \s!class\p_mathclass + \fi \else\ifx\p_factor\v!none - #3\s!height\zeropoint\s!depth\zeropoint\s!axis - #2% + #3% + \s!height\zeropoint + \s!depth\zeropoint + \ifx\p_mathclass\empty\else + \s!class\p_mathclass + \fi + \s!axis + % #2% \else \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax - #3\s!height\scratchdimen\s!depth\scratchdimen\s!axis + #3% + \s!height\scratchdimen + \s!depth\scratchdimen + \ifx\p_mathclass\empty\else + \s!class\p_mathclass + \fi + \s!axis \fi\fi\fi \Udelimiter#4\fam#1\relax \fi} @@ -95,7 +119,7 @@ \def\math_fenced_middle {\edef\p_middle - {\mathfenceparameter\c!middle}% + {\mathfenceparameter\c!middle}% \mskip\thinmuskip \math_fenced_color_push % \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi diff --git a/tex/context/base/mkiv/mult-sys.mkiv b/tex/context/base/mkiv/mult-sys.mkiv index 418ae743f..ead318b71 100644 --- a/tex/context/base/mkiv/mult-sys.mkiv +++ b/tex/context/base/mkiv/mult-sys.mkiv @@ -268,6 +268,7 @@ \definesystemconstant {internal} \definesystemconstant {current} \definesystemconstant {chain} +\definesystemconstant {class} % translating setups is asking for a mess so we keep them as-is: diff --git a/tex/context/base/mkiv/publ-ini.mkiv b/tex/context/base/mkiv/publ-ini.mkiv index 0802fa7d0..6c28bcf90 100644 --- a/tex/context/base/mkiv/publ-ini.mkiv +++ b/tex/context/base/mkiv/publ-ini.mkiv @@ -1364,6 +1364,11 @@ \let\currentbtxcitetag\p_reference \edef\currentbtxciteuservariables{#2}% \fi + \edef\p_specification{\dummyparameter\c!specification}% + \ifx\p_specification\empty + \else + \let\currentbtxspecification\p_specification + \fi \edef\p_alternative{\dummyparameter\c!alternative}% \ifx\p_alternative\empty \setbtxparametersetroot\s!cite diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index b5d4901ed..779281eb5 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index f8685b73f..a17ca6544 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/util-evo.lua b/tex/context/base/mkiv/util-evo.lua new file mode 100644 index 000000000..eeaad5843 --- /dev/null +++ b/tex/context/base/mkiv/util-evo.lua @@ -0,0 +1,550 @@ +if not modules then modules = { } end modules ['util-evo'] = { + version = 1.002, + comment = "library for fetching data from an evohome device", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE", + license = "see context related readme files" +} + +-- When I needed a new boiler for heating I decided to replace a partial +-- (experimental) zwave few-zone solution by the honeywell evohome system that can +-- drive opentherm. I admit that I was not that satified beforehand with the fact +-- that one has to go via some outside portal to communicate with the box but lets +-- hope that this will change (I will experiment with the additional usb interface +-- later). Anyway, apart from integrating it into my home automation setup so that I +-- can add control based on someone present in a zone, I wanted to be able to render +-- statistics. So that's why we have a module in ConTeXt for doing that. It's also +-- an example of Lua. +-- +-- As with other scripts, it assumes that mtxrun is used so that we have the usual +-- libraries present. +-- +-- The code is not that complex but figuring out the right request takes bit of +-- searching the web. There is an api specification at: +-- +-- https://developer.honeywell.com/api-methods?field_smart_method_tags_tid=All +-- +-- Details like the application id can be found in several places. There are +-- snippets of (often partial or old) code on discussion platforms so in the one can +-- get there. + +-- todo: load everything and keep it in mem and only save it when there are changes +-- todo: use a temp files per month +-- todo: %path% in filenames + +require("util-jsn") + +local json = utilities.json +local formatters = string.formatters +local floor, div = math.floor, math.div +local resultof, ostime, osdate, ossleep = os.resultof, os.time, os.date, os.sleep +local jsontolua, jsontostring = json.tolua, json.tostring +local savetable, loadtable = table.save, table.load +local setmetatableindex = table.setmetatableindex +local replacer = utilities.templates.replacer + +local applicationid = "b013aa26-9724-4dbd-8897-048b9aada249" +----- applicationid = "91db1612-73fd-4500-91b2-e63b069b185c" + +local report = logs.reporter("evohome") + +local defaultpresets = { + interval = 30 * 60, + credentials = { + -- username = "unset", + -- password = "unset", + -- accesstoken = "unset", + -- userid = "unset", + }, + -- everything = "evohome-everything", + -- history = "evohome-history", +} + +local function validpresets(presets) + if type(presets == "table") and presets.credentials then + setmetatableindex(presets,defaultpresets) + setmetatableindex(presets.credentials,defaultpresets.credentials) + return presets + else + report("invalid presets") + end +end + +local function loadedtable(filename) + for i=1,10 do + local t = loadtable(filename) + if t then + return t + else + ossleep(1/4) + end + end + return { } +end + +local function loadpresets(filename) + return loadtable(filename) +end + +local function loadhistory(filename) + if type(filename) == "table" then + filename = filename.history + end + return loadedtable(filename) +end + +local function loadeverything(filename) + if type(filename) == "table" then + filename = filename.everything + end + return loadedtable(filename) +end + +local function result(t,fmt,a,b,c) + if t then + report(fmt,a or "done",b or "done",c or "done","done") + return t + else + report(fmt,a or "failed",b or "failed",c or "failed","failed") + end +end + +local f = replacer ( + [[curl ]] .. + [[--silent --insecure ]] .. + [[-X POST ]] .. + [[-H "Authorization: Basic YjAxM2FhMjYtOTcyNC00ZGJkLTg4OTctMDQ4YjlhYWRhMjQ5OnRlc3Q=" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-d "Content-Type=application/x-www-form-urlencoded; charset=utf-8" ]] .. + [[-d "Host=rs.alarmnet.com/" ]] .. + [[-d "Cache-Control=no-store no-cache" ]] .. + [[-d "Pragma=no-cache" ]] .. + [[-d "grant_type=password" ]] .. + [[-d "scope=EMEA-V1-Basic EMEA-V1-Anonymous EMEA-V1-Get-Current-User-Account" ]] .. + [[-d "Username=%username%" ]] .. + [[-d "Password=%password%" ]] .. + [[-d "Connection=Keep-Alive" ]] .. + [["https://tccna.honeywell.com/Auth/OAuth/Token"]] +) + +local function getaccesstoken(presets) + if validpresets(presets) then + local c = presets.credentials + local s = c and f { + username = c.username, + password = c.password, + applicationid = applicationid, + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t,"getting access token: %s") + end + return result(false,"getting access token: %s") +end + +local f = replacer ( + [[curl ]] .. + [[--silent --insecure ]] .. + [[-H "Authorization: bearer %accesstoken%" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-H "applicationId: %applicationid%" ]] .. + [["https://tccna.honeywell.com/WebAPI/emea/api/v1/userAccount"]] +) + +local function getuserinfo(presets) + if validpresets(presets) then + local c = presets.credentials + local s = c and f { + accesstoken = c.accesstoken, + applicationid = c.applicationid, + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t,"getting user info: %s") + end + return result(false,"getting user info: %s") +end + +local f = replacer ( + [[curl ]] .. + [[--silent --insecure ]] .. + [[-H "Authorization: bearer %accesstoken%" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-H "applicationId: %applicationid%" ]] .. + [["https://tccna.honeywell.com/WebAPI/emea/api/v1/location/installationInfo?userId=%userid%&includeTemperatureControlSystems=True"]] +) + +local function getlocationinfo(presets) + if validpresets(presets) then + local c = presets.credentials + local s = c and f { + accesstoken = c.accesstoken, + applicationid = applicationid, + userid = c.userid, + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t,"getting location info: %s") + end + return result(false,"getting location info: %s") +end + +local f = replacer ( + [[curl ]] .. + [[--silent --insecure ]] .. + [[-H "Authorization: bearer %accesstoken%" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-H "applicationId: %applicationid%" ]] .. + [["https://tccna.honeywell.com/WebAPI/emea/api/v1/temperatureZone/%zoneid%/schedule"]] +) + +local function getschedule(presets,zoneid,zonename) + if zoneid and validpresets(presets) then + local c = presets.credentials + local s = c and f { + accesstoken = c.accesstoken, + applicationid = applicationid, + zoneid = zoneid, + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t,"getting schedule for zone %s: %s",zonename or "?") + end + return result(false,"getting schedule for zone %s: %s",zonename or "?") +end + +local f = replacer ( + [[curl ]] .. + [[--silent --insecure ]] .. + [[-H "Authorization: bearer %accesstoken%" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-H "applicationId: %applicationid%" ]] .. + [["https://tccna.honeywell.com/WebAPI/emea/api/v1/location/%locationid%/status?includeTemperatureControlSystems=True" ]] +) + +local function getstatus(presets,locationid,locationname) + if locationid and validpresets(presets) then + local c = presets.credentials + local s = c and f { + accesstoken = c.accesstoken, + applicationid = applicationid, + locationid = locationid, + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t and t.gateways and t,"getting status for location %s: %s",locationname or "?") + end + return result(false,"getting status for location %s: %s",locationname or "?") +end + +local function validated(presets) + if validpresets(presets) then + local data = getaccesstoken(presets) + if data then + presets.credentials.accesstoken = data.access_token + local data = getuserinfo(presets) + if data then + presets.credentials.userid = data.userId + return true + end + end + end +end + +local function geteverything(presets,filename) + if validated(presets) then + local data = getlocationinfo(presets) + if data then + for i=1,#data do + local gateways = data[i].gateways + local locationinfo = data[i].locationInfo + local locationid = locationinfo and locationinfo.locationId + if gateways and locationid then + local status = getstatus(presets,locationid,locationinfo.name) + if status then + for i=1,#gateways do + local g = status.gateways[i] + local gateway = gateways[i] + local systems = gateway.temperatureControlSystems + if systems then + local s = g.temperatureControlSystems + for i=1,#systems do + local zones = systems[i].zones + if zones then + local z = s[i].zones + for i=1,#zones do + local zone = zones[i] + if zone.zoneType == "ZoneTemperatureControl" then + local z = z[i] + zone.schedule = getschedule(presets,zone.zoneId,zone.name) + if z.name == zone.name then + zone.heatSetpointStatus = z.heatSetpointStatus + zone.temperatureStatus = z.temperatureStatus + end + end + end + end + end + end + end + end + end + end + if not filename then + filename = presets.everything + end + if filename then + savetable(filename,data) + end + return result(data,"getting everything: %s") + end + end + return result(false,"getting everything: %s") +end + +local function gettemperatures(presets,filename) + if validated(presets) then + local data = loadeverything(filename or presets) + if data then + local updated = false + for i=1,#data do + local gateways = data[i].gateways + local locationinfo = data[i].locationInfo + local locationid = locationinfo.locationId + if gateways then + local status = getstatus(presets,locationid,locationinfo.name) + if status then + for i=1,#gateways do + local g = status.gateways[i] + local gateway = gateways[i] + local systems = gateway.temperatureControlSystems + if systems then + local s = g.temperatureControlSystems + for i=1,#systems do + local zones = systems[i].zones + if zones then + local z = s[i].zones + for i=1,#zones do + local zone = zones[i] + if zone.zoneType == "ZoneTemperatureControl" then + local z = z[i] + if z.name == zone.name then + zone.temperatureStatus = z.temperatureStatus + updated = true + end + end + end + end + end + end + end + end + end + end + if updated and filename then + data.time = ostime() + savetable(filename,data) + end + return result(data,"getting temperatures: %s") + end + end + return result(false,"getting temperatures: %s") +end + +local function setmoment(target,time,data) + if not time then + time = ostime() + end + local t = osdate("*t",time ) + local c_year, c_month, c_day, c_hour, c_minute = t.year, t.month, t.day, t.hour, t.min + -- + local years = target.years if not years then years = { } target.years = years end + local d_year = years[c_year] if not d_year then d_year = { } years[c_year] = d_year end + local months = d_year.months if not months then months = { } d_year.months = months end + local d_month = months[c_month] if not d_month then d_month = { } months[c_month] = d_month end + local days = d_month.days if not days then days = { } d_month.days = days end + local d_day = days[c_day] if not d_day then d_day = { } days[c_day] = d_day end + local hours = d_day.hours if not hours then hours = { } d_day.hours = hours end + local d_hour = hours[c_hour] if not d_hour then d_hour = { } hours[c_hour] = d_hour end + -- + c_minute = div(c_minute,15) + 1 + -- + local d_last = d_hour[c_minute] + if d_last then + for k, v in next, data do + local d = d_last[k] + if d then + data[k] = (d + v) / 2 + end + end + end + d_hour[c_minute] = data + -- + target.lasttime = { + year = c_year, + month = c_month, + day = c_day, + hour = c_hour, + minute = c_minute, + } +end + +local function loadtemperatures(filename) + local status = loadeverything(filename) + if status then + setmetatable(status,mt) + local zones = status[1].gateways[1].temperatureControlSystems[1].zones + if zones then + local summary = { time = status.time } + for i=1,#zones do + local zone = zones[i] + if zone.modelType == "HeatingZone" then + local temperatureStatus = zone.temperatureStatus + local heatSetpointCapabilities = zone.heatSetpointCapabilities + local heatSetpointStatus = zone.heatSetpointStatus + summary[#summary+1] = { + name = zone.name, + current = temperatureStatus and temperatureStatus .temperature or 0, + min = heatSetpointCapabilities and heatSetpointCapabilities.minHeatSetpoint or 0, + max = heatSetpointCapabilities and heatSetpointCapabilities.maxHeatSetpoint or 0, + target = heatSetpointStatus and heatSetpointStatus .targetTemperature or 0, + } + end + end + return result(summary,"loading temperatures: %s") + end + end + return result(false,"loading temperatures: %s") +end + +local function updatetemperatures(presets,filename,historyname) + if validpresets(presets) then + if not filename then + filename = presets.everything + end + if not historyname then + historyname = presets.history + end + gettemperatures(presets,filename) + local t = loadtemperatures(filename) + if t then + local data = { } + for i=1,#t do + local ti = t[i] + data[ti.name] = ti.current + end + local history = loadhistory(historyname) or { } + setmoment(history,ostime(),data) + savetable(historyname,history) + return result(t,"updating temperatures: %s") + end + end + return result(false,"updating temperatures: %s") +end + +local mt = { __index = { [1] = { gateways = { [1] = { temperatureControlSystems = { [1] = { } } } } } } } + +local function findzone(status,name) + if status then + setmetatable(status,mt) + local zones = status[1].gateways[1].temperatureControlSystems[1].zones + if zones then + for i=1,#zones do + local zone = zones[i] + if zone.modelType == "HeatingZone" and zone.name == name then + return zone + end + end + end + end +end + +local function getzonestate(filename,name) + local status = loadeverything(filename) + local zone = findzone(status,name) + if zone then + local t = { + name = zone.name, + current = zone.temperatureStatus.temperature or 0, + min = zone.heatSetpointCapabilities.minHeatSetpoint, + max = zone.heatSetpointCapabilities.maxHeatSetpoint, + target = zone.heatSetpointStatus.targetTemperature, + mode = zone.heatSetpointStatus.setpointMode, + schedule = zone.schedule, + } + return result(t,"getting state of zone %s: %s",name) + end + return result(false,"getting state of zone %s: %s",name) +end + +local f = replacer ( + [[curl ]] .. + [[-X PUT ]] .. + [[--silent --insecure ]] .. + [[-H "Authorization: bearer %accesstoken%" ]] .. + [[-H "Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml" ]] .. + [[-H "applicationId: %applicationid%" ]] .. + [[-H "Content-Type: application/json" ]] .. + [[-d "%[settings]%" ]] .. + [["https://tccna.honeywell.com/WebAPI/emea/api/v1/temperatureZone/%zoneid%/heatSetpoint"]] +) + +local function setzonestate(presets,name,temperature) + if validated(presets) then + local data = loadeverything(presets) + local zone = findzone(data,name) + if zone then + local m = type(temperature) == "number" and temperature > 0 and + { + HeatSetpointValue = temperature, + SetpointMode = "TemporaryOverride", + TimeUntil = osdate("%Y-%m-%dT%H:%M:%SZ",os.time() + 60*60), + } + or + { + HeatSetpointValue = 0, + SetpointMode = "FollowSchedule", + } + + local s = f { + accesstoken = presets.credentials.accesstoken, + applicationid = applicationid, + zoneid = zone.zoneId, + settings = jsontostring(m), + } + local r = s and resultof(s) + local t = r and jsontolua(r) + return result(t,"setting state of zone %s: %s",name) + end + end + return result(false,"setting state of zone %s: %s",name) +end + +local evohome = { + helpers = { + getaccesstoken = getaccesstoken, + getuserinfo = getuserinfo, + getlocationinfo = getlocationinfo, + getschedule = getschedule, + }, + geteverything = geteverything, + gettemperatures = gettemperatures, + getzonestate = getzonestate, + setzonestate = setzonestate, + loadtemperatures = loadtemperatures, + updatetemperatures = updatetemperatures, + loadpresets = loadpresets, + loadhistory = loadhistory, + loadeverything = loadeverything, +} + +if utilities then + utilities.evohome = evohome +end + +-- local presets = evohome.loadpresets("c:/data/develop/domotica/code/evohome-presets.lua") +-- evohome.setzonestate(presets,"Voorkamer",22) +-- evohome.setzonestate(presets,"Voorkamer") + +return evohome + diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index 1856519ab..9d1416601 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -802,6 +802,7 @@ + @@ -1156,6 +1157,7 @@ + diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml index 97b954e5a..9f47a1f53 100644 --- a/tex/context/interface/mkiv/context-en.xml +++ b/tex/context/interface/mkiv/context-en.xml @@ -22260,6 +22260,9 @@ + + + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 601963f61..8c8249219 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-mathfence.xml b/tex/context/interface/mkiv/i-mathfence.xml index 097863889..76151fae4 100644 --- a/tex/context/interface/mkiv/i-mathfence.xml +++ b/tex/context/interface/mkiv/i-mathfence.xml @@ -48,6 +48,9 @@ + + + @@ -204,4 +207,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 40b54dccd..ceab04020 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index f8ad44f8f..a02bce663 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 11/14/17 13:52:52 +-- merge date : 11/15/17 22:08:52 do -- begin closure to overcome local limits and interference -- cgit v1.2.3