Frontier-Silicon based internet radio controlled by Node-RED

Hi!

I have a Silvercrest SIRD 14 B1 internet radio from the german discounter Lidl for 5 years now.
I knew, there must be an API, since there a several third party apps to control it like Technisat Connect or UNDOK (both for Android).
But quite recently I found a documentation for this device and many other Frontier-Silicon based radio devices here:

I did not find any Node-RED node or flow for these devices, so I started with some testing:

default Pin is 1234, however it can be changed in the system settings of the device.

default port is 80, but some devices use port 2244.

see also https://sourceforge.net/projects/fs-remote/ with many more informations, like:

Compatibility:
Internet Radio devices based on the Frontier Silicon technology such as some from the following manufacturers: Hama, Medion, Technisat, Dual, Sangean, Roberts, Revo, Ruark, Silvercrest, Auna, Como Audio. Pinell devices require specific port: "IP:2244".

You can get some more information about your device:

http://ip-address:8080/dd.xml

http://ip-address:port/device

http://ip-address:port:8080/icon2.png
http://ip-address:port:8080/icon.png

The following commands return a XML-based string, which you can easily convert with the XML-node.

Returns the max volume level:
http://ip-address:port/fsapi/GET/netRemote.sys.caps.volumeSteps?pin=1234
(so you can adapt the max value on your volume slider)

Sets / Returns the volume of the device:

http://ip-address:port/fsapi/GET/netRemote.sys.audio.volume?pin=1234
http://ip-address:port/fsapi/SET/netRemote.sys.audio.volume?pin=1234&value=xx

Gets / sets the power state of the radio:

http://ip-address:port/fsapi/GET/netRemote.sys.power?pin=1234
http://ip-address:port/fsapi/SET/netRemote.sys.power?pin=1234&value=0/1

friendly name of the device:
http://ip-address:port/fsapi/GET/netRemote.sys.info.friendlyName?pin=1234

Sets / Returns the Time till Sleep in seconds (minutes?) (0 = No Sleep) [works with Firmware V2.9.10 but not with V2.6.17]
http://ip-address:port/fsapi/GET/netRemote.sys.sleep?pin=1234
http://ip-address:port/fsapi/SET/netRemote.sys.sleep?pin=1234&value=40

gets / sets the mute state:

http://ip-address:port/fsapi/GET/netRemote.sys.audio.mute?pin=1234
http://ip-address:port/fsapi/SET/netRemote.sys.audio.mute?pin=1234&value=1

Returns the name of the artist of the current song
http://ip-address:port/fsapi/GET/netRemote.play.info.artist?pin=1234

Returns the first line of the display
http://ip-address:port/fsapi/GET/netRemote.play.info.name?pin=1234

Returns the second line of the display
http://ip-address:port/fsapi/GET/netRemote.play.info.text?pin=1234

For some of the advanced commands you need a session ID, which is generated with this command:

http://ip-address:port/fsapi/CREATE_SESSION?pin=1234 (or whatever pin you have set)

After that, you add the session ID from the http result with &sid=xxxxxx to your requests.
There is only one valid session ID at a time, so if you control your radio from two different devices, you will have to create new session IDs.
You can grab the return values from your http requests, to see if the sid ist still valid.

BTW: Last week I bought another Internet radio: Hama IR350M which is also Frontier Silicon based and works also with the above commands.

See my first flow on the next post!

This is my flow:

[{"id":"51a37033.59be38","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"ad90d084.72f808","type":"inject","z":"51a37033.59be38","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"0.5","topic":"","payload":"","payloadType":"date","x":110,"y":60,"wires":[["c57f91a9.4f0c08"]]},{"id":"c57f91a9.4f0c08","type":"function","z":"51a37033.59be38","name":"Configuration","func":"\nglobal.set (\"radioURL\",\"http://192.168.xx.xx:80\");\nglobal.set (\"radioPIN\",\"1234\");\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":300,"y":60,"wires":[["3e9d5a38.263d06"]]},{"id":"b4dc8d72.825e2","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":1150,"y":220,"wires":[["63e0b9fa.096d2"]]},{"id":"5c4c2146.e139e","type":"ui_switch","z":"51a37033.59be38","name":"Power","label":"","tooltip":"","group":"dead3030.39e6a8","order":1,"width":1,"height":1,"passthru":false,"decouple":"true","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-power-off fa-2x","oncolor":"orange","offvalue":"false","offvalueType":"bool","officon":"fa-power-off fa-2x","offcolor":"grey","x":810,"y":220,"wires":[["843f4275.2702b8"]]},{"id":"9fcfe351.aacb68","type":"ui_slider","z":"51a37033.59be38","name":"","label":"Volume","tooltip":"","group":"dead3030.39e6a8","order":6,"width":6,"height":1,"passthru":true,"outs":"end","topic":"","min":0,"max":"20","step":1,"x":520,"y":440,"wires":[["27434787.975e28"]]},{"id":"da61d256.ba6de","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":670,"y":140,"wires":[["db258698.173d6"]]},{"id":"63e0b9fa.096d2","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\nvar radioSID = global.get(\"radioSID\");\n\nvar  command = \"GET/netRemote.sys.power\";\n\nmsg.url = radioURL+\"/fsapi/\"+command+\"?pin=\"+radioPIN+\"&sid=\"+radioSID\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":140,"wires":[["da61d256.ba6de"]]},{"id":"843f4275.2702b8","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\nvar radioSID = global.get(\"radioSID\");\n\nvar  command = \"SET/netRemote.sys.power\";\n\nmsg.url = radioURL+\"/fsapi/\"+command+\"?pin=\"+radioPIN+\"&sid=\"+radioSID\n\nif (msg.payload)\n {msg.url+=\"&value=1\"}\n else\n {msg.url+=\"&value=0\"}\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":980,"y":220,"wires":[["b4dc8d72.825e2"]]},{"id":"db258698.173d6","type":"switch","z":"51a37033.59be38","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":850,"y":140,"wires":[["7e7e73b4.8f3134"],[]]},{"id":"7e7e73b4.8f3134","type":"xml","z":"51a37033.59be38","name":"","property":"payload","attr":"","chr":"","x":1010,"y":140,"wires":[["be845f9f.de83b"]]},{"id":"be845f9f.de83b","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.fsapiResponse.value[0].u8[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1180,"y":140,"wires":[["1cde2de8.d96da2"]]},{"id":"1cde2de8.d96da2","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"num","to":"true","tot":"bool"},{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"num","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":220,"wires":[["5c4c2146.e139e"]]},{"id":"e74e5e94.543b6","type":"inject","z":"51a37033.59be38","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"8","crontab":"","once":true,"onceDelay":"3","topic":"","payload":"","payloadType":"date","x":130,"y":380,"wires":[["63e0b9fa.096d2","99ed2300.49c45","b1a2448c.654c78","c5f9c9ed.58868"]]},{"id":"99ed2300.49c45","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\n\n\nmsg.url = radioURL+\"/fsapi/GET/netRemote.sys.audio.volume?pin=\"+radioPIN\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":360,"wires":[["ffdc100a.566b38"]]},{"id":"ffdc100a.566b38","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":550,"y":360,"wires":[["e60b5d1b.03b0e"]]},{"id":"e60b5d1b.03b0e","type":"switch","z":"51a37033.59be38","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":770,"y":360,"wires":[["a5442384.b772a"],[]]},{"id":"a5442384.b772a","type":"xml","z":"51a37033.59be38","name":"","property":"payload","attr":"","chr":"","x":930,"y":340,"wires":[["8130c612.abcfd","1c980680.a5cc02"]]},{"id":"8130c612.abcfd","type":"debug","z":"51a37033.59be38","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1170,"y":320,"wires":[]},{"id":"1c980680.a5cc02","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.fsapiResponse.value[0].u8[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1130,"y":380,"wires":[["9fcfe351.aacb68"]]},{"id":"dd97cc69.10a32","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":910,"y":440,"wires":[["7edeb9a6.1f28b8"]]},{"id":"27434787.975e28","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\n\n\nmsg.url = radioURL+\"/fsapi/SET/netRemote.sys.audio.volume?pin=\"+radioPIN+\"&value=\"+msg.payload\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":440,"wires":[["dd97cc69.10a32"]]},{"id":"7edeb9a6.1f28b8","type":"debug","z":"51a37033.59be38","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1130,"y":440,"wires":[]},{"id":"b1a2448c.654c78","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\n\nmsg.url = radioURL+\"/fsapi/GET/netRemote.play.info.name?pin=\"+radioPIN\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":520,"wires":[["6dd72642.f2e4d"]]},{"id":"6dd72642.f2e4d","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":530,"y":520,"wires":[["f932de53.50f4"]]},{"id":"f932de53.50f4","type":"switch","z":"51a37033.59be38","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":690,"y":520,"wires":[["aa47abb9.ad68"],[]]},{"id":"aa47abb9.ad68","type":"xml","z":"51a37033.59be38","name":"","property":"payload","attr":"","chr":"","x":850,"y":520,"wires":[["30be545e.61e814"]]},{"id":"1d64e0ad.f75fb7","type":"ui_text","z":"51a37033.59be38","group":"dead3030.39e6a8","order":2,"width":5,"height":1,"name":"","label":"station:","format":"{{msg.payload}}","layout":"row-left","x":1260,"y":520,"wires":[]},{"id":"c5f9c9ed.58868","type":"function","z":"51a37033.59be38","name":"","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\n\nmsg.url = radioURL+\"/fsapi/GET/netRemote.play.info.text?pin=\"+radioPIN\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":560,"wires":[["241a7cdc.951784"]]},{"id":"241a7cdc.951784","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":530,"y":560,"wires":[["3553127a.976a9e"]]},{"id":"3553127a.976a9e","type":"switch","z":"51a37033.59be38","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":690,"y":560,"wires":[["41419f74.ce1d4"],[]]},{"id":"41419f74.ce1d4","type":"xml","z":"51a37033.59be38","name":"","property":"payload","attr":"","chr":"","x":850,"y":560,"wires":[["9957b5b2.1459e"]]},{"id":"30be545e.61e814","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.fsapiResponse.value[0].c8_array[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1040,"y":520,"wires":[["1d64e0ad.f75fb7"]]},{"id":"7a7609ce.75c51","type":"ui_text","z":"51a37033.59be38","group":"dead3030.39e6a8","order":4,"width":7,"height":1,"name":"","label":"Info:","format":"{{msg.payload}}","layout":"row-left","x":1250,"y":560,"wires":[]},{"id":"9957b5b2.1459e","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.fsapiResponse.value[0].c8_array[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1040,"y":560,"wires":[["7a7609ce.75c51"]]},{"id":"3e9d5a38.263d06","type":"function","z":"51a37033.59be38","name":"Get SID","func":"var radioURL = global.get(\"radioURL\");\nvar radioPIN = global.get(\"radioPIN\");\n\nmsg.url = radioURL+\"/fsapi/CREATE_SESSION?pin=\"+radioPIN\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":480,"y":60,"wires":[["e2aa2b03.62f61"]]},{"id":"e2aa2b03.62f61","type":"http request","z":"51a37033.59be38","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":650,"y":60,"wires":[["411cd8e6.fa3dd"]]},{"id":"411cd8e6.fa3dd","type":"switch","z":"51a37033.59be38","name":"","property":"statusCode","propertyType":"msg","rules":[{"t":"eq","v":"200","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":830,"y":60,"wires":[["dd53b551.650c98"],[]]},{"id":"dd53b551.650c98","type":"xml","z":"51a37033.59be38","name":"","property":"payload","attr":"","chr":"","x":990,"y":60,"wires":[["69a1ba58.ab6be4"]]},{"id":"69a1ba58.ab6be4","type":"change","z":"51a37033.59be38","name":"","rules":[{"t":"set","p":"radioSID","pt":"global","to":"payload.fsapiResponse.sessionId[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1150,"y":60,"wires":[["fa3d7ae3.440798"]]},{"id":"fa3d7ae3.440798","type":"debug","z":"51a37033.59be38","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1310,"y":60,"wires":[]},{"id":"8399c0dd.6c93f","type":"ui_switch","z":"51a37033.59be38","name":"Mute","label":"switch","tooltip":"","group":"dead3030.39e6a8","order":5,"width":1,"height":1,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"volume_off","oncolor":"orange","offvalue":"false","offvalueType":"bool","officon":"volume_off","offcolor":"grey","x":550,"y":660,"wires":[[]]},{"id":"9e0f38c8.696b6","type":"comment","z":"51a37033.59be38","name":"no function yet","info":"","x":390,"y":660,"wires":[]},{"id":"dead3030.39e6a8","type":"ui_group","z":"","name":"Default","tab":"f6d18da4.d4c758","order":1,"disp":true,"width":7,"collapse":false},{"id":"f6d18da4.d4c758","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

The mute button does not work yet.
In the function node "configuration" you have to enter the data of your radio device:

global.set ("radioURL","http://192.168.xx.xx:80");
global.set ("radioPIN","1234");

I do not yet check all errors and do not control, whether there is another app, that controls the radio. (see "session ID" in the first post)

I have to read the max volume level and push that to the slider for the max value. One of my radios has a max level of 20, the other 32, so that is important to implement.

I have to test, how to get the preset stations, so that I can easily switch between them via dashboard.

After all this thoughts a new Node-RED frontier-silicon-node with an own configuration node seems to be a good thing, but I do not know, how to build a node.

1 Like