This project is a simple bridge for the Smart Friends Box and devices (Schellenberg, ABUS, Paulmann, Steinel). There is a REST API and an MQTT client.
Tests have been carried out on on the Smart Friends Box but it probably also works on the Schellenberg SH1-Box.
You must have the .Net 8.0 Runtime installed to use this or you must run as the docker/hassio-addon.
A device must be supported by the Smart Friends Box to be controllable. So if you paired a Zigbee or Z-Wave device and do not see it in the Smart Friends app, then is unlikely you be able to control it with this bridge even though you will see the device listed.
Recommended to use the HASSIO add-on. Add to the Supervisor Add-on store
https://github.com/GimpArm/hassio-addons
See readme specific to service type for other install methods.
First decide if using MQTT or REST API.
MQTT will integrate into the Home Assistant MQTT Integration. The devices you setup and map will automatically be discovered by the integration creating devices and entities. It also takes advantage of the push notifications from the Smart Friends Box and relays them to the MQTT broker which informs Home Assistant. It is a more powerful interface but requires that you have configured a broker and the MQTT integration, along with some device mappings because the Smart Friends Box does not give enough information to accurately guess the what kind of device or how to control it in Home Assistant.
REST API is a more simple passive system. You must manually configure entities in Home Assistant to query the service along with polling for changes. This means there is usually a few seonc delay between manually operating a device and seeing its state change in Home Assistant.
Both MQTT and REST API must be configured to talk to the Smart Friends Box.
- Open the (appsettings.json) and change it accordingly:
{
"SmartFriends": {
"Username": "", #---------------> Username (case sensitive)
"Password": "", #---------------> Password
"Host": "", #-------------------> IP of your Smart Friends Box
"Port": 4300, #-----------------> Port of the box, generally 4300/tcp
"CSymbol": "D19033", #----------> Extra param 1
"CSymbolAddon": "i", #----------> Extra param 2
"ShcVersion": "2.21.1", #-------> Extra param 3
"ShApiVersion": "2.20" #-------> Extra param 4
},
"Mqtt": {
"Enabled": false, #-------------------> Flag whether to enabled or disable the MQTT client.
"DataPath": "/config/smartfriends2mqtt", #---------------------> Directory path to where the deviceMap.json and typeTemplate.json files are stored.
"BaseTopic": "smartfriends2mqtt", #---> Base MQTT topic to store device information. Ok to leave as is.
"Server": "homeassistant", #----------> Broker server name or ip.
"Port": 1883, #-----------------------> Broker port, most likely 1883.
"User": "mqtt", #---------------------> Broker client username.
"Password": "4mqPass!", #-------------> Broker client password.
"UseSsl": false, #--------------------> Flag whether the broker requires SSL or not.
"ProtocolVersion": "V500" #-----------> One of V310=3, V311=4, V500=5. If you have no problems, no need to change.
}
}Extra API parameters: In order to find these values, simply open the Smart Friends App and go to the information page as illustrated:
Device ID's are important, they will be used to interact with the device itself.
After starting up in a browser go to:
http://homeassistant:5001/list
And you will see an output like this:
[
{
"id": 13103,
"name": "Blinds Dining",
"room": "Dining Room",
"gatewayDevice": "SmartFriendsBox",
"kind": "RollingShutter",
"manufacturer": "Alfred Schellenberg GmbH",
"state": "Stop",
"devices": {
"rollingShutter": {
"Id": 2973,
"description": "SchellenbergBlind",
"commands": {
"Stop": 0,
"Up": 1,
"Down": 2
},
"currentValue": "Stop"
},
"position": {
"Id": 3555,
"description": "SchellenbergPosition_Blind",
"max": 100,
"min": 0,
"precision": 0,
"step": 1,
"currentValue": 0
},
"stepper": {
"Id": 14246,
"description": "SchellenbergBlind.Steps",
"commands": {
"Up": 1,
"Down": 2
}
},
"default": {
"Id": 4144,
"description": "SchellenbergRssi",
"currentValue": "SignalHigh"
}
}
},
{
"id": 1323,
"name": "Light",
"room": "LivingRoom",
"gatewayDevice": "SmartFriendsBox",
"kind": "switchActuator",
"manufacturer": "Zigbee Switch Device",
"state": "Off",
"devices": {
"switchActuator": {
"Id": 14246,
"description": "Zigbee Switch Device",
"commands": {
"Off": 0,
"On": 1,
"Toggle": 2
}
}
}
},
...
...
]The service exposes a simple REST API which you can call to control your devices. Below are examples of the raw endpoints, followed by Home Assistant examples using the rest integration (REST sensors + rest_command) instead of command_line / shell_command.
- Open shutter:
http://127.0.0.1:5001/set/13103/rollingShutter/up - Close shutter:
http://127.0.0.1:5001/set/13103/rollingShutter/down - Stop shutter:
http://127.0.0.1:5001/set/13103/rollingShutter/stop - Go to position 50%:
http://127.0.0.1:5001/set/13103/position/50 - Get current shutter position:
http://127.0.0.1:5001/get/13103/position - Move shutter 1 step down:
http://127.0.0.1:5001/set/13103/stepper/down
Other devices can be controlled by using a command or setting a numeric value. Simple devices like a Zigbee switch can be controlled with:
- Turn device on:
http://127.0.0.1:5001/set/1323/on - Turn device off:
http://127.0.0.1:5001/set/1323/off - Read state:
http://127.0.0.1:5001/get/1323
This is an example of integrating to Home Assistant using the RESTful Sensor. The MQTT approach will yield better results but REST is still an option for people who do not want to use it.
This example creates three parts:
- A REST sensor to poll the current shutter position
- REST commands for up/down/stop/set-position
- A Template Cover that binds (1) and (2) into a real
cover.*entity
# 1) Read current position (polling)
rest:
- resource: "http://127.0.0.1:5001/get/10433/position"
scan_interval: 5
sensor:
- name: "Shutter Position Office"
unique_id: "shutter_position_office"
unit_of_measurement: "%"
value_template: "{{ 100 - (value_json.currentValue | int(0)) }}"
# 2) Control endpoints
rest_command:
shutter_up:
url: "http://127.0.0.1:5001/set/{{ device_id }}/rollingShutter/up"
method: GET
shutter_down:
url: "http://127.0.0.1:5001/set/{{ device_id }}/rollingShutter/down"
method: GET
shutter_stop:
url: "http://127.0.0.1:5001/set/{{ device_id }}/rollingShutter/stop"
method: GET
shutter_set_position:
# Invert for devices that are opposite of Home Assistant
url: "http://127.0.0.1:5001/set/{{ device_id }}/position/{{ 100 - position }}"
method: GET
# 3) The cover entity
cover:
- platform: template
covers:
shutter_office:
friendly_name: "Shutter - Office"
device_class: shutter
position_template: "{{ states('sensor.shutter_position_office') | int(0) }}"
open_cover:
service: rest_command.shutter_up
data:
device_id: 10433
close_cover:
service: rest_command.shutter_down
data:
device_id: 10433
stop_cover:
service: rest_command.shutter_stop
data:
device_id: 10433
set_cover_position:
service: rest_command.shutter_set_position
data:
device_id: 10433
position: "{{ position }}"Example configuration:
# 1) Read state
rest:
- resource: "http://127.0.0.1:5001/get/14106"
scan_interval: 5
sensor:
- name: "Office Light Raw State"
unique_id: "office_light_raw_state"
value_template: "{{ value_json.state }}" # "On" or "Off"
# 2) Control endpoints
rest_command:
device_on:
url: "http://127.0.0.1:5001/set/{{ device_id }}/on"
method: GET
device_off:
url: "http://127.0.0.1:5001/set/{{ device_id }}/off"
method: GET
# 3) The switch entity
switch:
- platform: template
switches:
office_light:
friendly_name: "Office Light"
# Convert the REST sensor string ("On"/"Off") into a boolean
value_template: "{{ states('sensor.office_light_raw_state') | lower == 'on' }}"
turn_on:
service: rest_command.device_on
data:
device_id: 14106
turn_off:
service: rest_command.device_off
data:
device_id: 14106- This REST approach is polling-based, so state updates can lag by your
scan_interval.
DeviceMap is a map of the Smart Friends Id to the HASSIO type/class with optional device specific overrides.
On start up the deviceMap.json file in the DataPath folder will be loaded. If no file exists then an empty file is created.
If there is no entry in the deviceMap.json file for a device then it will not be available over MQTT. This is required because mapping a device from the information the Smart Friends Box makes available to a HASSIO device cannot currently be done automatically.
{
"Id": number, #-------> (required) The ´id´ from the above print out.
"Type": string, #-----> (required) The HASSIO device type to be presented as.
"Class": string, #----> (optional) The HASSIO device class, not all device types have classes.
"Parameters": { #------> (optional) Key value override HASSIO settings and TypeTemplate for specific operation of the devices. See HASSIO MQTT device type specific documentation.
"hassio_key1": value1,
"hassio_key2": value2
}
}There are currently 2 variables that can be useful for making templates that apply to all devices of a specific type.
{baseTopic}is simply the value from the settingBaseTopicso the templates can remain generic.{deviceId}the MQTT unique ID for the device, currently it is in the form"sf_" + DeviceMap.Id.
{
"Id": 13103,
"Type": "cover",
"Class": "shutter"
}Set the icon to a lightbulb.
{
"Id": 1323,
"Type": "switch",
"Parameters": {
"icon": "hass:lightbulb"
}
}{
"Id": 206,
"Type": "binary_sensor",
"Class": "door"
}TypeTemplates define templates to apply to all devices types/classes to override the basic default behavior. See https://www.home-assistant.io/docs/mqtt/discovery/
On start up the typeTemplate.json file in the DataPath folder will be loaded. If no file exists then a file with the below examples will be created.
TypeTemplates are optional but for proper control of most devices it is probably required. I include the example for the Schellenberg Rolladen because that is all I own. For proper HASSIO integration you will need to do some trial and error and read the MQTT Discovery documentation.
For very basic devices like a Zigbee switch or Zigbee door/window sensor that only needs to read the state information and/or send a single sub device command no template is needed.
{
"Type": string, #-------> (required) Device type to apply the template to.
"Class": string, #------> (optional) Some device types have a class which you can use be even more specific about when to apply the template.
"Parameters": { #-------> (required) Key value override HASSIO settings for specific operation of the devices. See HASSIO MQTT device type specific documentation.
"hassio_key1": value1,
"hassio_key2": value2
}
}There are currently 2 variables that can be useful for making templates that apply to all devices of a specific type.
{baseTopic}is simply the value from the settingBaseTopicso the templates can remain generic.{deviceId}the MQTT unique ID for the device, currently it is in the form"sf_" + DeviceMap.Id.
{
"Type": "cover",
"Class": "shutter",
"Parameters": {
"command_topic": "{baseTopic}/{deviceId}/rollingShutter/set",
"position_topic": "{baseTopic}/{deviceId}/position",
"position_template": "{{ 100 - value | int }}",
"set_position_topic": "{baseTopic}/{deviceId}/position/set",
"set_position_template": "{{ 100 - position }}",
"state_stopped": "Stop",
"state_opening": "Up",
"state_closing": "Down",
"payload_stop": "Stop",
"payload_open": "Up",
"payload_close": "Down"
}
},Special thanks to LoPablo for their work on figuring out how the Schellenberg/SmartFriends API functions.
