This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Peak load limiter
#1
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.
Reply
#2
I think firstly you should create a list of your controllable loads with their power and priority.
Done is better than perfect
Reply
#3
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
Reply
#4
(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.
Reply
#5
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
Reply
#6
Sure, do share. Anything helps.
Reply
#7
(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.
Reply
#8
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
Reply
#9
(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.
Reply
#10
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
Reply
#11
(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
Reply


Forum Jump: