LogicMachine Forum
Peak load limiter - 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: Peak load limiter (/showthread.php?tid=1779)



Peak load limiter - tomnord - 07.12.2018

Hello, has anybody got any good ideas on how to make a peak load limiter based on current KW usage or kwh? Scalable to varius amount of loads to be controlled.


RE: Peak load limiter - buuuudzik - 07.12.2018

I think firstly you should create a list of your controllable loads with their power and priority.


RE: Peak load limiter - Erwin van der Zwart - 07.12.2018

Hi,

I created this a while ago, maybe it could help you in your task.

Code:
-- Set adresses address_max = '1/1/2' address_hyst = '1/1/3' address_relais1 = '1/1/4' address_relais2 = '1/1/5' address_relais3 = '1/1/6' address_relais4 = '1/1/7' -- Get measured power power = event.getvalue() -- Get limit value max = grp.getvalue(address_max) -- Get Hysteresis hyst = grp.getvalue(address_hyst) -- Calculate floor value hyst_floor = math.floor((max - hyst) + 0.5) -- Check if chanels need to be turned on if power < hyst_floor then    -- get current state of relais 4  current_state_relais4 = grp.getvalue(address_relais4)  if current_state_relais4 == false then     grp.write(address_relais4, true)     -- exit script and after that cascade to chanel 3      return  end    -- get current state of relais 3  current_state_relais3 = grp.getvalue(address_relais3)  if current_state_relais3 == false then     grp.write(address_relais3, true)     -- exit script and after that cascade to chanel 2      return  end   -- get current state of relais 2  current_state_relais2 = grp.getvalue(address_relais2)  if current_state_relais2 == false then     grp.write(address_relais2, true)     -- exit script and after that cascade to chanel 1      return  end  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == false then     grp.write(address_relais1, true)    -- exit script      return  end end -- Check if chanel 1 need to be turned off, after that cascade to chanel 2, then cascade to chanel 3 etcetera if power > max then  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == true then    grp.write(address_relais1, false)  else      -- get current state of relais 2      current_state_relais2 = grp.getvalue(address_relais2)      if current_state_relais2 == true then        grp.write(address_relais2, false)    else           -- get current state of relais 3           current_state_relais3 = grp.getvalue(address_relais3)           if current_state_relais3 == true then             grp.write(address_relais3, false)         else               -- get current state of relais 4              current_state_relais4 = grp.getvalue(address_relais4)              if current_state_relais4 == true then                grp.write(address_relais4, false)              end           end      end  end end
BR,

Erwin


RE: Peak load limiter - tomnord - 07.12.2018

(07.12.2018, 21:19)Erwin van der Zwart Wrote: Hi,

I created this a while ago, maybe it could help you in your task.

Code:
-- Set adresses address_max = '1/1/2' address_hyst = '1/1/3' address_relais1 = '1/1/4' address_relais2 = '1/1/5' address_relais3 = '1/1/6' address_relais4 = '1/1/7' -- Get measured power power = event.getvalue() -- Get limit value max = grp.getvalue(address_max) -- Get Hysteresis hyst = grp.getvalue(address_hyst) -- Calculate floor value hyst_floor = math.floor((max - hyst) + 0.5) -- Check if chanels need to be turned on if power < hyst_floor then    -- get current state of relais 4  current_state_relais4 = grp.getvalue(address_relais4)  if current_state_relais4 == false then     grp.write(address_relais4, true)     -- exit script and after that cascade to chanel 3      return  end    -- get current state of relais 3  current_state_relais3 = grp.getvalue(address_relais3)  if current_state_relais3 == false then     grp.write(address_relais3, true)     -- exit script and after that cascade to chanel 2      return  end   -- get current state of relais 2  current_state_relais2 = grp.getvalue(address_relais2)  if current_state_relais2 == false then     grp.write(address_relais2, true)     -- exit script and after that cascade to chanel 1      return  end  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == false then     grp.write(address_relais1, true)    -- exit script      return  end end -- Check if chanel 1 need to be turned off, after that cascade to chanel 2, then cascade to chanel 3 etcetera if power > max then  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == true then    grp.write(address_relais1, false)  else      -- get current state of relais 2      current_state_relais2 = grp.getvalue(address_relais2)      if current_state_relais2 == true then        grp.write(address_relais2, false)    else           -- get current state of relais 3           current_state_relais3 = grp.getvalue(address_relais3)           if current_state_relais3 == true then             grp.write(address_relais3, false)         else               -- get current state of relais 4              current_state_relais4 = grp.getvalue(address_relais4)              if current_state_relais4 == true then                grp.write(address_relais4, false)              end           end      end  end end
BR,

Erwin

