Yio Remote Community

Ideas for remote implementation

I have a few ideas about current Qt remote implementation. Unfortunately, I have not enough experience with Qt otherwise I would like to participate more.

  1. For a production version it is necessary to decompose the whole thing with Qt plugins into DLLs. If you implement functionalities like different media players, the whole thing explodes when you put all this into a monolithic source.

  2. I think integration-specific details should be kept out of the components folder by introducing an abstraction layer so that a light in the component layer is always the same no matter which interface it integrates. For this purpose I have replaced the entities from config.json with entity objects with more functionality, so that all integration-specific things are handled centrally in integrations/xxx.components. /components/light/Main.qml, homeassistant.qml … will be superfluous.

The Entity objects are then referenced directly eg in Button.qml and deliver there onChanged signals to show changes spontaneously. And they forward the commands to, for example, integrations/homeassitent.

@marton: If you are interested I fork the project to my repository and you can take a look …

I also have very limited experience with Qt and coding in general :slight_smile: So I am open to any suggestions.

The app is component based. The elements are stored in resource files and loaded when needed. It might occupy some disk space, but it won’t load the whole thing. I don’t think we have to worry about dlls in a linux environment. The goal is to run this on a Pi that is the core of the remote. You can run it on different systems, but the main development focus is going to be linux on a Raspberry Pi.

It is done this way right now. The light entity looks and behaves the same way no matter what integration is using it. Each entity has a variable that refers to the integration type. When for example turn on a switch, the entity is just sending a turn on command to the integration defined in the integration type variable. And the components/light/homeassistant.qml for example takes care of interpreting the turn on command and forwarding the right command to the home assistant integration.

I think it makes more sense to separate the components and the integrations in the way it is done right now. Otherwise we would end up x light components under the integrations. Right now we have 1 light component that can connect to multiple integrations.

Also the integration is just handling the connection between the smart home hub and the remote. Commands to that integration is defined in the component part of the integration.(Why load all the unnecessary commands, when you might not have all the components in your setup?) This way it is really easy to add a new component. You just connect it to the integrations signals.

I can’t seem to find your version on your github. Could you send me the link to the modified fork?

@marton : You can take a look on my version at https://github.com/ChristianRiedl.
I added a RIC-changes.txt in the software/remote directory with some more info.

Can you tell me what are you plans in general ?
Do you want to create a product which only requires some configuration ?
Do you assume that the user is able to customize and compile form sources ?

The most important thing for me is to get the hardware. I am software developer since 40 years and still like to try new technologies, It is not important for me to control TV with original remote or a universal one. I like to solve problems.

My requirements for the remote are anyhow quite high

  • Control light, blind, clima
  • Show temperatures
  • Control old audio equipment (B&O) via IR
  • Control Roon media player (including browsing my music)
  • Control TV (including TV program, my server creates my own TV program)
  • Maybe door camera integration
1 Like

Thanks! Now I can see your version. I haven’t been able to yesterday. I’ll take a deeper look in the weekend.

You can find some information about the plans in the forum but in short:
I am planning to sell the remote as a kit. So you would buy all the parts and you’d assemble it yourself. It is still a DIY project at this stage.

Once you have the hardware you’ll need an SD card and burn an image with the custom built OS and the software on it. You pop that in and a setup flow will guide you through the setup process. No compiling and things like that.

If you are using a home automation hub like Home Assistant, Homey or Openhub, you’ll be able to control lights, blinds and climate things if there’s an integration and component for it. I run Home Assistant myself, so I’m making components for that system. However you won’t be able to control you devices without a hub. You could if they are wifi enabled and someone writes the integration, but there are no zwave, zigbee or any other radios in the hardware.

There are talks about integrating IR capabilities into the dock part of the remote, so controlling IR devices can be an option.

Media player and TV integration is a software thing and can happen if someone takes the time and writes an integration.

All in all, the Yio Remote could control anything where it’s possible to do it with software.

1 Like

@ChristianRiedl i’m looking at your code right now; are you more or less trying to implement the ‘Neeo’ way of capabilities for an entity? As in; you can create a ‘dumb’ light entity and a light entity which is able to set brightness and maybe someone who also has color features? I might not understand the ‘feature_map’ change you did, can you elaborate?

What i’m hoping you did is that you can ‘create’ your own device (e.g. discovery type of stuff) which can tell to the remote UI which capabilities your lightEntity has and based on that build the UI out of it.

@Gilles
I do not care about recreating anything from NEEO. For NEEO smarthome was a side issue. However, I’ve been inspired by some interfaces (Alexa SmartSkill, Samsung SmartThings, Open Connectivity Foundation, openHab) and the way they are implementing it. I do not like the fact that integration-specific functionalities appear in different parts (integration, components) in the current YIO Remote implementation. And currently you have to search in the sources to find

