Ramp times

Discussion in 'C-Bus Automation Controllers' started by ssaunders, Sep 13, 2022.

  1. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    Lols, @Ashley. Python is a weapon. Like LUA, in the wrong hands it... bights.

    Soz to disagree, and I'm not getting all trollie here, but want to share and educate. This forum isn't like like Reddit, but we are a teensy bit waay off-topic re. ramping. so I feel dirty.

    C++ associativity is left to right, and logical and (&&) has higher precedence than logical or (||), so the associativity sticks with the higher precedence. Consider:

    ++i || ++j && ++k

    gets grouped as...

    (++i) || (++j && ++k)

    Left to right, yes, but considering precedence plus associativity, hence the grouping. Both associativity and precedence must be considered hand-in-hand.

    LUA is very similar. As the manual says, use parentheses when in doubt. https://www.lua.org/pil/3.5.html. 'And' is before 'or' in precendence, with left association. Same as C/C++/SQL/Basic/Fortran/Pascal/COBOL/PL/1... (except APL)

    C++ programmer for many more years than I deserve, smacking my head into stack and memory leak issues. (And yes, I was also a COBOL and PL/1 programmer. That old.) And now I deserve LUA??? Yeah, nah. Python day job for the win. I get to play with toys all day now. At a bank.
     
    Last edited: Nov 1, 2023
    ssaunders, Nov 1, 2023
    #21
    Ashley likes this.
  2. ssaunders

    kojobomb

    Joined:
    May 27, 2019
    Messages:
    76
    Likes Received:
    6
    Location:
    Possum Brush
    Coming from someone that didn't even know what an IP address was a couple of years back, and drowning in acronyms. I couldn't care less about the different languages idiosyncrasies I just need to know what trumps what and make everything work together seamlessly.
    If you hadn't already worked out yet this property is completely off grid and running 3phase power from batteries which make power management the highest priority.
    I am grateful of your help, support, insights, knowledge and banter because each time I'm learning something new.
    Thank you goes out to @SgrAystar clarity on the small nuances helps out big time.
    Now for my question, its not really off topic but relates to this GA's ramped levels.
    I have 10 or so subsections of power usage items that will grow over the years as we put in more buildings and infrastructure, all of these will need to be link to this ramped GA.

    Hot Water Systems x 4 at present but will become about 8 or more eventually
    Underfloor heating zones x 15 but could grow too
    HVAC units x 4 at present but will rise to about 8
    Water Transfer pumps x 3 at present
    irrigation pumps x 3 but will increase
    pool pumps x 3
    Water feature/koi pond
    Dam Areators
    Workshop heating processes
    Bar Fridges
    Electric farm vehicles

    Instead of assigning an exact level location on the '0-255' scale to each individual item, this will eventually become a headache to manage and track and place new items into, I'm looking for suggestions or best practice to implement a list that will continually hold all items and keep them evenly spread over the 255 levels (devices x 50, 255/50=5.1 rounded down to 5 levels per device) (devices x 100, 255/100= 2.55 down to 2 levels per device)
    Am I making this too complicated? or should I just allocate
    1-20 for hot water
    21-40 for underfloor heating
    41-60 for AC and so on......

    In summer when I deactivate underfloor heating from the list it will leave a large gap in the daily ramping of energy use.
    Any thoughts on this @Pie Boy @Ashley @ssaunders
     
    kojobomb, Nov 1, 2023
    #22
  3. ssaunders

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,534
    Likes Received:
    175
    Location:
    Adelaide, Australia
    Sorry to go off topic. Language idiosyncrasies are an entertaining diversion for us nerds. :)

    Anyway, can you please explain the function of ramping through all your devices. I'm not really sure what you are trying to accomplish.
     
    Ashley, Nov 2, 2023
    #23
  4. ssaunders

    kojobomb

    Joined:
    May 27, 2019
    Messages:
    76
    Likes Received:
    6
    Location:
    Possum Brush
    I didnt feel like you had gone off topic, I was afraid to hijack this thread and go off topic. In fact this new home and build has now got everyone calling me out to be a nerd, I'm actually enjoying this rabbit hole.
    The ramping is to turn these devices on based upon battery state or charge "SOC" and available surplus energy from solar system.
    Living off the grid successfully dictates that during the day there is an abundance of unused power to accommodate for the shortest day of the year and the longest spell of poor weather.
    Using this power during the daytime is the most critical aspect of energy use so that battery use at night time is kept to a minimum since battery size is probably the largest single cost outside of construction.
    Water supply is from a pressurised system and supplies 1000ltrs and re-pressurises in the morning
    Hot water systems only heat during the day
    Irrigation and pool run during the day
    These are all on schedules but i want them to run based on the surplus energy hence why I have scripted a GA to ramp based upon these variables.
     
    kojobomb, Nov 2, 2023
    #24
  5. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    I'm still missing something, too. I can't make the leap from a ramp to a selective on/off event.

    So you monitor state of charge, then want to selectively turn on certain loads during daytime only, based on whether the SOC says it's acceptable to do so?
     
    ssaunders, Nov 2, 2023
    #25
  6. ssaunders

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,534
    Likes Received:
    175
    Location:
    Adelaide, Australia
    You beat me to it :) What exactly is the ramping ga doing?
     
    Ashley, Nov 2, 2023
    #26
  7. ssaunders

    kojobomb

    Joined:
    May 27, 2019
    Messages:
    76
    Likes Received:
    6
    Location:
    Possum Brush
    The ramping GA was firstly so that i could log the script to prove conception and watch the GA against power fluctuations as of now it isn't doing anything other than proving that i can use the variables in a script to get a GA to ramp either way based on SOC and power availability.
    Now i am in need of converting this GA into selectivity of the loads that i have on schedules at present.
    I am completely flying blind and fumbling my way through cbus and the programming side of things.
    Can you explain what is the best way to convert the script that I now have proof of conception into the switching on/off of these devices??
    Is Keywords again the way forward?
     
    kojobomb, Nov 2, 2023
    #27
  8. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    I think I understand now. I think.

    You vary the ramp rate based on the duration of runtime that you expect will represent an acceptable duration for loads throughout the day. This is initially based probably on available power/SOC as at a given point at the start of each the day, then maybe varied during the day based on SOC updates. And this is essentially a countdown 'timer' that you want to use to turn device type A off at level 90, B at 110, C at 125? Right?

    If so, I think I'd do this another way. If I'm way off then more description required.
     
    ssaunders, Nov 2, 2023
    #28
  9. ssaunders

    kojobomb

    Joined:
    May 27, 2019
    Messages:
    76
    Likes Received:
    6
    Location:
    Possum Brush
    Once batteries have charged up to 90% capacity the GA ramps from 0-255 over 60 minutes and all loads start to be turned on sequentially and as long as the battery stays above 90% and the battery is not suplementing extra power into the system all loads continue to run.
    If the batteries start to supplement the PV power then the GA starts to ramp down over 15 minutes removing devices from the electricity supply and when the batteries no longer supply any power the GA starts to ramp up again using only the PV power maintaining a battery above 90% charge for the evening ahead.
    What is the easiest way to tag or list all of these devices and then link them to either the script or to the GA so that they follow the GA levels?

    Eventually i would like to be able to vary the ramp rate but for now I can just fine tune it via the script.
     
    kojobomb, Nov 2, 2023
    #29
  10. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    I think I would approach it like this, but I do consider your ramp approach as well.

    Add keywords on GAs that indicate whether they should be commanded by a script, and in what sequence they should be commanded. Something like "LOADCTL, group=whatever". A script could then read these keywords and build a table of devices to manage.

    A resident script that does the following:
    • Maintains a table of groups (used in group=)
    • Maintains its table of devices to manage by reading keywords (either one-off, or by periodically checking for changes). I point to an example of check for changes below, otherwise it's a script re-start required to re-read the table for changes.
    • If the stagger rate for group keywords (i.e. types of devices) is fixed, then just hard code it in the groups table, otherwise get that from another keyword, or calculate an even spread over start/stop periods, and store that in the groups table.
    • Set local cycle = 'idle'
    • In a loop with suitable periodic delay - the best kind of LUA delay is a socket library quirk: socket.select(nil, nil, seconds), which will not hog the AC2 CPU while it's sleeping, and also does fractions of a second.
    • In the same loop, get the current state of charge, etc.
    • In the same loop, if batteries reach 90%, then initiate a timed power-up sequence, essentially recording something like local cycleTime = socket.gettime(); local cycle='on' when hitting 90%. If in an 'on' cycle, once a time has passed for a group, initiate their power-up. This should probably be a staggered start, and that could be as simple as adding a table entry of additional increment delay for each group member. (Discover a new group member per keywords above, and add 5 or 10 seconds to its start time.) Once all devices are powered on, set cycle = 'idle'.
      You'd need to get the current state of all GAs at the start of each cycle to handle the event of a prior power down not fully getting to the end of the sequence, enabling skip-forward in wait time before starting more.
    • In the same loop, if the batteries start to supplement PV then cancel any additional start by setting cycle = 'off' and set cycleTime = socket.gettime(). Do the same as for power-up, but progressively powering down over time (probably without group stagger).
    That all assumes that there's enough PV to sustain the loads without any power state "flapping" occurring. So some hysteresis and sensible flapping limits for each day are probably called for.

    Or you could go with the funky ramp. It's probably ultimately simpler. Writing the current level to a GA is smart, as it would provide a simple way to survive script re-starts, and pick up where it left off. Or even better, why don't you use a User Parameter for this purpose? They store much bigger numbers than 0->255, so would give far greater timing granularity. Or you could just use a variable.

    In the ramp case, you could add keywords like "LOADCTL, level=10", causing the load to go on/off when the ramp GA hits that level (don't forget that the results of doing a keyword:split('=')[2] would need to be converted to a number using tonumber(), and also don't forget to check current device state before changing it because long ramp). For two or more level=10s you could add a simple delay in the script between "on" commands. Making delays not interfere with the ramp would presuppose that the total of all delays was less than each ramp increment, but this could be made non-blocking too. Your script will know whether it is ramping up or down, because it is the one doing the ramping, so can decide whether it should turn something on or off when a given level is reached.

    Or the level= keyword could be changed to a group=, and store the levels to use for each group in a table.

    For advanced use of keywords hints, head to https://github.com/autoSteve/acMqtt. I do this a lot, including change detection. The HUE send seceive script is probably easiest to approach. MQTT send receive does its keyword thing in a more elegant, but obtuse way, so would probably confuse one relatively new to LUA.

    Hope that lot makes sense.

    (edited for typos)
     
    Last edited: Nov 2, 2023
    ssaunders, Nov 2, 2023
    #30
  11. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    For another example where I utilise keywords, but do not check for keyword changes (i.e. requires script restart) is at https://github.com/autoSteve/dPIR. This is quite a straightforward resident script. It builds a table of things to monitor/parameters on startup, then moves on to an infinite loop with at most 1 second between iterations (you'd replace the socket:receive with something like socket.select(nil, nil, 1) for a simple one second delay).
     
    ssaunders, Nov 3, 2023
    #31
  12. ssaunders

    SgrAystar

    Joined:
    Oct 4, 2018
    Messages:
    60
    Likes Received:
    5
    Location:
    Melbourne, Australia
    This is exactly the type of puzzle that I know I would get hooked by, starting with a proof of concept, building something bigger than Ben Hur, realising most of it would better left alone ... I also haven't yet worked out a way for myself to shortcut that journey :rolleyes:

    I you stick at it you will get to the type of things mentioned above, but I think as someone on a coding learning curve I would approach it from a different angle.

    In advance it is interesting to think about efficiency & performance, but when you are using the system it will be all about reliability so start by using things you know will work.
    Will it be predictable for occupants?
    How to does someone manually override the automation?
    How will others use the system when it breaks and you are not there?
    How to deal with exceptions? Heat wave, unexpected visitors, equipment failure, complaints from cabin guests?

    Use scenes & schedules.
    Start by putting everything in one scene for winter day. Duplicating multiple times gives you a copy of the scene that you can schedule every Xmin thoughout the day to turn items on/off.
    Copy the whole lot again and adjust for a summer day, similar for spring/autumn.
    Now you will have a lot of scenes/schedules but it will rock solid.

    Start tinkering.
    As @ssaunders said you can use Use Parameters in the scenes. Use the same tag names &/or ga numbers as your lighting groups to make correlation easy.
    An integer parameter can hold the number of minutes for a timer. A string parameter can hold a startTime=, stopTime=, etc. Then scripts can use these values to set timers and act on them.
    Start by putting everything in one scene with Start/Stop times assuming 12 hour day. Scripts can use the number of minutes for the current day to expand or compress the times to fit the current day.
    The string may specify startLevel/StopLevel for a water tank pump instead of time.
    Now you have far less scenes/schedules still using the standard GUIs to manage them, plus relatively straightforward scripts to interpret the integers/strings.

    Optimising.
    Define each load in terms of: priority, minimum time, maximum time, nominal load.
    The position in the scene can represent priority and the others can be listed in the string, or it may be time to build a visualisation that represents the table.
    Leave the important items on timers and start turning optional items on/off depending on ambient conditions. This will get as complicated as you decide to make it.
    For each load in the scene,
    if max criteria met turn off and credit headroom​
    If headroom available
    go through the loads in priority order (top to bottom)
    if min criteria not met & nominal load under headroom, turn on and debit headroom
    Stop when no more headroom or end of list​
    If headroom still available
    go through the loads in priority order (top to bottom)
    if paused, turn on and debit headroom
    Stop when no more headroom or end of list​
    If still headroom available
    do nothing?​
    If no headroom available
    go through loads in reverse priority
    if min criteria not met, mark as paused, turn off and credit headroom
    Stop when headroom is positive
    Somehow deal with hysteresis so loads do not flipflop on/off.​

    Sit back with a hopefully cold drink from the bar fridge and research open source or off-the-shelf energy management systems ;)
     
    SgrAystar, Nov 3, 2023
    #32
    ssaunders likes this.
  13. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    :D:D:D @SgrAystar

    There be wisdom here, @kojobomb.

    The scripted integration of CBus with HomeAssistant that I have built on the AC is pretty rock solid these days, but has taken years to get there, helped by getting feedback and suggestions from others via Github. And yet bugs still pop up.

    Others implemented simple hacky proof of concept stuff to do this at less than 100 lines. Mine functionally worked at 1,000 lines. It now reliably works for me and others at 1,800 lines and countless hours invested.

    I built it because I had to. Nothing else with less moving parts existed, nothing was as complete, and most solutions relied on something like an unreliable Rasberry Pi, CGate, CNI and heaps of config in HomeAssistant.

    But if there was a more reliable or off-the-shelf alternative at the outset I would have jumped on it.

    I'm also alone in the house these days. No "Wife Approval Factor". Kids have flown the coop. No guests. So if my Philips Hue bedside lights don't turn off for some weird reason when I hit the "All off" CBus button I just unplug them and debug later.
     
    ssaunders, Nov 4, 2023
    #33
    SgrAystar likes this.
  14. ssaunders

    kojobomb

    Joined:
    May 27, 2019
    Messages:
    76
    Likes Received:
    6
    Location:
    Possum Brush
    Oh my god, I'm in stitches right now, head is sore from trying to comprehend everything and see my way through this cloud (its getting clearer every day, oh and easier, just dropped another 2 scripts in today for small items that have caused previous issues with battery use usually through forgetfulness of turning things off, scripting its getting quicker now).
    I have no "other half" so zero approval needed, my kids have chosen city life and I'm now loaded with lots of space and spare time to build, play and do things I want to. Completely over building everything as I've been accused of my whole life,
    I love the challenge and its actually coming together just as I envisioned it, I was messing around with CSS coding to get my visualization looking right last night, i will be reading this thread over and over again for the next while trying to get everything ironed out.
    I feel like I'm getting the knowledge from you @ssaunders and the wisdom from your comments @SgrAystar.
     
    kojobomb, Nov 4, 2023
    #34
  15. ssaunders

    ssaunders

    Joined:
    Dec 17, 2008
    Messages:
    242
    Likes Received:
    35
    Location:
    Melbourne
    Righto, @kojobomb. Sounds like a perfect situation for over-engineering everything to me, then going for simple only when it all turns to custard. You do you, and grin while getting smarter. #nerd.

    Love it.
     
    ssaunders, Nov 4, 2023
    #35
    Mr Mark likes this.
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.