Thanks Erwin, this looks like it could work good as a startingpoint.
I'm new to LM5 and scripting, so trial and error will be nessesary, it's great to have some place to start.


RE: Peak load limiter - Erwin van der Zwart - 08.12.2018

Hi,

I also created something for EV chargers that the max output power is set by the number of active loaders and available power.

I could share that so you can see how that works, it’s a bit more complex.

BR,

Erwin


RE: Peak load limiter - tomnord - 08.12.2018

Sure, do share. Anything helps.


RE: Peak load limiter - Domoticatorino - 10.12.2018

(07.12.2018, 21:19)Erwin van der Zwart Wrote: Hi,

I created this a while ago, maybe it could help you in your task.

Code:
-- Set adresses address_max = '1/1/2' address_hyst = '1/1/3' address_relais1 = '1/1/4' address_relais2 = '1/1/5' address_relais3 = '1/1/6' address_relais4 = '1/1/7' -- Get measured power power = event.getvalue() -- Get limit value max = grp.getvalue(address_max) -- Get Hysteresis hyst = grp.getvalue(address_hyst) -- Calculate floor value hyst_floor = math.floor((max - hyst) + 0.5) -- Check if chanels need to be turned on if power < hyst_floor then    -- get current state of relais 4  current_state_relais4 = grp.getvalue(address_relais4)  if current_state_relais4 == false then     grp.write(address_relais4, true)     -- exit script and after that cascade to chanel 3      return  end    -- get current state of relais 3  current_state_relais3 = grp.getvalue(address_relais3)  if current_state_relais3 == false then     grp.write(address_relais3, true)     -- exit script and after that cascade to chanel 2      return  end   -- get current state of relais 2  current_state_relais2 = grp.getvalue(address_relais2)  if current_state_relais2 == false then     grp.write(address_relais2, true)     -- exit script and after that cascade to chanel 1      return  end  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == false then     grp.write(address_relais1, true)    -- exit script      return  end end -- Check if chanel 1 need to be turned off, after that cascade to chanel 2, then cascade to chanel 3 etcetera if power > max then  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == true then    grp.write(address_relais1, false)  else      -- get current state of relais 2      current_state_relais2 = grp.getvalue(address_relais2)      if current_state_relais2 == true then        grp.write(address_relais2, false)    else           -- get current state of relais 3           current_state_relais3 = grp.getvalue(address_relais3)           if current_state_relais3 == true then             grp.write(address_relais3, false)         else               -- get current state of relais 4              current_state_relais4 = grp.getvalue(address_relais4)              if current_state_relais4 == true then                grp.write(address_relais4, false)              end           end      end  end end
BR,

Erwin

Hi Erwin,
I have some question about this script. 

1. Is this a resident script or event base script? 
2 If is it a resident script which is the refresh time? In case it was a event base script, what is the event base object?
3 Power, hyst and power limit are 4 byte floating point object as per Watt?

Thank you for your help.

regards.


RE: Peak load limiter - Erwin van der Zwart - 10.12.2018

Hi,

1. Event based on the measured power
2. NA
3. Doesn’t matter, 1, 2, 4 byte is fine as all is numeric

BR,

Erwin


RE: Peak load limiter - Domoticatorino - 12.12.2018

(10.12.2018, 18:10)Erwin van der Zwart Wrote: Hi,

1. Event based on the measured power
2. NA
3. Doesn’t matter, 1, 2, 4 byte is fine as all is numeric

BR,

Erwin

Thank you Erwin. Works very good.

(10.12.2018, 18:10)Erwin van der Zwart Wrote: Hi,

1. Event based on the measured power
2. NA
3. Doesn’t matter, 1, 2, 4 byte is fine as all is numeric

BR,

Erwin

Thank you Erwin. Works very good.


RE: Peak load limiter - Erwin van der Zwart - 12.12.2018

Hi,

Here is a more complex script for load balancing, i use it for EV chargers, they can use max 63 Amp and need minimal 8 Amp, based on active chargers and available power the chargers are set to a maximum loader output over modbus (for our EVLink)

