Sonos simple rule to decrease automically playing volume when going to bed

  • Platform information:
    • Hardware: RPi 3b sd card
    • OS: openhabian
    • Java Runtime Environment: which java platform is used and what version ( don’t know)
    • openHAB version:3.1.0
  • Issue of the topic:
    I have my Sonos players connected to Openhab . I mainly use the iOS app to control and monitor them but did not find any way to stop the playing music in my bedroom with a defined delay like 30 min and having playing volume decrease before to go off.
    I was wondering if a rule running on Openhab could control this
    I am a complete noob on rules definition in Openhab.
    I have more experience in nodered where I did the last rules I needed.
    I was thinking that perhaps another Openhab Sonos user already has the same idea and found something…

Thanks for any help.

No, i don’t have anything like that, but I have a somewhat similar use case.
My wife enjoys setting all the speakers at different volume around the house.
And then, at 04 am she likes to walk around asking google questions.
50% volume at 4am is very different than at 4pm…

So I have a basic routine in node red that updates the volume of all devices, and keeps them stable during the day.
For example:
At 8am: all speakers to 20%
At 10am: all speakers to 35%
At 8pm: all speakers to 15%
At 10 pm: all speakers to 5%

At 5% I can still listen to music while in bed. So I can say “play music for one hour” and after an hour the music stops.
At that point Im asleep, I don’t need any fancy fade effect there.
Though I’ll refrain from sharing your idea with the wife…

If you want to decrease the volume over time, I would suggest to start multiple timers:

E.g.
Set the volume to 30% right now
In 5 minutes from now, set the volume to 25%
In 10 minutes from now (5 min after the prior timer), set the volume to 20%
Etc…

If you are new to the rules engine, I would recommend to use blockly, as thats most likely the most easy way to start

Hello @Pedro_Liberal and @Matze0211,
Thank you for your fast answer.
For now, I have only one Sonos one with voice command possibility, sothat I did not investigate in this way, but the voice is only another way to give order to Openhab.
So I think I could begin with the command play music for 30 min and then later investigate on fading the volume…
Basically my idea was to define a volume decrease time rate.
I love also Pedro idea to fix the volume depending of day time …
I would define a sleep switch that I can activate .

When sleep switch is activated, I detect now time and calculate stop time aFading time starts 10 min before stop time.
When switch is on , every minute i trigger a script that does the following actions:

  • I calculate remaining time.
  • When remaining time is equal to 10 min, i mesure the player volume and store it in a variable
  • When remaining time is lower than 10 min, I set volume to remaining time/ 10• measured volume variable
  • When remaining time <0 I stop the player and reset the sleep switch.

This is probably more a PLC world approach than a event Openhab prorgramming method, so I am open to any comment to improve it.
Then the next step is to convert this algorithm in a blocky sketch.

You’re over complicating things a bit I think?
I try not to store too many variables, and instead directly set the state to what I want.

So for example, if that sleep switch is used to help you fall asleep, you could make it so that when you turn it on, it immediately sets the volume to x%, and then you add delay nodes every x minutes to continuously adjust the volume down. (Like you said, very PLC way of thinking, but that’s what I usually see around.)

Storing the variable would allow you to use that switch for other purposes yes, but then again, I don’t see what other use you’d have for it… I’d be happy if you could better detail your use case!

Edit: totally forgot! With node red you can set all those volumes to global variables and invoke them later in a different flow. That way you can do what you want :slight_smile:

Thanks for you feedback… the fading is the fancy thing but from my experience it helps me to avoid to wake up when suddenly the music stops…
The fading also does not start from the beginning …bout from the end just to make a smooth stop rather then a normal stop.
I will check the nodered solution where the graphic interface is more combenient especially for debugging and for the possibility to reuse sub flow to make it easier to repeat stuf define at on place…

I think I found something for that fade effect :slight_smile: try this out:
https://flows.nodered.org/flow/4abee421817eac7335b5633f166295af

Thanks, I did something this morning using a time out block in node red …it works verry well except that the timeout bloc is automatically starting at nodered start… and the time out preset cannot be forced from a dashboard… so I will basically trigger this myself with the flexibility I need but the interface with the Sonos player is working.

