Just to get a quick overview over the FHEM user interface, I am going to install inside Raspbian on a Raspberry Pi 2 - if you are using a different operating system, please take a look at the installation guide.
FHEM Installation
- Download the current fhem-X.Y.zip container (currently fhem-5.9.zip).
- Create a new folder for FHEM. For this article the folder
E:\fhem-5.9
was created. - Extract the entire content of the folder from the .zip container to
E:\fhem-5.9
.
Perl Installation
- Download a current Strawberry Perl Portable Edition and extract it in the FHEM folder.
- In this case, the content of the package strawberry-perl-5.28.1.1-64bit-portable.zip was extracted to
E:\fhem-5.9
.
Setup FHEM
Open a command prompt (cmd), change to the previously created folder, and start FHEM:
E:
cd fhem-5.9
perl\bin\perl fhem.pl fhem.cfg
Now a Windows security alert appears that Windows Firewall is blocking the Perl interpreter. To access FHEM, you must set up a firewall exception. For this purpose, the security note must be terminated with the button Allow Access.
Note: There is no visible output and the command won't terminate. The command prompt cannot be closed as long as FHEM is running.
Start a browser (Firefox, Chrome and Safari are recommended) and open:
http://localhost:8083/fhem
In the command input field of FHEM, this is the white, rectangular text input field to the right of the FHEM logo. Type update
and then press Enter.
At the end of the update process, FHEM prompts for a "shutdown restart". Please ignore this and type in the command input field only shutdown
followed by Enter to exit FHEM. Now return to the command prompt window. Restart the updated FHEM perl\bin\perl fhem.pl fhem.cfg
.
Now - before we continue - we should first activate the basic authentication for the web user interface. For that please click on the category Unsorted in the side menu on the left and then choose WEB:
From the Attributes channel choose the basicAuth
:
The authentication has to be given base64
encoded. On Linux you can use your terminal with the following command (let's say you want the user to be admin and the password to be instar):
echo -n admin:instar | base64
You can alternatively use an Online Encoder or simply use the terminal from your Chrome Browser and a little bit of Javascript:
$('input').value = window.btoa("admin:instar");
Confirm the input and login with your new Administrator login:
And don't forget to save your changes:
MQTT Broker
If you are following along on a Raspberry Pi don't forget to install the necessary Perl modules first (not necessary when you are on Windows):
sudo apt-get install libmodule-pluggable-perl
sudo cpan install Net::MQTT:Simple
sudo cpan install Net::MQTT:Constants
All INSTAR Full HD cameras offer a Mosquitto MQTT broker that can be used to integrate your camera into 3rd party systems like FHEM. If your camera does not offer an MQTT service, please refer to our documentation on how to install Mosquitto on an Raspberry Pi or a generic Debian computer or use the MQTT2_Server Module that is integrated in FHEM.
In our case we are using an INSTAR IN-8015 FHD camera with the newest firmware + MQTT broker installed.
To add the Broker to FHEM we need to to define it with the following command:
define <name> MQTT <host>:<port>
In the command we told FHEM to register on the MQTT service by adding our cameras IP address 192.168.2.116
as well as the default MQTT port 1883
:
define INSTAR_MQTT_SERVER MQTT 192.168.2.116:1883
We can now use MQTT.fx to test the server connection - optional. By typing the following command into the FHEM command line:
set INSTAR_MQTT_SERVER publish mqtt/test/topic {"val":"1"}
We should be able to see the message in MQTT.fx with a wildcard subscription #
for all messages that are handled by our MQTT broker:
Add Devices
Now we can add our camera as a MQTT_DEVICE - Note: that the camera now has both the MQTT Broker and the MQTT Client installed and acts as both accordingly.
Adding a Test Device
Let's add a MQTT device to FHEM that will be using our MQTT Broker with the following command define <name> MQTT_DEVICE
:
define Alarm MQTT_DEVICE
To assign the device to our MQTT broker we have to set the IODev Attribute
to the name that we choose for the Broker device - in this case INSTARMQTTSERVER:
attr Alarm IODev INSTAR_MQTT_SERVER
To subscribe the MQTT client inside FHEM to a specific MQTT topic, we now need to add a corresponding attribute to our configuration. Our camera will trigger an alarm event when it receives the following MQTT topic with a message payload of {"val":"1"}
: 10D1DC2131A8:alarm/pushalarm
(we prefix the MQTT topic alarm/pushalarm with the MAC address of our camera - to be able to target a specific device):
attr Alarm subscribeReading_Alarm 10D1DC2131A8:alarm/pushalarm
Optional: We can now use MQTT.fx to test the subscription - by publishing a message 10D1DC2131A8:alarm/pushalarm
we can now see that the transmission-state switches from subscription acknowledged
to incoming publish received
:
We are now able to receive a reading every time our camera's alarm is triggered by MQTT.
Go to Position
But it would be a lot more interesting if we were able to publish messages on MQTT to control our camera through the FHEM interface.
We can first start with adding a MQTT device to FHEM with the following command define GoToPos MQTT_DEVICE
.
I choose to do a Go-to-Position device that should send commands to our camera to move to one of the stored pan&tilt positions. We have to use the publishSet attribute to define what options we need to interact with the device inside the FHEM web user interface. In this case we need to add 8 elements to navigate between each stored position:
Please read update below
1 2 3 4 5 6 7 8 10D1DC2131A8:features/ptz/preset
Where 10D1DC2131A8:features/ptz/preset
is the MQTT topic we need to publish our message to and {"val":"0"}
- {"val":"7"}
represent the message payload that has to be send to let the camera move to position 1-8.
The corresponding webCommand (MQTT Message Payload) is defined with a colon separated list - which causes a little bit of a problem here since our server requires a JSON formated payload. If there is a way to create a list like {val:0}:{val:1}:{val:2}:{val:3}:{val:4}:{val:5}:{val:6}:{val:7}
, please let me know - Contact Us.
For now I will take a detour through Node-RED to receive the MQTT message from FHEM and then translate it's payload to the JSON form that the camera needs. For this I will delete the publishSet definition we made ealier and create a new one with a new MQTT topic:
1 2 3 4 5 6 7 8 10D1DC2131A8:nodered/features/ptz/preset
We can now set the webCommand to a straight list of numbers and then later use Node-RED to translate the nodered/features/ptz/preset
topic to a features/ptz/preset
topic that will carry the JSON payload - sounds complicated but will make sense once you see the Node-RED flow below:
0:1:2:3:4:5:6:7
Don't forget to hit Save config to save the changes we made:
Our GoToPos device now has 8 buttons assigned, labeled from 1-8. Clicking on each of them will update the state of our device accordingly and publish it's payload under the nodered/features/ptz/preset
topic:
Node-RED
We already installed Node-RED on Window in an earlier tutorial (follow this link for the Installation on a Raspberry Pi) and now want to use this installation to catch our malformated messages, transform and forward them to our camera's MQTT client.
Start by dragging a MQTT Node into the workspace:
Double-click the MQTT Node and click to add the MQTT server:
Here we can give our server a name and type in it's IP address and port. Note that the MQTT server on your INSTAR Full HD camera can be accessed unencrypted via the port 1883
. If you choose the port 8883
you also have to upload the server certificate in the TLS Configuration section! The username and password for your server can be added on the Security Tab:
Now click on Update to confirm your Server settings and add the MQTT Topic 10D1DC2131A8:nodered/features/ptz/preset
to the Node Properties Tab:
You can test your set-up by attaching an Debug node to the MQTT node and using the Buttons inside your FHEM interface. You should now receive MQTT message from the MQTT node:
We can now remove the Debug node, replace it with a Switch node that switches based on the Message Payload (0-7) and a Change node that transforms the payload to an JSON Object, e.g. if we receive the payload 1
from FHEM, we want the payload to change to {"val":"1"}
. We finish the sequence with an MQTT exit node that re-publishes the message to 10D1DC2131A8:features/ptz/preset
to be received by our camera.
This Solution is a bit verbose and would be much more elegant if the transformation was handled by FHEM directly. But it is doing the trick for now - if you are a FHEM expert and know how to solve this please Contact Us.
Every time you click on a button inside the FHEM UI the Node-RED Version of the message is published. Node-RED then transforms it into a message that our camera can understand and republishes it under the original MQTT topic.
Node-RED flow (FHEM->Camera)
You can copy the following code block and directly import it to you Node-RED environment (Note: that you will have to adjust the MQTT server that is selected by the MQTT nodes to have this flow work for you setup):
[{"id":"a8e41f4f.27d79","type":"mqtt in","z":"8a4560b4.b51e1","name":"nodered/features/ptz/preset","topic":"10D1DC2131A8:nodered/features/ptz/preset","qos":"1","datatype":"auto","broker":"71b4e74b.ddd018","x":125,"y":166,"wires":[["36b241a8.c1807e"]]},{"id":"2905841e.c141cc","type":"mqtt out","z":"8a4560b4.b51e1","name":"features/ptz/preset","topic":"10D1DC2131A8:features/ptz/preset","qos":"1","retain":"false","broker":"71b4e74b.ddd018","x":770,"y":160,"wires":[]},{"id":"d6fb84b2.514c38","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"0\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":39,"wires":[["2905841e.c141cc"]]},{"id":"36b241a8.c1807e","type":"switch","z":"8a4560b4.b51e1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"},{"t":"eq","v":"3","vt":"str"},{"t":"eq","v":"4","vt":"str"},{"t":"eq","v":"5","vt":"str"},{"t":"eq","v":"6","vt":"str"},{"t":"eq","v":"7","vt":"str"}],"checkall":"true","repair":false,"outputs":8,"x":315,"y":166,"wires":[["d6fb84b2.514c38"],["eb532fd8.b4d92"],["deaa695.1ed8c98"],["2c1a5d96.1b34a2"],["5f3a1afe.36a7f4"],["a51515e3.f455e8"],["190ffb70.d94255"],["f07cf298.dc074"]]},{"id":"eb532fd8.b4d92","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"1\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":79,"wires":[["2905841e.c141cc"]]},{"id":"deaa695.1ed8c98","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"2\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":119,"wires":[["2905841e.c141cc"]]},{"id":"2c1a5d96.1b34a2","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"3\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":159,"wires":[["2905841e.c141cc"]]},{"id":"5f3a1afe.36a7f4","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"4\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":199,"wires":[["2905841e.c141cc"]]},{"id":"a51515e3.f455e8","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"5\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":239,"wires":[["2905841e.c141cc"]]},{"id":"190ffb70.d94255","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"6\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":279,"wires":[["2905841e.c141cc"]]},{"id":"f07cf298.dc074","type":"change","z":"8a4560b4.b51e1","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"val\":\"7\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":533,"y":319,"wires":[["2905841e.c141cc"]]},{"id":"71b4e74b.ddd018","type":"mqtt-broker","z":"","name":"INSTAR_MQTT_SERVER","broker":"192.168.2.116","port":"8883","tls":"51d76162.2bd4","clientid":"Node-RED","usetls":true,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"51d76162.2bd4","type":"tls-config","z":"","name":"","cert":"","key":"","ca":"","certname":"mqtt_ca.crt","keyname":"","caname":"","servername":"","verifyservercert":false}]