I think it is better to define one standard object for each of the various things that you want to support (light, awnings, climate, temperature, speakers …) and on which the GUI then operates. And each of this thing typically supports several functionalities ( = features)

Light : Switch, brightness, color, color temp
Speaker : Vol up, vol down, vol level

In my implementation LightEntity has this properties (some more comments should be added)

property string entity_id
property string area
property var	friendly_name
property bool	sup_switch
property bool	sup_brightness
property bool	sup_color
property bool	sup_colortemp
property bool	state                   // on / off
property int	brightness          // 0 .. 100
property int	color                   // rgb 
property int	colortemp
property bool	favorite

The features are the sup_xxxx.

And depending oin the features LightEntity supports the commands.

“TOGGLE”, “ON”, “OFF”, “BRIGTHNESS”, “COLOR”, “COLORTEMP”

The implementer of an integration “only” has to convert the integration specific representation into the
“standard” object properties and to understand the “standard” commands. Sometimes the features have to be configured sometimes they are delivered by the integration hub.

I know the original implementation in components/light/homeassitant.qml has the same functionality. But the standard object LightEntity has the advantage that it also documents what the GUI supports and what the hub implementer has to implement.

Converting hub specific data into the standard object should be part of the one and only integration component. When the system grows (more objects, more integrations) I think it is better to have a clear structure (divide et impera). In the current state of the project (only light and homeassistant) it looks maybe over - engineered but I think this is the right moment to introduce a scalable structure which helps to handle complexity when the system is growing.

The generic “Entity” object which I use as generalization of all kind of objects is maybe not necessary but in my opinion simplifies hub implementation and config.json read write.

The bitmap feature_map maybe should be replaced by a string array of features. But this is only an implementation detail.

1 Like

I like the direction you went with your changes. I agree that there should be one “standard” representation that the integration has to adhere to. If i understand your idea and direction correctly this would mean that, for example, you could have one “TV” entity, with channel zapper screen, favorites screen, channel screen, numeric keyboard etc. all included and depending on how the device/integration exposes the features of this entity, all or just a part of these screens would appear to the user on the remote, right?

Yes, but the hard thing is to implement the GUI and the integration. The standard objects are something like a contract to define and document the functionality of the objects.

I am happy with the solution we will get and for me it is not a problem to create a version with new integrations. But it would be nice if new integrations can be implemented without modifying the original sources and recompiling. In Qt there is the concept of “plugin” which allows to add for example a new integration as dll. I made some experiments and was able to add such a dll implemented with Qt C++ objects.
But I was not able to solve it with Qt Qick / qml. I have not enough Qt skills and Qt documentation is not detailed enough. Maybe somebody can help.
I would like to know if somebody is interested in the possibility to implement integrations in C++

@ChristianRiedl I had some time to look at the code in a bit more detail and I understand what you’re doing and it makes sense.

What I wanted to do with the current setup is to separate the files that are connected to a component from the main integration files. Easier to manage I believe, when you don’t have to add code to the integration/homeassistant.qml or whatever, just create the files inside the components folder. My idea was that the main integration file handles the connection and communication between the hub and the remote and sends a signal when something changed. Then the component is interpreting the data and decided if it’s relevant.

But as I said before, I am not a developer, so my idea might not be the best.

I haven’t looked at the plugin part, but I think it’s not a big deal to recompile the software. The idea is that for not so hardcore users the remote will check for new versions and downloads the latest binaries and updates itself.

Recompiling is no big deal but you loose the advantage of automatic updates. And when the interfaces for the plugin dll are standardized it is possible that people like me implement such integration plugins and make it available as dll to other people. There are so many different integration hubs on the market that you cannot add them all in “standard remote”. Integration plugins are easy compared to the GUI.

It is much more complicated to integrate the GUI for a TV or a Media Player (with browse support) as plugin. Putting all the wanted GUI’s into the standard would require a very configurable GUI, which is quite complicated. But possible, (NEEO spent 3 years and the result was not great)

The master branch, after compiled, is uploaded to a github release. Right now the remote is looking for these, checks the version and if it’s newer, downloads and replaces the files.

It is much more complicated to integrate the GUI for a TV or a Media Player (with browse support) as plugin.

True, but that depends on how you approach it. If you take for example a certain GUI which has all the options (and possibilities for favorites) and make ‘what’ that component shows configurable on a per screen basis, i think you are almost there. I don’t want to ‘mimic’ the Neeo but i think taking the best of that SDK doesn’t hurt.