This fade library is exactly what I need! Thanks a lot…
I will try it next time I have free time to work on this.
I will generate the volume ramp down using this library from 30, and send the faded volume to Sonos player only when the faded volume is lower than the read volume from the player, like this it ramp always from the effective whatever it’s value.
At the end of the ramp down I stop the player.
The next day, a Sonos alarm will preset the starting volume.
I will give feedback here when it is validated

1 Like

Looking forward to it! :slight_smile:

hello,

i finally suceed using the fade in/out dsm.

here is the nodered code:


[{"id":"07b418b868827c02","type":"openhab2-out2","z":"a9460b5630be12ed","name":"","controller":"10d7ae83.f33b51","itemname":"SonosPlay1Chambre_Volume","topic":"ItemCommand","payload":"","onlywhenchanged":false,"x":1070,"y":795,"wires":[[]]},{"id":"d45d453f378dfd04","type":"inject","z":"a9460b5630be12ed","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"volume","payload":"10","payloadType":"num","x":765,"y":780,"wires":[["07b418b868827c02"]]},{"id":"a846024b2c0b8d6e","type":"inject","z":"a9460b5630be12ed","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"volume","payload":"30","payloadType":"num","x":765,"y":810,"wires":[["07b418b868827c02"]]},{"id":"6820c9c9.829228","type":"inject","z":"a9460b5630be12ed","name":"stop","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"stop","payload":"","payloadType":"str","x":545,"y":765,"wires":[["b3c0022e.f99bc"]]},{"id":"4e43e7f0.d1eee8","type":"debug","z":"a9460b5630be12ed","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1040,"y":720,"wires":[]},{"id":"b3c0022e.f99bc","type":"dsm","z":"a9460b5630be12ed","name":"fade in/out","sm_config":"{\n \"inputTrigger\": \"topic\",\n \"stateOutput\": \"current\",\n \"currentState\": \"stopped\",\n \n \"states\": {\n \"stopped\": {\n \"start\": \"started\",\n \"stop\": \"stopped\"\n },\n \"started\": {\n \"fade_in\": \"fade_in\",\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n },\n \"fade_in\": {\n \"fade_in\": \"fade_in\",\n \"stop\": \"stopped\"\n },\n \"fade_out\": {\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n }\n },\n \"data\": {\n \"initialdelay\": 0,\n \"start\": 0,\n \"end\": 1,\n \"duration\": 3000,\n \"step\": 100,\n \"unit\": \"Milliseconds\",\n \"factor\": 1\n },\n \"methods\": {\n \"init\": [\n \"sm.tick = function(tran, msg) {\",\n \" timeout.id = setTimeout(function() {\",\n \" sm.text = 'fading ' + sm.data.duration + ' ' + sm.data.unit + ' - ' + sm.data.actual;\",\n \" msg.payload = sm.data.actual;\",\n \" node.send(msg);\",\n \" resume(tran, msg);\",\n \" }, sm.data.step * sm.data.factor);\",\n \"};\",\n \"sm.factors = {'milliseconds': 1, 'seconds': 1000, 'minutes': 60000};\",\n \"sta.fill = 'grey';\"\n ],\n \"start\": [\n \"if (typeof msg.payload.initialdelay !== 'undefined') sm.data.initialdelay = msg.payload.initialdelay;\",\n \"if (typeof msg.payload.start !== 'undefined') sm.data.start = msg.payload.start;\",\n \"if (typeof msg.payload.end !== 'undefined') sm.data.end = msg.payload.end;\",\n \"if (typeof msg.payload.duration !== 'undefined') sm.data.duration = msg.payload.duration;\",\n \"if (typeof msg.payload.step !== 'undefined') sm.data.step = msg.payload.step;\",\n \"if (typeof msg.payload.unit !== 'undefined') {\",\n \" if (sm.factors.hasOwnProperty(msg.payload.unit.toLowerCase())) {\",\n \" sm.data.factor = sm.factors[msg.payload.unit.toLowerCase()];\",\n \" sm.data.unit = msg.payload.unit;\",\n \" } else {\",\n \" node.warn('>' + msg.payload.unit + '< unknown, available: Milliseconds, Seconds, Minutes');\",\n \" };\",\n \"} else {\",\n \" sm.data.factor = 1;\",\n \" sm.data.unit = 'Milliseconds';\",\n \"};\",\n \n \"clearTimeout(timeout.id);\",\n \"timeout.id = setTimeout(function() {\",\n \" sm.data.delta = (sm.data.step / sm.data.duration) * Math.abs(sm.data.start - sm.data.end);\",\n \" sm.data.actual = sm.data.start;\",\n \n \" if (sm.data.end > sm.data.start) {\",\n \" sm.text = 'fade_in';\",\n \" resume('fade_in', msg);\",\n \" } else {\",\n \" sm.text = 'fade_out';\",\n \" resume('fade_out', msg);\",\n \" };\",\n \"}, sm.data.initialdelay * sm.data.factor);\",\n \"sm.text = 'initial delay ' + sm.data.initialdelay + ' ' + sm.data.unit;\",\n \"msg.payload = sm.data.start;\",\n \"node.send(msg);\"\n ],\n \"fade_in\": [\n \"if (sm.data.actual < sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual + sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual > sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_in', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n ],\n \"fade_out\": [\n \"if (sm.data.actual > sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual - sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual < sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_out', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n ],\n \"stop\": [\n \"sm.text = sm.currentState;\",\n \"clearTimeout(timeout.id);\"\n ],\n \"onAfterTransition\": \"output = false;\",\n \"status\": {\n \"fill\": {\n \"get\": \"sm.currentState === 'stopped' ? 'grey': 'green';\"\n },\n \"shape\": \"dot\",\n \"text\": {\n \"get\": \"sm.text || sm.currentState;\"\n }\n }\n }\n}","x":760,"y":720,"wires":[["4e43e7f0.d1eee8","07b418b868827c02"]]},{"id":"927d03117eebcb65","type":"status","z":"a9460b5630be12ed","name":"Fade out status","scope":["b3c0022e.f99bc"],"x":125,"y":840,"wires":[["b801eea1cc448398","9f2c464b307ff887","0a78f8501b424507"]]},{"id":"b801eea1cc448398","type":"switch","z":"a9460b5630be12ed","name":"","property":"status.text","propertyType":"msg","rules":[{"t":"eq","v":"stopped","vt":"str"},{"t":"cont","v":"initial","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":415,"y":855,"wires":[["9bea071c123766a0","e2551f68bd2b216e"],["c0ccb9a62bd659e9","c89d571462f439ed"]]},{"id":"9f2c464b307ff887","type":"debug","z":"a9460b5630be12ed","name":"debug 33","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"status.text","targetType":"msg","statusVal":"","statusType":"auto","x":420,"y":810,"wires":[]},{"id":"9bea071c123766a0","type":"change","z":"a9460b5630be12ed","name":"PAUSE","rules":[{"t":"set","p":"payload","pt":"msg","to":"PAUSE","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":870,"wires":[["14cbb1635baceed8"]]},{"id":"14cbb1635baceed8","type":"openhab2-out2","z":"a9460b5630be12ed","name":"","controller":"10d7ae83.f33b51","itemname":"SonosPlay1Chambre_Controledumedia","topic":"ItemCommand","payload":"","onlywhenchanged":false,"x":1045,"y":885,"wires":[[]]},{"id":"f4f4a2fd01f9dc86","type":"function","z":"a9460b5630be12ed","name":"memo Volume init & start sleep timer","func":"flow.set(\"volume_init\", flow.get(\"Son_cuis_volume\"));\n\nvar newmsg = {}\nnewmsg.payload = {\n \"initialdelay\": 60,\n \"start\": 20,\n \"end\": 0,\n \"duration\": 60,\n \"step\": 1,\n \"unit\": \"Seconds\"\n}\nnewmsg.payload.start = flow.get(\"Son_cuis_volume\");\nnewmsg.payload.initialdelay = flow.get(\"Sleep_time\");\nnewmsg.topic = msg.payload;\nreturn newmsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":720,"wires":[["b3c0022e.f99bc"]]},{"id":"a16ec7db5c4a7106","type":"ui_numeric","z":"a9460b5630be12ed","name":"sleep time","label":"Sleep Timer (minutes)","tooltip":"","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"wrap":true,"passthru":true,"topic":"topic","topicType":"msg","format":"{{value}}","min":"1","max":"30","step":1,"className":"","x":175,"y":690,"wires":[["99281219e2eabed5"]]},{"id":"99281219e2eabed5","type":"change","z":"a9460b5630be12ed","name":"","rules":[{"t":"set","p":"Sleep_time","pt":"flow","to":"60*payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":690,"wires":[[]]},{"id":"0a78f8501b424507","type":"ui_text","z":"a9460b5630be12ed","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"name":"","label":"Sleep Fading","format":"{{msg.status.text}}","layout":"row-spread","className":"","x":415,"y":900,"wires":[]},{"id":"5fbf5fa62ea2444a","type":"ui_button","z":"a9460b5630be12ed","name":"","group":"fce3aa005d32999e","order":13,"width":"2","height":"1","passthru":false,"label":"Start Sleep","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"start","payloadType":"str","topic":"topic","topicType":"msg","x":175,"y":720,"wires":[["f4f4a2fd01f9dc86"]]},{"id":"e2551f68bd2b216e","type":"change","z":"a9460b5630be12ed","name":"restore_Volume","rules":[{"t":"set","p":"payload","pt":"msg","to":"volume_init","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":745,"y":840,"wires":[["07b418b868827c02"]]},{"id":"82bad00c0696873c","type":"inject","z":"a9460b5630be12ed","name":"5s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":155,"y":975,"wires":[["8aa695d6db75c7c2"]]},{"id":"c0ccb9a62bd659e9","type":"change","z":"a9460b5630be12ed","name":"","rules":[{"t":"set","p":"Sleep_time_CountDown","pt":"flow","to":"Sleep_time","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":745,"y":930,"wires":[[]]},{"id":"8aa695d6db75c7c2","type":"function","z":"a9460b5630be12ed","name":"CountDown","func":"var cd = flow.get(\"Sleep_time_CountDown\");\nif (cd > 0){\n cd = cd - 5;\nflow.set(\"Sleep_time_CountDown\", cd);\nvar msg ={ \"payload\":cd};\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":975,"wires":[["eaaec7a0f15835a1","0eb0a771b0f8ed95"]]},{"id":"eaaec7a0f15835a1","type":"debug","z":"a9460b5630be12ed","name":"debug 34","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":1005,"wires":[]},{"id":"0eb0a771b0f8ed95","type":"ui_text","z":"a9460b5630be12ed","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"name":"","label":"Sleep time before fading","format":"{{msg.payload}}","layout":"row-spread","className":"","x":730,"y":975,"wires":[]},{"id":"c89d571462f439ed","type":"change","z":"a9460b5630be12ed","name":"PLAY","rules":[{"t":"set","p":"payload","pt":"msg","to":"PLAY","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":900,"wires":[["14cbb1635baceed8"]]},{"id":"10d7ae83.f33b51","type":"openhab2-controller2","name":"openhabian32","protocol":"http","host":"192.168.1.35","port":"8080","path":"","username":"openhabian32","password":"","ohversion":"v3","token":"oh.nodered.LP6Q2uZdoOKwK46iRBqrfuDC7Cmko815gEqlApZYAODX5DDWnr3B2G3JX0OOKAz2SqOkzxG5zfWhzn3cvvi80w"},{"id":"fce3aa005d32999e","type":"ui_group","name":"Sleep","tab":"940e1897.3ad938","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"940e1897.3ad938","type":"ui_tab","name":"Test","icon":"dashboard","disabled":false,"hidden":false}]

and the layout

i have created some interface in nodered dashboard

dsm is a fantastic tool that can be used in a lot of situation, catching the status of the dsm allows to manage additional task based on the running state.

after searching a lot on creating dydnamic intervall , i found a dsm example with interval…

Best regards

1 Like

Great work :slight_smile: once i have some free time at the pc I’ll have to test it out!

After sending my messsage, i discovered that some part was missing in my flow.

To be able to save the actual volume, i need first to save it in a flow context variable each time it is updated

please find the updated flow

Update code with right code box format :


[{"id":"2eda76ef65b1a8e2","type":"openhab2-in2","z":"a9460b5630be12ed","name":"","controller":"10d7ae83.f33b51","itemname":"SonosPlay1Chambre_Volume","topic":"","initialstate":true,"whenupdated":false,"whencommand":false,"whenchanged":true,"changedfrom":"","changedto":"","x":210,"y":150,"wires":[["5131755a15879308","25a3e6abf17b4011"]]},{"id":"5131755a15879308","type":"debug","z":"a9460b5630be12ed","name":"debug 28","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":675,"y":105,"wires":[]},{"id":"07b418b868827c02","type":"openhab2-out2","z":"a9460b5630be12ed","name":"","controller":"10d7ae83.f33b51","itemname":"SonosPlay1Chambre_Volume","topic":"ItemCommand","payload":"","onlywhenchanged":false,"x":1055,"y":390,"wires":[[]]},{"id":"d45d453f378dfd04","type":"inject","z":"a9460b5630be12ed","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"volume","payload":"10","payloadType":"num","x":750,"y":375,"wires":[["07b418b868827c02"]]},{"id":"a846024b2c0b8d6e","type":"inject","z":"a9460b5630be12ed","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"volume","payload":"30","payloadType":"num","x":750,"y":405,"wires":[["07b418b868827c02"]]},{"id":"25a3e6abf17b4011","type":"function","z":"a9460b5630be12ed","name":"set flow Son_cuis_volume","func":"let volume=Number(msg.payload) ;\nflow.set(\"Son_cuis_volume\", volume);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":135,"wires":[[]]},{"id":"6820c9c9.829228","type":"inject","z":"a9460b5630be12ed","name":"stop","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"stop","payload":"","payloadType":"str","x":530,"y":360,"wires":[["b3c0022e.f99bc"]]},{"id":"4e43e7f0.d1eee8","type":"debug","z":"a9460b5630be12ed","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1025,"y":315,"wires":[]},{"id":"b3c0022e.f99bc","type":"dsm","z":"a9460b5630be12ed","name":"fade in/out","sm_config":"{\n \"inputTrigger\": \"topic\",\n \"stateOutput\": \"current\",\n \"currentState\": \"stopped\",\n \n \"states\": {\n \"stopped\": {\n \"start\": \"started\",\n \"stop\": \"stopped\"\n },\n \"started\": {\n \"fade_in\": \"fade_in\",\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n },\n \"fade_in\": {\n \"fade_in\": \"fade_in\",\n \"stop\": \"stopped\"\n },\n \"fade_out\": {\n \"fade_out\": \"fade_out\",\n \"stop\": \"stopped\"\n }\n },\n \"data\": {\n \"initialdelay\": 0,\n \"start\": 0,\n \"end\": 1,\n \"duration\": 3000,\n \"step\": 100,\n \"unit\": \"Milliseconds\",\n \"factor\": 1\n },\n \"methods\": {\n \"init\": [\n \"sm.tick = function(tran, msg) {\",\n \" timeout.id = setTimeout(function() {\",\n \" sm.text = 'fading ' + sm.data.duration + ' ' + sm.data.unit + ' - ' + sm.data.actual;\",\n \" msg.payload = sm.data.actual;\",\n \" node.send(msg);\",\n \" resume(tran, msg);\",\n \" }, sm.data.step * sm.data.factor);\",\n \"};\",\n \"sm.factors = {'milliseconds': 1, 'seconds': 1000, 'minutes': 60000};\",\n \"sta.fill = 'grey';\"\n ],\n \"start\": [\n \"if (typeof msg.payload.initialdelay !== 'undefined') sm.data.initialdelay = msg.payload.initialdelay;\",\n \"if (typeof msg.payload.start !== 'undefined') sm.data.start = msg.payload.start;\",\n \"if (typeof msg.payload.end !== 'undefined') sm.data.end = msg.payload.end;\",\n \"if (typeof msg.payload.duration !== 'undefined') sm.data.duration = msg.payload.duration;\",\n \"if (typeof msg.payload.step !== 'undefined') sm.data.step = msg.payload.step;\",\n \"if (typeof msg.payload.unit !== 'undefined') {\",\n \" if (sm.factors.hasOwnProperty(msg.payload.unit.toLowerCase())) {\",\n \" sm.data.factor = sm.factors[msg.payload.unit.toLowerCase()];\",\n \" sm.data.unit = msg.payload.unit;\",\n \" } else {\",\n \" node.warn('>' + msg.payload.unit + '< unknown, available: Milliseconds, Seconds, Minutes');\",\n \" };\",\n \"} else {\",\n \" sm.data.factor = 1;\",\n \" sm.data.unit = 'Milliseconds';\",\n \"};\",\n \n \"clearTimeout(timeout.id);\",\n \"timeout.id = setTimeout(function() {\",\n \" sm.data.delta = (sm.data.step / sm.data.duration) * Math.abs(sm.data.start - sm.data.end);\",\n \" sm.data.actual = sm.data.start;\",\n \n \" if (sm.data.end > sm.data.start) {\",\n \" sm.text = 'fade_in';\",\n \" resume('fade_in', msg);\",\n \" } else {\",\n \" sm.text = 'fade_out';\",\n \" resume('fade_out', msg);\",\n \" };\",\n \"}, sm.data.initialdelay * sm.data.factor);\",\n \"sm.text = 'initial delay ' + sm.data.initialdelay + ' ' + sm.data.unit;\",\n \"msg.payload = sm.data.start;\",\n \"node.send(msg);\"\n ],\n \"fade_in\": [\n \"if (sm.data.actual < sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual + sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual > sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_in', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n ],\n \"fade_out\": [\n \"if (sm.data.actual > sm.data.end) {\",\n \" sm.data.actual = Math.round((sm.data.actual - sm.data.delta) * 100) / 100;\",\n \" if (sm.data.actual < sm.data.end) {sm.data.actual = sm.data.end;};\",\n \" sm.tick('fade_out', msg);\",\n \"} else {\",\n \" resume('stop', msg);\",\n \"};\"\n ],\n \"stop\": [\n \"sm.text = sm.currentState;\",\n \"clearTimeout(timeout.id);\"\n ],\n \"onAfterTransition\": \"output = false;\",\n \"status\": {\n \"fill\": {\n \"get\": \"sm.currentState === 'stopped' ? 'grey': 'green';\"\n },\n \"shape\": \"dot\",\n \"text\": {\n \"get\": \"sm.text || sm.currentState;\"\n }\n }\n }\n}","x":745,"y":315,"wires":[["4e43e7f0.d1eee8","07b418b868827c02"]]},{"id":"927d03117eebcb65","type":"status","z":"a9460b5630be12ed","name":"Fade out status","scope":["b3c0022e.f99bc"],"x":110,"y":435,"wires":[["b801eea1cc448398","9f2c464b307ff887","0a78f8501b424507"]]},{"id":"b801eea1cc448398","type":"switch","z":"a9460b5630be12ed","name":"","property":"status.text","propertyType":"msg","rules":[{"t":"eq","v":"stopped","vt":"str"},{"t":"cont","v":"initial","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":400,"y":450,"wires":[["9bea071c123766a0","e2551f68bd2b216e"],["c0ccb9a62bd659e9","c89d571462f439ed"]]},{"id":"9f2c464b307ff887","type":"debug","z":"a9460b5630be12ed","name":"debug 33","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"status.text","targetType":"msg","statusVal":"","statusType":"auto","x":405,"y":405,"wires":[]},{"id":"9bea071c123766a0","type":"change","z":"a9460b5630be12ed","name":"PAUSE","rules":[{"t":"set","p":"payload","pt":"msg","to":"PAUSE","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":705,"y":465,"wires":[["14cbb1635baceed8"]]},{"id":"14cbb1635baceed8","type":"openhab2-out2","z":"a9460b5630be12ed","name":"","controller":"10d7ae83.f33b51","itemname":"SonosPlay1Chambre_Controledumedia","topic":"ItemCommand","payload":"","onlywhenchanged":false,"x":1030,"y":480,"wires":[[]]},{"id":"f4f4a2fd01f9dc86","type":"function","z":"a9460b5630be12ed","name":"memo Volume init & start sleep timer","func":"flow.set(\"volume_init\", flow.get(\"Son_cuis_volume\"));\n\nvar newmsg = {}\nnewmsg.payload = {\n \"initialdelay\": 60,\n \"start\": 20,\n \"end\": 0,\n \"duration\": 60,\n \"step\": 1,\n \"unit\": \"Seconds\"\n}\nnewmsg.payload.start = flow.get(\"Son_cuis_volume\");\nnewmsg.payload.initialdelay = flow.get(\"Sleep_time\");\nnewmsg.topic = msg.payload;\nreturn newmsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":435,"y":315,"wires":[["b3c0022e.f99bc"]]},{"id":"a16ec7db5c4a7106","type":"ui_numeric","z":"a9460b5630be12ed","name":"sleep time","label":"Sleep Timer (minutes)","tooltip":"","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"wrap":true,"passthru":true,"topic":"topic","topicType":"msg","format":"{{value}}","min":"1","max":"30","step":1,"className":"","x":160,"y":285,"wires":[["99281219e2eabed5"]]},{"id":"99281219e2eabed5","type":"change","z":"a9460b5630be12ed","name":"","rules":[{"t":"set","p":"Sleep_time","pt":"flow","to":"60*payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":375,"y":285,"wires":[[]]},{"id":"0a78f8501b424507","type":"ui_text","z":"a9460b5630be12ed","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"name":"","label":"Sleep Fading","format":"{{msg.status.text}}","layout":"row-spread","className":"","x":400,"y":495,"wires":[]},{"id":"5fbf5fa62ea2444a","type":"ui_button","z":"a9460b5630be12ed","name":"","group":"fce3aa005d32999e","order":13,"width":"2","height":"1","passthru":false,"label":"Start Sleep","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"start","payloadType":"str","topic":"topic","topicType":"msg","x":160,"y":315,"wires":[["f4f4a2fd01f9dc86"]]},{"id":"e2551f68bd2b216e","type":"change","z":"a9460b5630be12ed","name":"restore_Volume","rules":[{"t":"set","p":"payload","pt":"msg","to":"volume_init","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":435,"wires":[["07b418b868827c02"]]},{"id":"82bad00c0696873c","type":"inject","z":"a9460b5630be12ed","name":"5s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":570,"wires":[["8aa695d6db75c7c2"]]},{"id":"c0ccb9a62bd659e9","type":"change","z":"a9460b5630be12ed","name":"","rules":[{"t":"set","p":"Sleep_time_CountDown","pt":"flow","to":"Sleep_time","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":525,"wires":[[]]},{"id":"8aa695d6db75c7c2","type":"function","z":"a9460b5630be12ed","name":"CountDown","func":"var cd = flow.get(\"Sleep_time_CountDown\");\nif (cd > 0){\n cd = cd - 5;\nflow.set(\"Sleep_time_CountDown\", cd);\nvar msg ={ \"payload\":cd};\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":415,"y":570,"wires":[["eaaec7a0f15835a1","0eb0a771b0f8ed95"]]},{"id":"eaaec7a0f15835a1","type":"debug","z":"a9460b5630be12ed","name":"debug 34","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":675,"y":600,"wires":[]},{"id":"0eb0a771b0f8ed95","type":"ui_text","z":"a9460b5630be12ed","group":"fce3aa005d32999e","order":1,"width":0,"height":0,"name":"","label":"Sleep time before fading","format":"{{msg.payload}}","layout":"row-spread","className":"","x":715,"y":570,"wires":[]},{"id":"c89d571462f439ed","type":"change","z":"a9460b5630be12ed","name":"PLAY","rules":[{"t":"set","p":"payload","pt":"msg","to":"PLAY","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":695,"y":495,"wires":[["14cbb1635baceed8"]]},{"id":"faf5972c03f5c083","type":"comment","z":"a9460b5630be12ed","name":"gestion du sleep mode sur sonos chambre","info":"","x":395,"y":210,"wires":[]},{"id":"10d7ae83.f33b51","type":"openhab2-controller2","name":"openhabian32","protocol":"http","host":"192.168.1.35","port":"8080","path":"","username":"openhabian32","password":"","ohversion":"v3","token":"oh.nodered.LP6Q2uZdoOKwK46iRBqrfuDC7Cmko815gEqlApZYAODX5DDWnr3B2G3JX0OOKAz2SqOkzxG5zfWhzn3cvvi80w"},{"id":"fce3aa005d32999e","type":"ui_group","name":"Sleep","tab":"940e1897.3ad938","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"940e1897.3ad938","type":"ui_tab","name":"Test","icon":"dashboard","disabled":false,"hidden":false}]

1 Like

This time the code was properly formatted in a code box…
yesterday I forgot the CR before the code triple tick…

1 Like

Hello,
I created the nodered rule and validated it using my sone play1 running in the kitchen because it is close to the office where my desktop computer is located … then I just replaced all the Openhab link node to do the same on the play1 of the bedroom.
I test it this week from the bedroom but it did not work because the Openhab thing related to my bedroom seems to be not really link to the play1 sitting in my bedroom.
When I change something on the player from the Openhab dashboard, nothing change on the real play1…
So I need probably to reset somehow the Openhab configuration of the thing…
The status of the thing is Online and the IP address is right… how is it possible?

Pierre RUWET