rdmtc / node-red-contrib-sun-position

This is a ultimate Node-Red Timer, Sun, Moon and Blind flow control.
Apache License 2.0
106 stars 25 forks source link

Is there an option for sun azimuth position for Southern hemisphere? #209

Open hvddrift opened 3 years ago

hvddrift commented 3 years ago

When using the blind node I believe the expectation is we are in the Northern hemisphere. I am having difficulty in working out the Start and End Degrees for Brisbane Australia with an East facing Window.

I would Assume I would enter in 90 and 0, but it does not accept it.

Screenshots https://i.imgur.com/QywUl0o.png

Hypnos3 commented 3 years ago

Can you please paste the screenshot directly to the issue in Github? I have no access to i.imgur.com.

hvddrift commented 3 years ago

QywUl0o

It was showing that in my case the smaller number (start) would be in the second box.

For example. The Sun rises in the East (at I assume) 90 deg from North.

Then transverses towards the North (0 deg) and then sets west. -90

My East facing window I (again assume) I would put the Strat as 90, and End as 0

Here is an example: https://www.sunearthtools.com/dp/tools/pos_sun.php Use 27.4689682,153.0234991

Brisbane City, Queensland, Australia

Thanks

Hypnos3 commented 3 years ago

can be tested in https://github.com/rdmtc/node-red-contrib-sun-position/releases/tag/1.2.0

hvddrift commented 3 years ago

Hi

I am still having issues with the node. If you make a new position, eg 27.4689682,153.0234991 and make an East facing Window where the Sun enters at 90 Degrees and Ends at 2 degrees you will see the node will throw an error.

waynethomas69 commented 2 years ago

@hvddrift, I'm in the southern hemisphere too. The easy solution is just to reverse the start and end values as if the sun rose in the west and set in the east. If your window was truly east-facing your wall would actually be running north to south, so the values you should enter would be start = 0 and end = 180; not the direction you are looking out the window. In my case, by house is rotated roughly 30ish degrees from true north. For my east-facing windows I have put the start as 30 degrees, and the stop as 120. Strictly speaking I should have put 210 for the stop value, but the sun is always below the horizon for us when the azimuth is greater than 90 degrees. For my north facing windows I have put -45 degrees as the start point, and 125 as the end point. The fact the sun actually starts coming in the window at 125, and ends at -45 doesn't cause issues - it works perfectly.

hvddrift commented 2 years ago

@waynethomas69 I totally missed this. Thank you. I have tried to play with it again. Is there any chance you could share your flow with me? For example, on the east window?

Again thanks for the fdeedback.

waynethomas69 commented 2 years ago