Looking at their readme.

The view for a device in the recipe is generated automatically depending on the device capabilities.

See widget documentation for more details on the way default views are generated.

Which in turn says:

The view for devices is dynamically generated based on their capabilities and components. This process is done in three steps:

  1. A list of compatible widget is generated for the recipe view
  2. Slides are generated based on the available widgets
  3. Slider are reordered or hidden based on user settings

Check here how i did it for Neeo: https://github.com/Webunity/neeo-driver-ziggo-horizon/blob/master/index.js#L29
Docs: https://neeoinc.github.io/neeo-sdk/#src-lib-models-devicebuilder.ts-addbuttongroup

If you look at some of the pictures:

This ‘view’ consists probably of 4 button groups:

  • Color buttons
  • Numpad
  • Guide
  • Info

If you add only ‘one’ of them (in your device definition) this view would be shown. One thing i hope will be possible (somehow, probably have to code it myself) is the possibility to add ‘favorites’ to a device, like shown in below picture;

I don’t know where to store them etc etc. but you also see that one ‘recipe’ is a combination of multiple ‘views’ (the dots at the top of the screen)

I have implemented now a more thoughtful version of entity objects. I think they should be implemented in C++ to get the optimal functionality with minimum resource usage. But I have made a great effort to make the implementation of new entities as easy as possible.

And I implemented an integration plugin DLL sample which shows how to add an integration without recompiling.

You can take a look : https://github.com/ChristianRiedl/yio-remote

Until now it is tested only on Windows. If @marton want’s to go in this direction I will test it on the PI.

My next project will be a prototype of a simple TV integration with GlobalCache IR sender.

Here a bit more about my current solution :

Goals :

  • GUI objects like components/light/Button should work with integration-neutral entities.

  • This entities should be able to provide the GUI with a comfortable easy to use interface.

  • This entities should not use more ressources as necessary (only possible with C++)

  • Transforming integration specific formats into standard entity attributes and back (commands) is part of the one and only integration module

  • Integrations can be implemented as qml or C++ modules

  • Integrations can be implemented as Plugin DLLs to allow adding of integrations without recompiling the remote software

Implementation :

  • Entity : Base class implementing common features of the entity object

  • LightEntity : Light entity implementation

  • Entities : Singleton root object containing all entity objects. Entities is global accessible (“all_entities”)

The C++ sources are inside /sources/entities
Entities are created in main.qml based on the config.json entities. config.json entities are replaced by the entity objects

  • Integration Plugin DLL loading:

The name of the plugin dll is configured by an additional property “plugin” containing the name of the dll in config.json / integration

Handled by an extension of launcher.cpp. Dlls have to be stored in the Plugin directory

Required changes :

main.qml/LoadEntities : replace config.json entities against Entity object

helper.js/saveConfig : before writing the entity object it is replaced by an object containing only the properties which should be stored.

components/light/Button.qml : make use of the light entity object (getting attributes, features, send commands)

integration/homeassistent.qml Add the transformation to and from standard-entity

Status :

Tested on Windows 10 / VS2017 with modified homeassistent.qml and my MQTT based pluging interface DLL (SmartHomePlugin)

Thanks so much for your work and suggestions @ChristianRiedl! I agree that tackling the entities in C++ is less resource heavy.

I’m not sure DLLs would work on linux and I still think that having plugins is not a high priority right now, but in the future it could be handy.

Anyways, I’ll look into merging your ideas once I’m done with the things I’m working on right now.

A post was split to a new topic: OLED display consideration

There are shared libraries (.so) in Linux too. I see no reason why it should not work.

I will start to try my version on a PI Zero W.

On which platform do you create the PI Zero executable ? Theoretically it should be possible to cross compile with MinGW on Windows, but I never tried it.

Cool, I didn’t know it existed.

I’m cross compiling on my mac running linux.

I started to setup a PI Zero W for testing. My biggest problem is to get a suited Qt Version on the PI.
I was able to compile the remote with Qt 5.7.1 which is available for the PI. I learned that compiling on the PI Zero is acceptable for a project of similar size (5 - 10 minutes). But YIO remote requires minimum Qt version 5.7.11. I did not find binary packages for the PI newer than 5.7.1.
So the only possibility is to build it from the sources ?
At first I tried it on Windows 10 with VisualGdb. I failed.
I wanted to avoid setting up Linux on my PC so I decided to build it on the PI Zero following this instructions :

https://www.tal.org/tutorials/building-qt-512-raspberry-pi

It is running now for 12 hours and I am not sure if and when I will get a running Qt. …

Does somebody know where to get binary packages >= 5.11 for the PI ?