![]() |
|
Outside compensation curve - Printable Version +- LogicMachine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8) +--- Thread: Outside compensation curve (/showthread.php?tid=1770) |
Outside compensation curve - oyvindnordbo - 04.12.2018 I have tried to make an outside compensation curve for a heating system in the FB editor, but do not find out completely of unwanted blocks that are most powerful to use. I need to write from four groups -10 ° C = 45 ° C -5 ° C = 40 ° C 0 ° C = 35 ° C 5 ° C = 30 ° C In order to get a set point out of what outdoor temperature it is, is this possible? RE: Outside compensation curve - admin - 04.12.2018 Do you really need a curve here? From your data it looks like simple linear compensation, for each 5 degrees of temperature the setpoint is lowered by 5 degrees: Code: setpoint = 35 - temperatureRE: Outside compensation curve - oyvindnordbo - 04.12.2018 Yes wee need a curve besause all values is going to be able to change in the visualizatione RE: Outside compensation curve - admin - 04.12.2018 This might be helpful: http://lua-users.org/wiki/SimpleFit RE: Outside compensation curve - Daniel - 04.12.2018 There is block in match advance curve function with 2 points, it might be good starting point. RE: Outside compensation curve - merel - 04.12.2018 Hello. You can try this: Code: function linear_by_table(input,curve,offset)
local FDY = offset or 0
fk1= (curve["y"][1] - curve["y"][2]) / (curve["x"][1] - curve["x"][2])
fk2= (curve["y"][2] - curve["y"][3]) / (curve["x"][2] - curve["x"][3])
fk3= (curve["y"][3] - curve["y"][4]) / (curve["x"][3] - curve["x"][4])
if input < curve["x"][1] then
out = curve["y"][1] + FDY;
elseif input >= curve["x"][1] and input < curve["x"][2] then
out = fk1 * (input - curve["x"][1]) + curve["y"][1] + FDY
elseif input >= curve["x"][2] and input < curve["x"][3] then
out = fk2 * (input - curve["x"][2]) + curve["y"][2] + FDY
elseif input >= curve["x"][3] and input < curve["x"][4] then
out = fk3 * (input - curve["x"][3]) + curve["y"][3] + FDY
else
out = curve["y"][4] + FDY
end
return out
end
curve = {}
curve["x"] = {-20,-10,0,20}
curve["y"] = {80,70,65,18}
--offset=2
--log(linear_by_table(20,curve,offset))
log(linear_by_table(-15,curve))RE: Outside compensation curve - jerryhenke - 16.01.2025 (04.12.2018, 13:45)merel Wrote: Hello.Wow. Thanks! Used this today and made some small changes. My code looks like this and runs nicely. Code: function linear_by_table(input, curve, offset)
local FDY = offset or 0
local n = #curve["x"] -- Number of points
if n ~= #curve["y"] then
error("x and y lists must have the same number of values")
end
local out
if input < curve["x"][1] then
out = curve["y"][1] + FDY
elseif input >= curve["x"][n] then
out = curve["y"][n] + FDY
else
for i = 1, n - 1 do
if input >= curve["x"][i] and input < curve["x"][i + 1] then
local fk = (curve["y"][i + 1] - curve["y"][i]) / (curve["x"][i + 1] - curve["x"][i])
out = fk * (input - curve["x"][i]) + curve["y"][i] + FDY
break
end
end
end
return out
end
-- Define the curve for interpolation
local curve = {x = {-20, -10, 0, 10, 20}, y = {42, 34, 32, 25, 15}}
-- Adjust offset to shift the entire curve
local offset = 0
-- Get outdoor temperature from KNX address 0/3/0
local outdoor_temp = grp.getvalue('0/3/0')
-- Calculate the flow setpoint based on the outdoor temperature
local flow_setpoint = linear_by_table(outdoor_temp, curve, offset)
-- Write the calculated value to KNX address 5/5/0
grp.write('5/5/0', flow_setpoint)
-- Log the results
log('Outdoor temperature: ' .. outdoor_temp .. ', Flow setpoint: ' .. flow_setpoint)RE: Outside compensation curve - Erwin van der Zwart - 16.01.2025 For the outdoor temp combined with a curve i usually use a 3 days average, this can simply be done by attaching a trend to your measurement object and use this small script. Code: require('trends')
dateslastthreedays = {}
dateslastthreedays['start'] = os.date('*t', os.time() - (86400 * 4))
dateslastthreedays['end'] = os.date('*t', os.time() - (86400 * 1))
threedaysaverage = trends.fetchone('OUTDOOR TEMP', dateslastthreedays)RE: Outside compensation curve - jerryhenke - 16.01.2025 (16.01.2025, 17:08)Erwin van der Zwart Wrote: For the outdoor temp combined with a curve i usually use a 3 days average, this can simply be done by attaching a trend to your measurement object and use this small script. The only trend I have right now is outdoor temperature with a 5-min resolution. I tried your script and can't really make it work. I get incorrect values. I would rather like to use a span of the last 9 hours average temperature or so, not from four days agou until yesterday which i read your script. I tried change 86400 * 4 to 86400 * 1 and the "end" to 86400 * 0, but that gives 0 as temperature. Any good suggestions? Quote:require('trends') RE: Outside compensation curve - Erwin van der Zwart - 17.01.2025 You always fetch a full day, that is why my sample is using yesterday until 4 days back, so 3 full days.. From the knowledge base (time values are ignored) : Code: dates - Lua table with two items - start and end, each item must contain year, month, day keys, time values (hours, minutes and seconds) are ignoredYou can get today via: Code: require('trends')
local today = {}
today['start'] = os.date('*t', os.time())
today['end'] = os.date('*t', os.time() + 86400)
-- Fetch the average temperature for the timespan
local todayaverage = trends.fetchone('Temperatuur Woonkamer', today)
log(todayaverage)To see the full data used just change -> trends.fetchone into -> trends.fetch, here you will see all samples of today RE: Outside compensation curve - admin - 17.01.2025 KB doc needs updating. It's possible to fetch data for the given period if start/end is a not a table but a timestamp number. Fetch data for the last hour: Code: date = os.date('*t') -- current date as a table
time = os.time(date, true) -- convert UTC timestamp
-- fetch data for the last hour (3600 seconds)
datarange = {
['start'] = time - 3600,
['end'] = time,
}
data = trends.fetch('trend name', datarange)
log(data)RE: Outside compensation curve - Erwin van der Zwart - 17.01.2025 Great! This makes it so much easier to use in many cases (: RE: Outside compensation curve - jerryhenke - 17.01.2025 (17.01.2025, 08:18)admin Wrote: KB doc needs updating. It's possible to fetch data for the given period if start/end is a not a table but a timestamp number. Amazing. Now it seems to work. I ended up with this script for a damped outdoor temperatur that i later use for my control of floor heating. Thougts? Also - do I have to define the resolution of the trend log that I use? Now mine is 5 minutes, but I am also starting a 1 hour-resolution trend log of outside temperature. I imagine less work for LM to calculate the average if I have a table with less values? Quote:require('trends') |