@hvddrift, below is the flow for my north-east facing window which works as expected; as the sun moves east to west the blind moves throughout the day to keep it blocked (in summer). The only thing that doesn't work is the overrides (which I have raised as a separate issue) so I can't get it to stay open when the sky is cloudy or when the sun is blocked by the soffit. There's a bunch of stuff adding hysteresis and limiting how often/far the blind is allowed to move, so it's a bit busy. I also use room and outside temperature rather than seasons to determine whether the blinds should block sun or maximise sun... these are all excuses for why it is so messy. [ { "id": "513e2cbe.766de4", "type": "tab", "label": "Blinds", "disabled": false, "info": "" }, { "id": "5c083b6f.bb90c4", "type": "openweathermap", "z": "513e2cbe.766de4", "name": "Weather", "wtype": "current", "lon": "174.743854", "lat": "-36.723076", "city": "", "country": "", "language": "en", "x": 240, "y": 100, "wires": [ [ "89a25b09.9ef248", "9f5c7d6.54fd08", "f0619733.3dc7e8" ] ] }, { "id": "89a25b09.9ef248", "type": "function", "z": "513e2cbe.766de4", "name": "clouds", "func": "msg.payload = Number(msg.payload.clouds);\nglobal.set(\"clouds\",msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 370, "y": 80, "wires": [ [ "6c9ba372.f6b81c" ] ] }, { "id": "6c9ba372.f6b81c", "type": "openhab2-out2", "z": "513e2cbe.766de4", "name": "Clouds", "controller": "dc36288e.c49b28", "itemname": "clouds", "topic": "ItemUpdate", "payload": "", "onlywhenchanged": false, "x": 520, "y": 80, "wires": [] }, { "id": "9f5c7d6.54fd08", "type": "compass-point", "z": "513e2cbe.766de4", "direction": "toCompass", "subset": "secondary", "language": "en", "inputField": "data.wind.deg", "outputField": "payload", "name": "Compass", "x": 380, "y": 120, "wires": [ [] ] }, { "id": "e63007df.98a398", "type": "inject", "z": "513e2cbe.766de4", "name": "Inject", "topic": "", "payload": "", "payloadType": "date", "repeat": "180", "crontab": "", "once": true, "onceDelay": 0.1, "x": 90, "y": 160, "wires": [ [ "5c083b6f.bb90c4", "fb3839f8.258698" ] ] }, { "id": "993d3cd.a3345c", "type": "sunpos", "z": "513e2cbe.766de4", "name": "", "lon": "174.743854", "lat": "-36.723076", "start": "sunrise", "startoffset": "-5", "end": "night", "endoffset": 0, "x": 370, "y": 220, "wires": [ [ "28d2ed1c.9dbd22" ] ] }, { "id": "1ed7a730.f243b9", "type": "function", "z": "513e2cbe.766de4", "name": "Rolling", "func": "// determines the average of all payload values passed in \n// over the specified time range\nconst range = 20 * 60 * 1000; // window time millisecs\nlet buffer = context.get('buffer') || [];\nlet total = context.get('total') || 0; // the accumulated total so far\n\nlet now = new Date();\nlet value = Number(msg.payload);\n// remove any samples that are too old\nwhile (buffer[0] && buffer[0].timestamp < now - range) {\n // remove oldest sample from array and total\n// node.warn(removing oldest ${buffer[0].timestamp});\n total -= buffer[0].value;\n buffer.shift();\n}\n// add the new sample to the end\nbuffer.push({timestamp: now, value: value});\ntotal += value;\n\ncontext.set('buffer', buffer);\ncontext.set('total', total);\n\nmsg.payload = total/buffer.length;\n//node.warn(length: ${buffer.length}, total: ${total}, average: ${msg.payload});\nreturn msg;", "outputs": 1, "noerr": 0, "x": 230, "y": 600, "wires": [ [ "eaaf71c0.e9bc3", "64d78721.f98018", "f7a4941a.2045b8" ] ] }, { "id": "eaaf71c0.e9bc3", "type": "hysteresis", "z": "513e2cbe.766de4", "name": "hot", "rising_threshold": "20", "falling_threshold": "19", "initial_edge": "any", "x": 370, "y": 560, "wires": [ [ "85f92e54.e3ab7" ] ] }, { "id": "64d78721.f98018", "type": "hysteresis", "z": "513e2cbe.766de4", "name": "cold", "rising_threshold": "9", "falling_threshold": "8", "initial_edge": "any", "x": 370, "y": 620, "wires": [ [ "da7dbe30.394c9" ] ] }, { "id": "85f92e54.e3ab7", "type": "function", "z": "513e2cbe.766de4", "name": "set hot", "func": "if (msg.edge == \"rising\") {\n flow.set(\"hot\",true);\n}\nelse {\n flow.set(\"hot\",false);\n}\nreturn;", "outputs": 1, "noerr": 0, "x": 490, "y": 560, "wires": [ [] ] }, { "id": "da7dbe30.394c9", "type": "function", "z": "513e2cbe.766de4", "name": "set cold", "func": "if (msg.edge == \"falling\") {\n flow.set(\"cold\",true);\n}\nelse {\n flow.set(\"cold\",false);\n}\nreturn;", "outputs": 1, "noerr": 0, "x": 500, "y": 620, "wires": [ [] ] }, { "id": "fb3839f8.258698", "type": "function", "z": "513e2cbe.766de4", "name": "hot/cold", "func": "let hot = flow.get(\"hot\") || false;\nlet cold = flow.get(\"cold\") || false;\nlet clouds = global.get(\"clouds\") || 0;\n\nif (hot) {\n msg.mode = 2;\n}\nelse if (cold) {\n msg.mode = 1;\n}\nelse {\n msg.mode = 0;\n}\nreturn msg;", "outputs": 1, "noerr": 0, "x": 220, "y": 220, "wires": [ [ "993d3cd.a3345c" ] ] }, { "id": "f7a4941a.2045b8", "type": "debug", "z": "513e2cbe.766de4", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "x": 390, "y": 680, "wires": [] }, { "id": "9e522336.78e15", "type": "blind-control", "z": "513e2cbe.766de4", "name": "Haddon", "topic": "output", "addIdType": "none", "addId": "", "positionConfig": "3781295f.518f16", "autoTrigger": true, "autoTriggerTime": "1800000", "startDelayTime": 10000, "results": [ { "p": "", "pt": "msgTopic", "v": "", "vt": "topic" }, { "p": "", "pt": "msgPayload", "v": "", "vt": "level" }, { "p": "blindCtrl", "pt": "msg", "v": "", "vt": "ctrlObj" } ], "blindIncrement": "1", "blindOpenPos": "100", "blindClosedPos": "0", "blindPosReverse": false, "blindPosDefault": "open (max)", "blindPosDefaultType": "levelFixed", "slatPosDefault": "", "slatPosDefaultType": "none", "overwriteExpire": "1800000", "rules": [ { "index": 0, "name": "Sunrise", "isValid": true, "valid": {}, "topic": "", "importance": 0, "resetOverwrite": false, "description": "<div>✎ Please edit this rule.</div><div><i class=\"fa fa-clock-o\" aria-hidden=\"true\"></i> ↥ until <var>sunrise end</var><div class=\"indent-time-text\"><i class=\"fa fa-step-backward\" aria-hidden=\"true\"></i> <span>at the earliest (min)</span> <var>7:30</var></div></div><div><div class=\"indent-level-text\"> <i class=\"fa fa-angle-down\" aria-hidden=\"true\"></i><span>blind position: </span> ↕ absolute <var>closed (min)</var></div></div>", "conditions": [], "time": { "type": "pdsTime", "value": "sunriseEnd", "operator": 0, "offsetType": "none", "offset": "1", "multiplier": 60000, "days": "*", "months": "*", "operatorText": "↥ until" }, "timeMin": { "type": "entered", "value": "7:30", "offsetType": "none", "offset": "1", "multiplier": 60000 }, "level": { "type": "levelFixed", "value": "closed (min)", "operator": 0, "operatorText": "↕ absolute" }, "slat": { "type": "none", "value": "" }, "version": 3 }, { "index": 1, "name": "Cloudy Sunset", "isValid": false, "valid": {}, "topic": "", "importance": 0, "resetOverwrite": false, "description": "<div>✎ Please edit this rule.</div><div><i class=\"fa fa-code-fork\" aria-hidden=\"true\"></i> <var>global.clouds</var> > 90</div><div><i class=\"fa fa-clock-o\" aria-hidden=\"true\"></i> ↧ from <var>blue hour dusk start</var> - 00:20<div class=\"indent-time-text\"><i class=\"fa fa-step-forward\" aria-hidden=\"true\"></i> <span>no later than (max)</span> <var>20:30</var></div></div><div><div class=\"indent-level-text\"> <i class=\"fa fa-angle-down\" aria-hidden=\"true\"></i><span>blind position: </span> ↕ absolute <var>closed (min)</var></div></div>", "conditions": [ { "condition": 1, "conditionText": "", "valueType": "global", "value": "clouds", "operator": "gt", "operatorText": ">", "thresholdType": "num", "threshold": "90" } ], "time": { "type": "pdsTime", "value": "blueHourDuskStart", "operator": 1, "offsetType": "num", "offset": "-20", "multiplier": 60000, "days": "*", "months": "*", "operatorText": "↧ from" }, "timeMax": { "type": "entered", "value": "20:30", "offsetType": "none", "offset": "1", "multiplier": 60000 }, "level": { "type": "levelFixed", "value": "closed (min)", "operator": 0, "operatorText": "↕ absolute" }, "slat": { "type": "none", "value": "" }, "version": 3, "enabled": true }, { "index": 2, "name": "Clear Sunset", "isValid": false, "valid": {}, "topic": "", "importance": 0, "resetOverwrite": false, "description": "<div>✎ Please edit this rule.</div><div><i class=\"fa fa-clock-o\" aria-hidden=\"true\"></i> ↧ from <var>blue hour dusk start</var><div class=\"indent-time-text\"><i class=\"fa fa-step-forward\" aria-hidden=\"true\"></i> <span>no later than (max)</span> <var>20:30</var></div></div><div><div class=\"indent-level-text\"> <i class=\"fa fa-angle-down\" aria-hidden=\"true\"></i><span>blind position: </span> ↕ absolute <var>closed (min)</var></div></div>", "conditions": [], "time": { "type": "pdsTime", "value": "blueHourDuskStart", "operator": 1, "offsetType": "none", "offset": "1", "multiplier": 60000, "days": "*", "months": "*", "operatorText": "↧ from" }, "timeMax": { "type": "entered", "value": "20:30", "offsetType": "none", "offset": "1", "multiplier": 60000 }, "level": { "type": "levelFixed", "value": "closed (min)", "operator": 0, "operatorText": "↕ absolute" }, "slat": { "type": "none", "value": "" }, "version": 3 } ], "sunControlMode": 16, "sunFloorLengthType": "num", "sunFloorLength": "550", "sunMinDelta": "10", "blindPosMin": "closed (min)", "blindPosMinType": "levelFixed", "blindPosMax": "open (max)", "blindPosMaxType": "levelFixed", "sunSlat": "", "sunSlatType": "none", "smoothTime": "1200000", "sunTopic": "", "windowTopType": "num", "windowTop": "2000", "windowBottomType": "num", "windowBottom": "900", "windowAzimuthStartType": "numAzimuth", "windowAzimuthStart": "-45", "windowAzimuthEndType": "numAzimuth", "windowAzimuthEnd": "125", "oversteers": [ { "mode": 1, "valueType": "global", "value": "clouds", "operator": "gte", "operatorText": "≥", "thresholdType": "num", "threshold": "95", "blindPos": { "type": "levelFixed", "value": "open (max)" }, "slatPos": { "type": "none", "value": "" } }, { "mode": 1, "valueType": "pdsCalcElevation", "value": "", "operator": "gte", "operatorText": "≥", "thresholdType": "numAltitude", "threshold": "50", "blindPos": { "type": "levelFixed", "value": "open (max)" }, "slatPos": { "type": "none", "value": "" } } ], "oversteerTopic": "", "x": 920, "y": 340, "wires": [ [], [ "42388b83.b92344" ] ] }, { "id": "f0619733.3dc7e8", "type": "debug", "z": "513e2cbe.766de4", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "x": 370, "y": 160, "wires": [] }, { "id": "5934e71b.459e68", "type": "openhab2-out2", "z": "513e2cbe.766de4", "name": "", "controller": "dc36288e.c49b28", "itemname": "haddon_blind", "topic": "ItemCommand", "payload": "", "onlywhenchanged": false, "x": 1260, "y": 340, "wires": [] }, { "id": "3d2491b9.b58ece", "type": "hysteresis", "z": "513e2cbe.766de4", "name": "hot", "rising_threshold": "22", "falling_threshold": "21", "initial_edge": "any", "x": 370, "y": 740, "wires": [ [ "d337ddca.1ab21" ] ] }, { "id": "d337ddca.1ab21", "type": "function", "z": "513e2cbe.766de4", "name": "set haddonHot", "func": "if (msg.edge == \"rising\") {\n flow.set(\"haddonHot\",true);\n}\nelse {\n flow.set(\"haddonHot\",false);\n}\nreturn;", "outputs": 1, "noerr": 0, "x": 520, "y": 740, "wires": [ [] ] }, { "id": "28d2ed1c.9dbd22", "type": "function", "z": "513e2cbe.766de4", "name": "hot room", "func": "let haddonHot = flow.get(\"haddonHot\") || false;\n\nif (haddonHot) {\n if (msg.mode != 1) { //if not winter mode\n msg.mode = 2; //set to summer mode\n }\n}\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 640, "y": 340, "wires": [ [ "9e522336.78e15" ] ] }, { "id": "dc6933bf.6f0bb", "type": "function", "z": "513e2cbe.766de4", "name": "get value", "func": "msg.payload = Number(msg.payload.split(' ')[0]);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 240, "y": 740, "wires": [ [ "3d2491b9.b58ece" ] ] }, { "id": "1667536f.fa948d", "type": "openhab2-in2", "z": "513e2cbe.766de4", "name": "Haddon Temp", "controller": "dc36288e.c49b28", "itemname": "temperature_haddon", "topic": "", "initialstate": true, "whenupdated": true, "whencommand": false, "whenchanged": false, "changedfrom": "", "changedto": "", "x": 90, "y": 740, "wires": [ [ "dc6933bf.6f0bb" ] ] }, { "id": "75c63f6e.0a3f1", "type": "openhab2-in2", "z": "513e2cbe.766de4", "name": "Outside Temp", "controller": "dc36288e.c49b28", "itemname": "gOutsideTemp", "topic": "", "initialstate": true, "whenupdated": true, "whencommand": false, "whenchanged": true, "changedfrom": "", "changedto": "", "x": 90, "y": 600, "wires": [ [ "1ed7a730.f243b9" ] ] }, { "id": "294be4f3.c57fdc", "type": "function", "z": "513e2cbe.766de4", "name": "Open?", "func": "var minMsg = { topic: \"setBlindSettingsBottom\",payload: 0};\nflow.set(\"haddonWindow\", msg.payload);\nif (msg.payload == \"OPEN\") {\n minMsg.payload = 50;\n} else {\n minMsg.payload = 0;\n}\nnode.send(minMsg);\nreturn;", "outputs": 1, "noerr": 0, "x": 790, "y": 440, "wires": [ [ "9e522336.78e15" ] ] }, { "id": "8fcc36ec.7110a8", "type": "trigger", "z": "513e2cbe.766de4", "op1": "", "op2": "", "op1type": "nul", "op2type": "payl", "duration": "15", "extend": true, "units": "s", "reset": "", "bytopic": "all", "name": "Last", "x": 670, "y": 440, "wires": [ [ "294be4f3.c57fdc" ] ] }, { "id": "ab5111b0.25eda", "type": "openhab2-in2", "z": "513e2cbe.766de4", "name": "Window", "controller": "dc36288e.c49b28", "itemname": "haddon_window", "topic": "", "initialstate": true, "whenupdated": false, "whencommand": false, "whenchanged": true, "changedfrom": "", "changedto": "", "x": 540, "y": 440, "wires": [ [ "8fcc36ec.7110a8" ] ] }, { "id": "8e49206e.06181", "type": "openhab2-in2", "z": "513e2cbe.766de4", "name": "Haddon Blind", "controller": "dc36288e.c49b28", "itemname": "haddon_blind", "topic": "", "initialstate": true, "whenupdated": false, "whencommand": false, "whenchanged": true, "changedfrom": "", "changedto": "", "x": 190, "y": 400, "wires": [ [ "73bea842.1e0b18", "1017b1ae.d96d9e" ] ] }, { "id": "52ad842b.b0fb7c", "type": "change", "z": "513e2cbe.766de4", "name": "Override", "rules": [ { "t": "set", "p": "position", "pt": "msg", "to": "payload", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 720, "y": 380, "wires": [ [ "9e522336.78e15" ] ] }, { "id": "b2c28280.4cb97", "type": "trigger", "z": "513e2cbe.766de4", "op1": "close", "op2": "open", "op1type": "str", "op2type": "str", "duration": "20", "extend": true, "units": "s", "reset": "", "bytopic": "all", "name": "Block", "x": 450, "y": 360, "wires": [ [ "e013c051.4873b" ] ] }, { "id": "e013c051.4873b", "type": "gate", "z": "513e2cbe.766de4", "name": "", "controlTopic": "output", "defaultState": "open", "openCmd": "open", "closeCmd": "close", "toggleCmd": "toggle", "defaultCmd": "default", "statusCmd": "", "persist": false, "x": 590, "y": 380, "wires": [ [ "52ad842b.b0fb7c" ] ] }, { "id": "73bea842.1e0b18", "type": "function", "z": "513e2cbe.766de4", "name": "Record", "func": "flow.set(\"haddonBlind\", Number(msg.payload));\nreturn;", "outputs": 1, "noerr": 0, "x": 400, "y": 440, "wires": [ [] ] }, { "id": "1017b1ae.d96d9e", "type": "delay", "z": "513e2cbe.766de4", "name": "delay", "pauseType": "delay", "timeout": "1", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "x": 430, "y": 400, "wires": [ [ "e013c051.4873b" ] ] }, { "id": "7d1be00.75c362", "type": "link out", "z": "513e2cbe.766de4", "name": "Block Out", "links": [ "adddaf3c.bf09e" ], "x": 1195, "y": 420, "wires": [] }, { "id": "adddaf3c.bf09e", "type": "link in", "z": "513e2cbe.766de4", "name": "Block In", "links": [ "7d1be00.75c362" ], "x": 355, "y": 360, "wires": [ [ "b2c28280.4cb97" ] ] }, { "id": "42388b83.b92344", "type": "function", "z": "513e2cbe.766de4", "name": "Output?", "func": "var current = flow.get(\"haddonBlind\");\nmsg.payload = msg.payload.level;\nvar delta = Math.abs(msg.payload - current);\n\nif (delta > 3) {\n return msg;\n}\nelse {\n return;\n}", "outputs": 1, "noerr": 0, "x": 1080, "y": 340, "wires": [ [ "5934e71b.459e68", "7d1be00.75c362" ] ] }, { "id": "dc36288e.c49b28", "type": "openhab2-controller2", "z": "", "name": "Openhab3", "protocol": "http", "host": "openhabianpi", "port": "8080", "path": "", "username": "", "password": "", "ohversion": "v3" }, { "id": "3781295f.518f16", "type": "position-config", "z": "", "name": "Home", "isValide": "true", "longitude": "0", "latitude": "0", "angleType": "deg", "timeZoneOffset": "99", "timeZoneDST": "0", "stateTimeFormat": "3", "stateDateFormat": "12", "contextStore": "" } ]