danielwippermann / resol-vbus-java

A Java library for processing RESOL VBus data
7 stars 6 forks source link

[question] - I need a possibility to change "Handbetrieb" values of my Resol MX via LAN/VBus #27

Open df8oe opened 1 year ago

df8oe commented 1 year ago

Hi Daniel, many thanks for your impressive documentations. I am using Resol MX and want to change "Handbetrieb" values via LAN/VBus. I am using RPI for this task, reading out values is done via python package https://github.com/rellit/resol-vbus-python . I push data in influxdb, visualizing with Grafana and everything is working well. Because the data is transferred every minute (and transfer needs a couple of seconds) there are two possibilities to switch relays / set PWM states: 1) implement simple "writing data method" to resol-vbus-python 2) add java call to your library after python script has finished to only change the wanted value

Both do have advantages and disadvantages: If I will use 1) I need a pointing to the bytes/values which are transferred to set the value, if I use 2) I need a pointing how I can call the command using resol-vbus-java. Making the solution KISS it would be better to implement setting possibility to python. I can extract the ids from mx-menu.xml manually (if I know which ones are needed). But how to transfer on/off/auto to specific relay and min/max/on/off/auto to PWM Outputs? And additionally: does writing values wear out hardware cells in the MCU and reduces lifetime of the chip?

danielwippermann commented 1 year ago

Hi @df8oe!

Sorry for the late reply, your question slipped through in my inbox...

