This is supported. Not sure if a Switch or Connectivity Kit will support your APC, one of the developers actually uses as Somfy hub and an Atlantic hub for this…
Ohhh nice, unexpected
my plan is to keep to cozytouch for APC and add a connectivity kit for other I/O devices.
I have this reference (actually i have 8)
i can se the temperature that is measured in the room but it seems that the setting of the requested temperature is not implemented yet
by looking at the diagnostic file of the Tahoma Switch, it seems however that everything is there to configure the device the same way than the somfy app does
I have no python knowledge, (30 years ago i was able to code in java, C++, Assembler… may be i should try to learn) but ready to test
{
"deviceURL": "io://****-****-9373/3000744#1",
"available": true,
"synced": true,
"type": 1,
"states": [
{
"type": 3,
"name": "core:StatusState",
"value": "available"
},
{
"type": 3,
"name": "core:DiscreteRSSILevelState",
"value": "good"
},
{
"type": 1,
"name": "core:RSSILevelState",
"value": 100
},
{
"type": 3,
"name": "core:OpenClosedValveState",
"value": "open"
},
{
"type": 3,
"name": "core:OperatingModeState",
"value": "manual"
},
{
"type": 1,
"name": "core:TargetRoomTemperatureState",
"value": 20
},
{
"type": 1,
"name": "core:TargetTemperatureState",
"value": 20
},
{
"type": 3,
"name": "io:CurrentHeatingModeState",
"value": "manual"
},
{
"type": 1,
"name": "core:DerogatedTargetTemperatureState",
"value": 20
},
{
"type": 1,
"name": "core:DerogationEndDateTimeState",
"value": 1673960789000
},
{
"type": 1,
"name": "core:DerogationStartDateTimeState",
"value": 1673960789000
},
{
"type": 3,
"name": "io:DerogationHeatingModeState",
"value": "manual"
},
{
"type": 3,
"name": "io:DerogationTypeState",
"value": "further_notice"
},
{
"type": 1,
"name": "io:ManualModeTargetTemperatureState",
"value": 20
},
{
"type": 1,
"name": "core:BatteryLevelState",
"value": 74
},
{
"type": 3,
"name": "io:ValveInstallationModeState",
"value": "finished"
},
{
"type": 1,
"name": "core:ComfortRoomTemperatureState",
"value": 21
},
{
"type": 1,
"name": "core:EcoTargetTemperatureState",
"value": 19
},
{
"type": 1,
"name": "core:FrostProtectionRoomTemperatureState",
"value": 8
},
{
"type": 1,
"name": "io:AwayModeTargetTemperatureState",
"value": 17
},
{
"type": 1,
"name": "io:GeofencingModeTargetTemperatureState",
"value": 20
},
{
"type": 1,
"name": "io:OpenWindowDetectedTargetTemperatureState",
"value": 8
},
{
"type": 3,
"name": "core:ActiveTimeProgramState",
"value": "none"
},
{
"type": 1,
"name": "core:MaxSetpointState",
"value": 26
},
{
"type": 1,
"name": "core:MinSetpointState",
"value": 5
},
{
"type": 3,
"name": "core:OpenWindowDetectionActivationState",
"value": "active"
},
{
"type": 1,
"name": "core:TemperatureOffsetConfigurationState",
"value": 0
},
{
"type": 3,
"name": "io:ByPassActivationState",
"value": "disable"
},
{
"type": 3,
"name": "io:LockKeyActivationState",
"value": "disable"
},
{
"type": 11,
"name": "core:TimeProgram1State",
"value": {
"sunday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"friday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"monday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"thursday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"tuesday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"wednesday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"saturday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
}
}
},
{
"type": 11,
"name": "core:TimeProgram2State",
"value": {
"sunday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"friday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"monday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"thursday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"tuesday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"wednesday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
},
"saturday": {
"timeslots": [
{
"from": {
"minute": 0,
"hour": 0
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 6
}
},
{
"from": {
"minute": 0,
"hour": 6
},
"mode": "comfort",
"to": {
"minute": 0,
"hour": 21
}
},
{
"from": {
"minute": 0,
"hour": 21
},
"mode": "eco",
"to": {
"minute": 0,
"hour": 24
}
}
]
}
}
}
],
"label": "** ** ** ** ** **",
"subsystemId": 1,
"attributes": [],
"enabled": true,
"controllableName": "io:HeatingValveIOComponent",
"definition": {
"states": [
{
"name": "core:StatusState"
},
{
"name": "core:ActiveTimeProgramState"
},
{
"name": "core:MaxSetpointState"
},
{
"name": "core:MinSetpointState"
},
{
"name": "core:OpenWindowDetectionActivationState"
},
{
"name": "core:TemperatureOffsetConfigurationState"
},
{
"name": "io:ByPassActivationState"
},
{
"name": "io:LockKeyActivationState"
},
{
"name": "core:TimeProgram2State"
},
{
"name": "core:BatteryLevelState"
},
{
"name": "core:SensorDefectState"
},
{
"name": "io:ValveInstallationModeState"
},
{
"name": "core:DerogatedTargetTemperatureState"
},
{
"name": "core:DerogationEndDateTimeState"
},
{
"name": "core:DerogationStartDateTimeState"
},
{
"name": "io:DerogationHeatingModeState"
},
{
"name": "io:DerogationTypeState"
},
{
"name": "io:ManualModeTargetTemperatureState"
},
{
"name": "core:ComfortRoomTemperatureState"
},
{
"name": "core:EcoTargetTemperatureState"
},
{
"name": "core:FrostProtectionRoomTemperatureState"
},
{
"name": "io:AwayModeTargetTemperatureState"
},
{
"name": "io:GeofencingModeTargetTemperatureState"
},
{
"name": "io:OpenWindowDetectedTargetTemperatureState"
},
{
"name": "core:NameState"
},
{
"name": "core:OpenClosedValveState"
},
{
"name": "core:OperatingModeState"
},
{
"name": "core:TargetRoomTemperatureState"
},
{
"name": "core:TargetTemperatureState"
},
{
"name": "io:CurrentHeatingModeState"
},
{
"name": "core:TimeProgram1State"
},
{
"name": "core:DiscreteRSSILevelState"
},
{
"name": "core:RSSILevelState"
}
],
"widgetName": "ValveHeatingTemperatureInterface",
"attributes": [],
"uiClass": "HeatingSystem",
"commands": [
{
"commandName": "startIdentify",
"nparams": 0
},
{
"commandName": "stopIdentify",
"nparams": 0
},
{
"commandName": "exitDerogation",
"nparams": 0
},
{
"nparams": 4,
"commandName": "setAllModeTemperatures",
"paramsSig": "p1,p2,p3,p4"
},
{
"commandName": "getName",
"nparams": 0
},
{
"nparams": 2,
"commandName": "setDerogation",
"paramsSig": "p1,p2"
},
{
"nparams": 1,
"commandName": "setName",
"paramsSig": "p1"
},
{
"commandName": "identify",
"nparams": 0
},
{
"nparams": 1,
"commandName": "wink",
"paramsSig": "p1"
},
{
"nparams": 2,
"commandName": "setTimeProgramById",
"paramsSig": "p1,p2"
},
{
"nparams": 1,
"commandName": "setValveSettings",
"paramsSig": "p1"
},
{
"nparams": 1,
"commandName": "advancedRefresh",
"paramsSig": "p1"
},
{
"nparams": 1,
"commandName": "delayedStopIdentify",
"paramsSig": "p1"
}
],
"type": "ACTUATOR"
}
},
We can indeed support this device (ValveHeatingTemperatureInterface), however we would need time to write an implementation, someone to test and reviewers on the core repository.
You could start with creating an issue in core, where you included your diagnostics and share which features your model supports via the original app. (so which presets / settings etc.).
Alright - then lets try to get this up and running - I am fed up with my wife complaining that we have two seperate “smarthome-boxes” that fiddle around with temperature valves e.g. TahomaBox for IO and Homeassistant for the “old” ZWave Valves.
I want HA only for obvious reasons
I will try to get all the information for @imick and the awesome volunteer team from my end and write a summary today evening.
I have opened a request here (i hope it is on the right place)
The additional functions are described there (in addition to existing functions that already allow us to get the local temperature and other technical data)
Thanks to tell me what i should do from there
Best would be an issue on GitHub, including your diagnostics information.
Done
Last time I was searching for some wireless scene switches which could replace my Somfy Smoove IO wall units. I had found this Moes switch:
The problem with this switch is that it is not very fast with sending the zigbee command. Also I read a lot of stories that the batteries are drained very fast (2 months).
Because I have everywhere Hue Lights in my house I thought maybee the Hue Dimmer Switches are an option.
So I have replaced 2 Somfy Smoove IO units for 2 Hue Dimmer Switches V2 for testing the coming days.
To use the KIS (keep it simple) principle
- The Hue Dimmer Switch sends zigbee signal to an Ikea Zigbee repeater
- My raspbery pi 4 has a Dresden Conbee II stick
- Node-Red checks which dimmer is sending the command and sends an open/close/stop/etc… command to a cover template depending which button and which action (short / long press release)
- In the cover template the system sends a window/door status request to a microcontroller (ESP8266) that has reed contacts connected to the window/door
- When window/door is closed, the command is send to the real cover. When it is open it will ignore the requested cover command and nothing happens.
I still have to place labels on the hue buttons. For now I have created the next functions to the buttons:
- Top button: Short press release → cover open (normal speed)
- Top button: Long press release → cover open (discrete speed)
- Second/third button → stop cover (I will give it also some specific position function like the “My” button)
- Bottom button: Short press release → cover close (normal speed)
- Bottom button: Long press release → cover close (discrete speed)
I have to say that it works quite nice. There is offcourse some lag. This will be improced with a local api. Also i’m going to change my microcontroller to a version with ethernet instead of wifi.
When everything stays working perfect, I will change all my Somfy smoove IO units by those Hue dimmers.
Pros:
- When controlling the covers with the Hue Dimmer, Home Assistant has directly the new state of the covers (with the Somfy Smoove IO (which sends commands to the motor instead of the hub), Home Assistant has the wrong states)
- I can execute all kind of safety logic before really controlling the cover.
- In Home Assistant I see the state of the battery
Neg:
- There are mutiple players which could have failure
- When there is no internet connection, the hue dimmers could not operate the covers (is solved with a local api/homekit and I have also some Somfy Situo IO units which are connected directly to the motors).
But when somebody knows another wireless switch, I’m still interested. At this moment I don’t have buy all the other switches that I “have” to replace.
@imick Hi, I have a question: With the Overkiz Cloud Integration, I can also see lamps that have been integrated into Tahoma Switch via philps Hue and Somfy Protect. with the local developer API integration, these lamps are no longer retrieved. would it be possible to get the bulbs from the Local Developer API as well?
Thanks for an answer.
Hi, sadly the local api as implemented by Somfy/Overkiz is just a subset or their cloud version.
It’s why all the devices are not returned when you switch to the local version. There is nothing we can do on our side.
But may I ask why you paired your Hue lights with the Tahoma? The Hue integration within HA is way more powerful and give instant feedback.
Hi, actually I also use the Hue integration in Home Assistant. It’s a basic question as I noticed the difference. There is also an MQTT integration for the Somfy Protect devices, but so far I have also gotten along well with the Overkiz Cloud Integration.
@Stylewarz3 which Somfy Protect devices do show up in your Overkiz cloud, but not in your Overkiz local? Can you share the hardware and model names? (you can find that on the device page in Home Assistant).
In the future; we will probably make it possible to use local and cloud API next to each other.
@imick of course:
The first device is not specific:
Modell:
Home Protect System
von Somfy
Firmware: 1
The second device:
Modell: MyFoxAlarmController
Hardware: myfox:SomfyProtectAlarmController
The third device:
Modell: MyFoxSecurityCamera
Hardware: myfox:SomfyProtectSecurityCameraController
With the MyFox Security Camera device, lights connected to the camera are also integrated as entities.
I made significant progress to integrate ValveHeatingTemperatureInterface, which corresponds to this somfy product
The first (and biggest) difficulty was to extract the overkiz integration built in home assistant from the core back in a custom component, (simply use the core source code, and adding a version is not working)
I have to admit i am quite new in Home assistant ecosystem and my python skills were quite limited. I used to be an embedded software engineer in the last century, but more used to develop in assembler, C/C++ and Java than on the kind of new languages where you discover issues when running it…
OK after some time i managed to build this development environment in my custom folder, taking this fork as the heart of the custom component GitHub - iMicknl/home-assistant-core at overkiz/local_support
When implementing the somfy device i started from pre integration work done few years ago and managed to at least be able to set a temperature on my valve. and it worked !
"""Support for ValveHeatingTemperatureInterface."""
import logging
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (
HVAC_MODE_HEAT,
SUPPORT_PRESET_MODE,
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from ..entity import OverkizEntity
_LOGGER = logging.getLogger(__name__)
# Map Overkiz HVAC States to Home Assistant HVAC states
OVERKIZ_TO_HVAC_STATES = {
"open": "heating",
"closed": "idle",
}
HVAC_STATES_TO_OVERKIZ = {v: k for k, v in OVERKIZ_TO_HVAC_STATES.items()}
# Map Home Assistant presets to TaHoma presets
PRESET_MODE_TO_OVERKIZ = {
"away": "awayMode",
"comfort": "comfort",
"eco": "eco",
"frostprotection": "frostprotection",
"geofencing": "geofencingMode",
"manual": "manual",
"suddenDrop": "suddenDropMode",
}
OVERKIZ_TO_PRESET_MODE = {v: k for k, v in PRESET_MODE_TO_OVERKIZ.items()}
class ValveHeatingTemperatureInterface(OverkizEntity, ClimateEntity):
"""Representation of Valve Heating Temperature Interface device."""
_attr_hvac_mode = HVAC_MODE_HEAT
_attr_hvac_modes = [HVAC_MODE_HEAT]
_attr_preset_modes = [*PRESET_MODE_TO_OVERKIZ]
_attr_supported_features = SUPPORT_PRESET_MODE | SUPPORT_TARGET_TEMPERATURE
_attr_temperature_unit = TEMP_CELSIUS
@property
def hvac_action(self) -> None:
"""Return the valvestate and transpose in Climate state."""
return OVERKIZ_TO_HVAC_STATES[self.executor.select_state("core:OpenClosedValveState")]
@property
def target_temperature(self) -> None:
"""Return the temperature."""
return self.executor.select_state("core:TargetTemperatureState")
@property
def current_temperature(self):
"""TO DO Return current temperature from sensor - not working for the momment"""
return self.executor.select_state("core:TemperatureState")
async def async_set_temperature(self, **kwargs) -> None:
"""Set new temperature."""
temperature = kwargs.get(ATTR_TEMPERATURE)
await self.executor.async_execute_command("setDerogation",float(temperature),"further_notice")
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode."""
# TODO
return
@property
def preset_mode(self) -> str:
"""Return the current preset mode, e.g., home, away, temp."""
return OVERKIZ_TO_PRESET_MODE[
self.executor.select_state("io:DerogationHeatingModeState")
]
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode."""
await self.executor.async_execute_command(
"setDerogation", PRESET_MODE_TO_OVERKIZ[preset_mode]
)
So i am the most happy man on earth as i can already pilot my valve using HA environment and not anymore the Somfy one
But now i want to go beyond
- Integrate a way to merge the sensor with the valve
the overkiz integration is generating two devices for my valve
- the valve itself with name io:HeatingValveIOComponent
- the sensor of the current temperature with name io:TemperatureIOSystemSensor
they have the same URL but with #1 and #2 at the end of the URL
I wish to merge them or at least to copy the current temperature from #2 in the #1
- the Somfy IO protocol used by the device is allowing to access the device every 5 mins, so when changing the target temperature, the update is not done instantaneously. I used the simple-thermostat card (from HACS) that is showing it in a very nice way. I change the target temperature, it stays red until the temperature has changed and come back to black. Could be nice if a similar behavior is set on official HA cards
I will continue to improve the integration (management of the io:OpenWindowDetectedTargetTemperatureState function for instance) and ready to share work in teams if some of you share the same goal
I wish also to better integrate my tahoma switch component (device internal:PodV3Component, device internal:WifiComponent, io:StackComponent…) if anyone interested to work together…
Hello Stylewarz
My Understanding is that Somfy protect is not handled physically by your somfy box (Tahoma or Tahoma switch) locally.
It is integrated in the cloud, together with your box installation by Somfy making it visible with the same API. (thus a HA cloud API integration implement both your box and the somfy protect services)
Reason why you do not see it if you implement local
My recommendation (that i did in my installation) would be to integrate somfy protect locally using Homekit (for the flow part, the light…)
and using MQTT (for the configuration part - using SomfyProtect2MQTT add on ) as it implement most of the configuration available in the somfy protect app itself but is not implementing the real flow of the camera (only snapshot)
I made a card to fully use what I developped
it is using simple-thermostat from HACS
type: custom:simple-thermostat
entity: climate.vanne_e1_salon #THE NAME OF YOUR VALVE DEVICE
layout:
mode:
icons: true
headings: false
hide:
temperature: true
sensors:
- entity: sensor.vanne_e1_salon_vanne_e1_salon_temperature #THE NAME OF YOUR SENSOR
name: Currently
Hey @legantois dont put more work into it as imick commited an integration for the valve in github. In one of the comming updates (when it is all done and approved for) it should be supported by core.
Maybe you want to contact them to join them in integrating stuff as you seem very capable and enthusiastic Sadly I am only enthusiastic but not capable as I cant code stuff and fail at simply yaml code
We are in contact, no worries.
You can still help. What kind of bridge do you have ?
I have the (now older) tahoma box (not the tahoma switch).
And I got plenty of zip-shades from Somfy, Io thermostats, Io smoke detectors etc.
And the zigbee usb stick in the tahoma box to control the Danfoss Thermostats.
I plan to remove the heating control from the tahoma box and to control them over Z-Wave.
Except the Io ones as they only can be controlled by the tahoma integration.