All works with TAG's on the binary state (active/not active) object and a offset of 1 in the main address (32/1/1 = State -> 32/1/1 = Set max charging output) so you can easily add multiple chargers (:
Code:
-- Get maximal available amperage Max_Amp = grp.getvalue('35/0/10') -- Get current messured amperage Current_Amp = grp.getvalue('35/0/11') -- Calculate available amperage for loaders Available_Amp = Max_Amp - Current_Amp -- Minimal amperage output on loader Min_Loader_Amp = 8 -- Maximal amperage output on loader Max_Loader_Amp = 63 -- Get all loaders on/off states All_Loaders = grp.tag('LoaderState') -- Function to sort table by updatetime local function tableSortCat (a,b)  return a.updatetime < b.updatetime end -- Sort table All_Loaders by updatetime table.sort(All_Loaders, tableSortCat) -- Create table with active loader Active_Loaders = {} -- Determine amount of active loaders Number_Active_Loaders = 0 -- Ceeate new table with values and only loader tagged bit objects for _, item in pairs(All_Loaders) do  if item.datatype == 1 or (item.datatype > 999 and item.datatype < 2000) then    if item.value == true then      Number_Active_Loaders = Number_Active_Loaders + 1    end    table.insert(Active_Loaders, {id = item.id, updatetime = item.updatetime, datatype = item.datatype, address = item.address, value = item.value})  end end -- Sort table Active_Loaders by updatetime table.sort(Active_Loaders, tableSortCat) -- Determine maximum loaders based on available power Max_Number_Loaders_Possible =  math.floor(Available_Amp / Min_Loader_Amp) -- Check if more loaders are active then max possible loaders if Number_Active_Loaders < Max_Number_Loaders_Possible then  Max_Number_Loaders_Possible = Number_Active_Loaders end --Set available amperage per loader Available_Amperage_Loader_Per_Unit = math.round(Available_Amp / Max_Number_Loaders_Possible, 2) --Check if output exceeds loaders Max_Amp if Available_Amperage_Loader_Per_Unit > Max_Loader_Amp then  Available_Amperage_Loader_Per_Unit = Max_Loader_Amp end -- Set loaders to 0 when current amperage exceeds max amperage if Current_Amp > Max_Amp then     Max_Number_Loaders_Possible = 0  Available_Amperage_Loader_Per_Unit = 0 end -- Write values to the output of each loader Number_Loaders_Value_Written = 0 for _, item in pairs(All_Loaders) do  Address_Table = string.split(item.address, "/")  New_Address = Address_Table[1]+1 .. '/' .. Address_Table[2] .. '/' .. Address_Table[3]  if item.value == true then    if Number_Loaders_Value_Written < Max_Number_Loaders_Possible then        grp.checkupdate(New_Address,Available_Amperage_Loader_Per_Unit)      Number_Loaders_Value_Written = Number_Loaders_Value_Written + 1    else      grp.checkupdate(New_Address,0)    end  else    grp.checkupdate(New_Address,0)  end end
BR,

Erwin


RE: Peak load limiter - BMA - 19.02.2021

(07.12.2018, 21:19)Erwin van der Zwart Wrote: Hi,

I created this a while ago, maybe it could help you in your task.

Code:
-- Set adresses address_max = '1/1/2' address_hyst = '1/1/3' address_relais1 = '1/1/4' address_relais2 = '1/1/5' address_relais3 = '1/1/6' address_relais4 = '1/1/7' -- Get measured power power = event.getvalue() -- Get limit value max = grp.getvalue(address_max) -- Get Hysteresis hyst = grp.getvalue(address_hyst) -- Calculate floor value hyst_floor = math.floor((max - hyst) + 0.5) -- Check if chanels need to be turned on if power < hyst_floor then    -- get current state of relais 4  current_state_relais4 = grp.getvalue(address_relais4)  if current_state_relais4 == false then     grp.write(address_relais4, true)     -- exit script and after that cascade to chanel 3      return  end    -- get current state of relais 3  current_state_relais3 = grp.getvalue(address_relais3)  if current_state_relais3 == false then     grp.write(address_relais3, true)     -- exit script and after that cascade to chanel 2      return  end   -- get current state of relais 2  current_state_relais2 = grp.getvalue(address_relais2)  if current_state_relais2 == false then     grp.write(address_relais2, true)     -- exit script and after that cascade to chanel 1      return  end  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == false then     grp.write(address_relais1, true)    -- exit script      return  end end -- Check if chanel 1 need to be turned off, after that cascade to chanel 2, then cascade to chanel 3 etcetera if power > max then  -- get current state of relais 1  current_state_relais1 = grp.getvalue(address_relais1)  if current_state_relais1 == true then    grp.write(address_relais1, false)  else      -- get current state of relais 2      current_state_relais2 = grp.getvalue(address_relais2)      if current_state_relais2 == true then        grp.write(address_relais2, false)    else           -- get current state of relais 3           current_state_relais3 = grp.getvalue(address_relais3)           if current_state_relais3 == true then             grp.write(address_relais3, false)         else               -- get current state of relais 4              current_state_relais4 = grp.getvalue(address_relais4)              if current_state_relais4 == true then                grp.write(address_relais4, false)              end           end      end  end end
BR,

Erwin

Hello,

A well working script, but is it a easy way to get the outputs to stay off only for 10-15 minutes a time and gets blocked to turn off for a 30-60min or something afterwards? So the it loops trough all the relay channels befor the first channel turns off again.

Bjørn