I have wanted to document parts of that question for quite some time now (e.g. in my reminder to self: https://github.com/danielwippermann/resol-vbus/issues/88 :) ). I'll do that probably today and link that documentation here.

Best regards, Daniel

danielwippermann commented 1 year ago

Hi @df8oe!

The first draft of the documentation is available here:

http://danielwippermann.github.io/resol-vbus/#/md/docs/vbus-parameterization

Feel free to ask if something is still unclear.

The documentation includes example code for a parameterization application in JavaScript. That could be used:

My Python knowledge is limited so I sadly cannot really assist in extending resol-vbus-python to perform the necessary things.

Best regards, Daniel

df8oe commented 1 year ago

Many thanks for this - it looks quite good. I will dig into it the next days. For me coding skills are exactly reversed: my best coding is in c / c++, followed by python and at last java. But no coding language is difficult - they all follow logical rules. So I will start learning and probably push functions to python. Thanks for accepting questions in the future - I think I will need this for porting...

Best regards Andreas

danielwippermann commented 1 year ago

The minimal Java example for a single value would be:

/**
 * Copyright (C) 2008-2016, RESOL - Elektronische Regelungen GmbH.
 * Copyright (C) 2016-present, Daniel Wippermann.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
package de.resol.vbus.example.parameterization;

import java.net.InetAddress;

import de.resol.vbus.Connection;
import de.resol.vbus.Datagram;
import de.resol.vbus.TcpDataSource;
import de.resol.vbus.TcpDataSourceProvider;

public class Main {

    public static void main(String[] args) {
        try {
            Connection connection;

            // Create a connection to a LAN-enabled VBus device
            TcpDataSource dataSource = TcpDataSourceProvider.fetchInformation(InetAddress.getByName("192.168.x.y"), 500);
            dataSource.setLivePassword("vbus");
            connection = dataSource.connectLive(0, 0x0020);

            // Establish the connection
            connection.connect();

            // Passively wait for the datagram offering transfer of the VBus master role
            Datagram dgram = connection.waitForFreeBus(10000);
            if (dgram == null) {
                throw new Error("No bus offer received");
            }

            // Remember the address of the controller
            int peerAddress = dgram.getSourceAddress();

            // Respond to that offer by reading the changeset ID (value index 0) of the controller
            dgram = connection.getValueById(peerAddress, 0x0000, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to get changeset ID");
            }

            // Remember the changeset ID and optionally forget a previously cached value-index-to-value mapping
            int changesetId = dgram.getValue();

            // Lookup a value index by its value ID hash (in this example `Relais_Regler_R1_Handbetrieb`)
            dgram = connection.getValueIdByIdHash(peerAddress, 0x2D84EA19, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to lookup value index");
            }

            // Remember that value index
            int valueIndex = dgram.getValueId();

            // Read the changeset ID again to "resynchronize"
            dgram = connection.getValueById(peerAddress, 0x0000, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to resynchronize");
            }

            // Send a request to set `Relais_Regler_R1_Handbetrieb`
            dgram = connection.setValueById(peerAddress, valueIndex, 2, false, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to set value");
            }

            // Read the changeset ID again to "resynchronize"
            dgram = connection.getValueById(peerAddress, 0x0000, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to resynchronize");
            }

            // Send a request to get `Relais_Regler_R1_Handbetrieb`
            dgram = connection.getValueById(peerAddress, valueIndex, 500, 500, 3);
            if (dgram == null) {
                throw new Error("Unable to get value");
            }

            // Do something with that value
            int value = dgram.getValue();

            // Transfer master role back to the controller
            connection.releaseBus(peerAddress, 1500, 0, 2);

            // Disconnect from the VBus
            connection.disconnect();
        } catch (Throwable ex) {
            ex.printStackTrace();
        }

    }

}
danielwippermann commented 1 year ago

I have added an updated version of that example to the repo as well.

https://github.com/danielwippermann/resol-vbus-java/commit/1fd19b76ccf45d36cfb41175b27410d8f4a1c255

Have a nice weekend, Daniel

danielwippermann commented 1 year ago

Ah, nearly forgot to answer the still open questions:

But how to transfer on/off/auto to specific relay and min/max/on/off/auto to PWM Outputs?

The following information is extracted from the MX2-Menu.xml which is part of the RPT download package for the RESOL DeltaSol MX 2.08.

Each relay has a value named Relais_<location>_R<number>_Handbetrieb. Location can be Regler, Modul1 and so on based on where the relay is located.

If you search for those values in the XML file and follow the trails of type inheritance from Relais_Vt{0}_Handbetrieb to Handbetrieb you find the following type:

    <type id='Handbetrieb'>
        <valueText id='Aus'>
            <text lang='ref'>Aus</text>
        </valueText>
        <valueText id='Min'>
            <text lang='ref'>Min{imum}</text>
        </valueText>
        <valueText id='Auto'>
            <text lang='ref'>Auto{matikbetrieb}</text>
        </valueText>
        <valueText id='Max'>
            <text lang='ref'>Max{imum}</text>
        </valueText>
        <valueText id='Ein'>
            <text lang='ref'>Ein</text>
        </valueText>
    </type>

That means values of type 'Handbetrieb' can be 0 = "Aus/Off", 1 = "Min", 2 = "Auto", 3 = "Max" and 4 = "Ein/On".

Outputs follow the same pattern. Their values are named Ausgang_<location>_A<number>_Handbetrieb and they also derive indirectly from the Handbetrieb base type, resulting in the same five possible values.

And additionally: does writing values wear out hardware cells in the MCU and reduces lifetime of the chip?

Yes, although not the MCU itself, but its external non-volatile memory chip. Each command to change the value will trigger a write to that non-volatile memory after a short delay. Constantly changing the values has the negative side-effect of wearing out the non-volatile memory cells which could eventually result in a chip that no longer is able to persist the controller's configuration and balance values.

Depending on your use case there are alternatives to using the manual mode. If you are just wanting to switch a relay which is otherwise not used by the controller configuration itself we have used a simulated extension module in the past which simply reports a certain temperature to the controller which in turn is configured to react to temperature changes from the "virtual" temperature sensor. That way you do not need to constantly change a manual mode parameter. But as I said, that solution depends on your use case...

Have a nice weekend, Daniel

Stefan8877 commented 1 year ago

Hi Daniel,

your last Comment is very interesting. I would like to manually control Relay 4 on my Deltasol BX Plus, depending on temperatures that I determine externally in my SmartHome system.

I wrote a program in FreePascal that works quite well, apart from a few small problems. But now I read that it is not good for the hardware if I change the parameter several times a day.

What other option do I have to control the relay ? How does it work with the simulated expansion ? Would that be a good possibility ?

Regards

Stefan

danielwippermann commented 12 months ago

Hi Stefan,

well, the set of possibilities differ by controller and configuration since not every controller supports extension modules and you need some kind of thermostat function to make it work.

But take your RESOL DeltaSol BX Plus for example: it supports extension modules (Main menu / Inputs&Modules / Modules) and the optional functions in the "Arrangement" section include a "Function block" which can be configured as a thermostat function. You simply start the extension module simulation, enable the respective extension module in the controller which then allows you to choose one of the simulated sensor inputs for your thermostat function to switch one of the real relais. And hence switching the simulated temperature value between 0 °C and 100 °C triggers the thermostat function without having to modify the "Manual mode" setting for the respective relay. That way your controller's non-volatile memory will not be affected.

Best regards, Daniel