Hi alltogether,
Most of the time I only read some topics to get help, I am not a really experienced programmer but learned to set up Openhab - learning by doing. Now it is running smoothly since 1.5 years with several components: Echo, Sonos, Shelly, Hue, Xiaomi. All managed through an Raspberry with OH and a Conbee stick. I do love that system and my wife got used to it
Enough introduction. I posted my latest project in the German Facebook group yesterday and got asked to post more details about it - here we go.
The task: 2 kids each with a Sonos in his room who want to listen to radio dramas (Hoerspiel in German) in the evening, sometimes kids music during the day. They donât have mobile phones, yet, I didnât want to change the different episodes several times in the evening and wanted to give them the possiblity to select and change it on their own. Provider Amazon Music.
How I did it:
I re-activated my MQTT Broker in Openhab (had it before for Shelly but those are switched to the binding now), the MQTT Broker got a âGeneric MQTT Thingâ with two channels, one for each of the kids, those channels are set up as âNumberâ.
I used two Raspberries, each one connected to a USB-RFID reader from Aliexpress (EM4100, TK4100). Each kid got until now five 125 khz RFID chips.
I placed one Raspberry in each kids room and wrote a small Python script (nano rfid.py):
#!/usr/bin/env python 3
from evdev import InputDevice
from select import select
import paho.mqtt.publish as publish
MQTT_SERVER = âIP of the Brokerâ
MQTT_PATH = âThe MQTT state topic where the data is being sent toâ
rfid_presented = ââ
keys = âX^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXXâ
dev = InputDevice(â/dev/input/event0â)
while True:
r,w,x = select([dev], [], [])
for event in dev.read():
if event.type==1 and event.value==1:
if event.code==28:
print(rfid_presented)
publish.single(MQTT_PATH, rfid_presented, hostname=MQTT_SERVER)
rfid_presented = â1â
publish.single(MQTT_PATH, rfid_presented, hostname=MQTT_SERVER)
rfid_presented = ââ
else:
rfid_presented += keys[ event.code ]
I combined that code from different sources in the web as I was not really experienced with python. You might need to change the event ID, you can see it on your Raspberry by
ls -lah /dev/input/by-id
Take care: In case you plug or unplug other sources like keyboards, mouse etc. on the Raspberry, the event number changes. So I had the Raspberry on remote only and accessed it via Putty while only the RFID reader was on its USB-ports. I never changed that system afterwards and it works like a charm now since some days.
I also set the script in the autostart:
sudo nano /etc/rc.local
before the âexit 0â I added the path:
python /home/pi/rfid.py &
As it runs in a loop, I closed it with the â&â.
I also had to install MQTT on each of the Raspis:
sudo apt-get install -y mosquitto mosquitto-clients
And to use it from scripts, Paho:
sudo pip install paho-mqtt
That was it on the Raspiâs. Then back to Openhab.
If everything is set up like this, the numbers of the chips are being sent to the MQTT channel now. I added two items:
Number RFID_Receiver_Number_1 âRFID Receiver Numberâ {channel=âmqttchannel1â}
The items for the different playlists:
Switch rfid_kid1_pl_1 âPlaylist Kid 1, 1â
Then the rules for assigning the RFID-code to the rule as an example:
var Timer Kid1Timer1 = null
rule âkid 1, pl1â
when
Item RFID_Receiver_Number_1 changed to âNUMBEROFTHECHIPâ
then
rfid_kid1_pl1.sendCommand(ON)
end
And the final execution:
rule âKid 1 Playlist 1â
when
Item rfid_kid1_pl1 received command ON
then
if (rfid_funktion_kid1.state==ON) {
sw_sonos_kid1_clearq.sendCommand(ON)
sw_sonos_kid1_standalone.sendCommand(ON)
rfid_kid1_pl1.sendCommand(OFF)
if (time_2023.state==ON) {
licht_kind_dunkel.sendCommand(ON)
}
if (time_1904.state==ON) { //Einschlafmusik
sw_sonos_kid1_shuffle.sendCommand(ON) //ATTENTION: Shuffle ON as this is music!
Kid1Timer1 = createTimer(now.plusSeconds(5), [|
sendCommand(str_sonos_kid1_playlist, âa11â)
sendCommand(SONOS1_Kid1_C, PLAY)
])
}
else if (time_1904.state==OFF) {
sw_sonos_kid1_shuffle.sendCommand(ON) //ATTENTION: Shuffle ON as this is music!
Kid1Timer1 = createTimer(now.plusSeconds(5), [|
sendCommand(str_sonos_kid1_playlist, âa1â)
sendCommand(SONOS1_Kid1_C, PLAY)
])
}
if (time_1908.state==ON) {
dim_sonos_kid1_volume.sendCommand(10)
}
else if (time_1908.state==OFF) {
dim_sonos_kid1_volume.sendCommand(30)
}
}
end
So there are some additional functions in:
- It dims the light (licht_kind_dunkel) between 20-23 pm once an RFID is presented.
- It clears any previous songs in the playlist of the sonos player (CLEARQ-item).
- It removes the Sonos player from any groups (STANDALONE-item).
- It switches the Shuffle on (SHUFFLE-item) - this will be switched to off for the radio-dramas.
- It starts 5 seconds after activation as each kid can also use its chips on the reader of the other kid - using a different playlist.
- It uses different playlist at different times, e.g. music to sleep in the evening, kids-party-music during the day, other radio-dramas during the day than in the eveningâŠ
- It uses a different volume in the evening than during the day.
The playlists are the defined playlists in the Sonos Controller, so those are easy to change.
Finally: I tried to describe it here really step-by-step as I did it. Sorry, if this is too much detail, but I am as I wrote also not experienced and wanted to make it as easy as possible for everyone. It is my first try for an explanation for others, normally I am the one who learns.
Thanks to everyone who already helped me!
Would be happy for some feedback both positive and negative.
Have a nice Sunday!
Best regards,
Christoph