Send HTTP request using a button

Here is a customized plugin code that you can try out - the descriptions in the code are in French.
This code was created with the help of artificial intelligence - maybe that will help you. But as already mentioned, it’s best to use the Vera plugin.
No guarantee that it will work.

plugin.Name = "VeraRequests";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = 60; // Interrogation toutes les 60 secondes
plugin.DefaultSettings = { "VeraHost": "Your_Vera_IP", "VeraPort": "3480" };

var http = new HTTPClient();

var baseUrl;

function onChangeRequest(device, attribute, value) {
    if (attribute != "TemperatureRequest")
        throw "Attribut invalide";

    var temperature = getTemperature(value);
    console.log("Température actuelle pour l'appareil " + value + ": " + temperature);

    var mediaCenter = plugin.Devices["1"];
    if (mediaCenter != null) {
        mediaCenter.Attributes["CurrentTemperature"] = temperature;
    }
}

function onConnect() {
    baseUrl = "http://" + plugin.Settings["VeraHost"] + ":" + plugin.Settings["VeraPort"] + "/data_request";

    var mediaCenter = plugin.Devices["1"];
    if (mediaCenter != null) {
        mediaCenter.SupportedMediaCommands = ["TemperatureRequest"];
    }
}

function onDisconnect() {
}

function onPoll() {
    // Exemple d'appel pour plusieurs appareils lors de l'interrogation
    var devices = [227, 228, 229]; // Ajoutez ici vos numéros d'appareils
    devices.forEach(function(deviceNum) {
        var temperature = getTemperature(deviceNum);
        console.log("Température actuelle pour l'appareil " + deviceNum + ": " + temperature);

        var mediaCenter = plugin.Devices["1"];
        if (mediaCenter != null) {
            mediaCenter.Attributes["CurrentTemperature_" + deviceNum] = temperature;
        }
    });
}

function onSynchronizeDevices() {
    var mediaCenter = new Device();
    mediaCenter.Id = "1";
    mediaCenter.DisplayName = "VeraRequests";
    mediaCenter.Capabilities = ["TemperatureControl"];
    mediaCenter.Attributes = {};
    plugin.Devices[mediaCenter.Id] = mediaCenter;
}

function getTemperature(deviceNum) {
    var url = baseUrl + "?id=variableget&DeviceNum=" + deviceNum + "&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature";
    try {
        var response = http.get(url);
        console.log("Réponse de la température: " + response);
        return response;
    } catch (error) {
        console.error("Échec de la requête HTTP: " + error);
    }
}

Hello Kalle,

I had to make some minor adaptations in your code to make it work but it works!

I ended up understanding this morning that my modified ‘HTTPExample.plugin’ example was working well and that the error message I was getting was not related to the request but to the display of the response in the log.
It was necessary to write ‘console.log(response.data);’ in place of ‘console.log(response);’. Beginner’s mistake…

Here is the result obtained with your code. It’s perfect.

Now that I have the Vera’s temperature, what do you think would be the easiest way to display it on my label?
I’m not sure I know how to do it at my beginner level.

Thank you very much for your help.

You can try this PluginCode, The plugin code store the temp in the “mediaCenter.Attributes” Température.

plugin.Name = "VeraRequests";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.PollingInterval = 60; // Interrogation toutes les 60 secondes
plugin.DefaultSettings = { "VeraHost": "Your_Vera_IP", "VeraPort": "3480" };

var http = new HTTPClient();

var baseUrl;

function onChangeRequest(device, attribute, value) {
    if (attribute != "TemperatureRequest")
        throw "Attribut invalide";

    var temperature = getTemperature(value);
    console.log("Température actuelle pour l'appareil " + value + ": " + temperature);

    var mediaCenter = plugin.Devices["1"];
    if (mediaCenter != null) {
        mediaCenter.Attributes["CurrentTemperature"] = temperature;
    }
}

function onConnect() {
    baseUrl = "http://" + plugin.Settings["VeraHost"] + ":" + plugin.Settings["VeraPort"] + "/data_request";

    var mediaCenter = plugin.Devices["1"];
    if (mediaCenter != null) {
        mediaCenter.SupportedMediaCommands = ["TemperatureRequest"];
    }
}

function onDisconnect() {
}

function onPoll() {
    // Exemple d'appel pour plusieurs appareils lors de l'interrogation
    var devices = [227, 228, 229]; // Ajoutez ici vos numéros d'appareils
    devices.forEach(function(deviceNum) {
        var temperature = getTemperature(deviceNum);
        console.log("Température actuelle pour l'appareil " + deviceNum + ": " + temperature);

        var mediaCenter = plugin.Devices["1"];
        if (mediaCenter != null) {
            mediaCenter.Attributes["CurrentTemperature_" + deviceNum] = temperature;
        }
    });
}

function onSynchronizeDevices() {
    var mediaCenter = new Device();
    mediaCenter.Id = "1";
    mediaCenter.DisplayName = "VeraRequests";
    mediaCenter.Capabilities = ["TemperatureControl"];
    mediaCenter.Attributes = { "Température": {} }; // Ajouter l'attribut "Température"
    plugin.Devices[mediaCenter.Id] = mediaCenter;
}

function getTemperature(deviceNum) {
    var url = baseUrl + "?id=variableget&DeviceNum=" + deviceNum + "&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature";
    try {
        var response = http.get(url);
        console.log("Réponse de la température: " + response);
        return response;
    } catch (error) {
        console.error("Échec de la requête HTTP: " + error);
    }
}

Hello Kalle,

Sorry for my incompetence but I can’t get the plugin to work. Above all, I would like to understand the code and the definition of the attribute raises questions for me.
In the 'OnChangeRequest function you set the attribute “CurrentTemperature”
mediaCenter.Attributes[“CurrentTemperature”] = temperature;
but in the ‘OnPoll’ function you set
mediaCenter.Attributes[“CurrentTemperature_” + deviceNum] = temperature;
and finally in the ‘onSynchronizeDevices’ function you set
mediaCenter.Attributes = { “Température”: {} };

I admit to being a little lost.

Another thing about the ‘OnPoll’ function. In the device loop you write
var mediaCenter = plugin.Devices[“1”];

Shouldn’t we rather write something like

var id = 0;
devices.forEach(function(deviceNum) {
    id += 1;
    var mediaCenter = plugin.Devices[id];
    ...
    }

As an example I defined two devices this way. Is this correct?

And here is the binding definition for my text label.

Something else with ‘baseUrl’ definition in the ‘OnConnect’ function.
I clearly defined
plugin.DefaultSettings = { “VeraHost”: “192.168.xx.xx”, “VeraPort”: “3480” };

in the beginning of the plugin but
baseUrl = “http://” + plugin.Settings[“VeraHost”] + “:” + plugin.Settings[“VeraPort”] + “/data_request”;
returns
http://null:null/data_request’

Hi Max,
the code is AI generated by Bing CoPilot. The most code which I generate by AI does the job, but I had no chance to test this code.

OK, let us start from the scratch - this is now a working Plugin Code for your device 227 where the value can be displayed in a label. Can you try this code?

// Plugin VeraUI5 pour HomeRemote V 1.0
// Récupérer les données de température

plugin.Name = "VeraUI5";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.DefaultSettings = { 
    "IpAddress": "192.168.68.16",
    "Port": "3480",
    "PollingInterval": "15000"
};

var http = new HTTPClient();

function onChangeRequest(device, attribute, value) {
    // Vous pouvez ajouter du code ici pour répondre aux demandes de changement
}

function onConnect() {
    plugin.PollingInterval = parseInt(plugin.Settings["PollingInterval"], 10);
}

function onDisconnect() {
    // Vous pouvez ajouter du code ici pour répondre aux événements de déconnexion
}

function onPoll() {
    var ipAddress = plugin.Settings["IpAddress"];
    var port = plugin.Settings["Port"];
    var deviceId = 227; // ID de l'appareil

    var response = http.get("http://" + ipAddress + ":" + port + "/data_request?id=variableget&DeviceNum=" + deviceId + "&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature");
    if(response.status == 200) {
        var data;
        if(typeof response.data === 'object') {
            data = response.data;
        } else {
            data = JSON.parse(response.data);
        }
        var device = plugin.Devices[deviceId];
        device.Temperature = data;
    }
}

function onSynchronizeDevices() {
    var deviceId = 227; // ID de l'appareil
    var VeraUI5 = new Device();
    VeraUI5.Id = deviceId;
    VeraUI5.DisplayName = "Capteur de Température";
    VeraUI5.Capabilities = [];
    VeraUI5.Attributes = ["Température"];
    plugin.Devices[VeraUI5.Id] = VeraUI5;
}

Hi Kalle,

I tried your code but without success.
I think the problem is linked to the problem I talked to you about ‘baseUrl’ at the end of my last message.
In the ‘onPoll’ function, if I log ‘ipAddress’ and ‘port’ the result is
ipAddress = null
port = null
I assigned the ip address and port directly in the url and the HTTP request works fine.

But the same thing happens when we assign the temperature value in the plugin attribute.

    device.Temperature = data;
    console.log("Data = " + data);
    console.log("device.Temperature = " + device.Temperature);

returns

Data = 22.4
device.Temperature = null

So the temperature is not stored correctly in the device and this probably explains why the binding of the label text does not work.
I have tried almost everything for two days and I have the impression that this is the problem that is blocking everything.

Another weird thing for me is that the ‘onSynchronizeDevices’ function is not called when I run the simulator but that might be the normal behavior.

I haven’t understood everything yet but I have just resolved the problem of memorizing the temperature in the device. I just noticed that I had added a call to the ‘onSynchronizeDevices’ function in the ‘onConnect’ function following my previous remark. By deleting this call I recover the temperature placed in the device

Data = 22.3
device.Temperature = 22.3

On the other hand, the problem persists regarding the plugin settings (PollingInterval, port, …).

I forgot to tell you that the ‘device’ variable initialization doesn’t seem right.
I replaced

var device = plugin.Devices[deviceId];

with

var device = plugin.Devices[“1”];

because ‘deviceId’ = 227 and there is only one VeraUI5 device in the project.

With all this I finally managed to display the temperature in my label :+1:

I can finally go get some sleep…

Good to hear that you were able to solve the problem.

Hi Kalle,

It’s a lot thanks to you. Thank you very much for your assistance and advice.
I will now be able to create my own dashboard to manage the Vera’s devices.
Before closing the subject, however, I would like to clarify the problem of the plugin settings and also understand the principle of synchronization.

The documentation states

I understand but:

  • Is it really necessary to implement this function?
  • What would be the use of synchronizing the plugin?
  • Where is the control menu to start synchronization in the application and in the simulator?

If you still have a little time to give me, your experience would be valuable to me.

I think this function is the same as when you click on “Synconize Device” with the right mouse button in Devices.
But I could be wrong and it is meant to load all current data into the plugin when you start the remote control.
To summarize: The onSynchronizeDevices function ensures that a new device with certain capabilities and attributes is created and added to the plugin’s list of devices.

image

Thank you for these details.
In my case for this to work correctly the ‘onSynchronizeDevices’ function of my VeraUI5 plugin would have to ask the VeraLite in order to retrieve the new devices and to integrate them into the plugin. This is probably what should be done during the Vera plugin synchronization.
It would also be necessary to take into account any deleted devices on the VeraLite to remove them in the plugin.

Otherwise an idea about the problem with the functioning of the plugin settings?

Can you post your plugin code, so that I can test it?

I’m not sure if this also works in the UI5, but with this command you can retrieve all available devices of the Vera
http://your_vera_ip:3480/data_request?id=invoke

If you put it in your browser, you will see all vera devices

VeraUI5.plugin (5.2 KB)

The ‘invoke’ request works perfectly on the Veralite. This will be very useful to me

Hi Max,
in this code I have removed the hard coding baseURL. At the first start it has my Vera IP - you can go in the plugin settings and change it to your IP. There are also settings for the port and polling. In my case the settings work. The code has know a function to get sure the settings are setup before the onConnect.
Please try it and let me know if it works.

// Plugin VeraUI5 pour HomeRemote V 1.0
// Exemple de base pour récupérer les données de température et d'humidité de la salle de bain

plugin.Name = "VeraUI5";
plugin.OnChangeRequest = onChangeRequest;
plugin.OnConnect = onConnect;
plugin.OnDisconnect = onDisconnect;
plugin.OnPoll = onPoll;
plugin.OnSynchronizeDevices = onSynchronizeDevices;
plugin.DefaultSettings = { 
    "IpAddress": "192.168.68.16",
    "Port": "3480",
    "PollingInterval": "5000"
};

var http = new HTTPClient();
var baseUrl;

function initializeSettings() {
    console.log("initializeSettings");
    
    // Vérifier si les paramètres ont été chargés
    if (!plugin.Settings["IpAddress"] || !plugin.Settings["Port"] || !plugin.Settings["PollingInterval"]) {
        console.error("Paramètres non chargés correctement");
        return false;
    }
    
    // Initialiser les paramètres
    plugin.PollingInterval = parseInt(plugin.Settings["PollingInterval"], 10) || 5000;
    var ipAddress = plugin.Settings["IpAddress"];
    var port = plugin.Settings["Port"];
    baseUrl = "http://" + ipAddress + ":" + port + "/data_request";
    
    console.log("Paramètres initialisés avec succès");
    return true;
}

function onChangeRequest(device, attribute, value) {
}

function onConnect() {
    console.log("onConnect");
    
    // Vérifier l'initialisation des paramètres
    if (!initializeSettings()) {
        console.error("Connexion impossible car les paramètres n'ont pas été initialisés correctement");
        return;
    }
    
    console.log("PollingInterval = " + plugin.PollingInterval);
    console.log(baseUrl);
}

function onDisconnect() {
}

function onPoll() {
    console.log("onPoll");
    
    // Mise à jour de tous les appareils Vera.
    // Limité aux capteurs d'humidité et de température de la salle de bain dans cet exemple.
    var devices = [227, 228]; // La sonde Oregon Scientific THX122NR-01 a deux capteurs considérés comme deux appareils distincts dans la VeraLite
    devices.forEach(function(deviceNum, index) {
        console.log("mise à jour de l'appareil " + deviceNum);
        console.log("Récupération de la température auprès de la Vera");
        var temperature = getTemperature(deviceNum);
        console.log("Température actuelle pour l'appareil " + deviceNum + ": " + temperature);
        console.log("Récupération de l'humidité auprès de la Vera");
        var humidity = getHumidity(deviceNum);
        console.log("Humidité actuelle pour l'appareil " + deviceNum + ": " + humidity);
        console.log("Récupération du niveau de la batterie auprès de la Vera");
        var batLevel = getBatteryLevel(deviceNum);
        console.log("Niveau de la batterie actuel pour l'appareil " + deviceNum + ": " + batLevel);
        var device = plugin.Devices[index + 1]; // En supposant que les ID des appareils commencent à 1
        if (device != null) {
            device.Temperature = temperature;
            console.log("device.Temperature = " + device.Temperature);
            device.Humidity = humidity;
            console.log("device.Humidity = " + device.Humidity);
            device.BatteryLevel = batLevel;
            console.log("device.BatteryLevel = " + device.BatteryLevel);
        } else {
            console.log("device is null");
        }
    });
}

function onSynchronizeDevices() {
    console.log("onSynchronizeDevices");
    
    var VeraUI5 = new Device();
    VeraUI5.Id = "1";
    VeraUI5.DisplayName = "Capteur de Température Sdb";
    VeraUI5.Capabilities = [];
    VeraUI5.Attributes = ["Temperature","Humidity","BatteryLevel"]; 
    plugin.Devices[VeraUI5.Id] = VeraUI5;
}

function getTemperature(deviceNum) {
    var url = baseUrl + "?id=variableget&DeviceNum=" + deviceNum + "&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature";
    try {
        var response = http.get(url);
        if (response.status == 200) {
           var data;
           if (typeof response.data === 'object') {
              data = response.data;
           } else {
              data = JSON.parse(response.data);
           }
        console.log("Réponse de la requête: " + data);
        return data;
        }
    } catch (error) {
        console.error("Échec de la requête HTTP: " + error);
    }
}

function getHumidity(deviceNum) {
    var url = baseUrl + "?id=variableget&DeviceNum=" + 228 + "&serviceId=urn:micasaverde-com:serviceId:HumiditySensor1&Variable=CurrentLevel";
    try {
        var response = http.get(url);
        if (response.status == 200) {
           var data;
           if (typeof response.data === 'object') {
              data = response.data;
           } else {
              data = JSON.parse(response.data);
           }
        console.log("Réponse de la requête: " + data);
        return data;
        }
    } catch (error) {
        console.error("Échec de la requête HTTP: " + error);
    }
}

function getBatteryLevel(deviceNum) {
    var url = baseUrl + "?id=variableget&DeviceNum=" + deviceNum + "&serviceId=urn:micasaverde-com:serviceId:HaDevice1&Variable=BatteryLevel";
    try {
        var response = http.get(url);
        if (response.status == 200) {
           var data;
           if (typeof response.data === 'object') {
              data = response.data;
           } else {
              data = JSON.parse(response.data);
           }
        console.log("Réponse de la requête: " + data);
        return data;
        }
    } catch (error) {
        console.error("Échec de la requête HTTP: " + error);
    }
}

image

But the ‘invoke’ request only returns devices and not scenes.

I tried your modification but the settings still don’t work.

image

Weird thing. The plugin definition panel does not contain settings unlike yours.

Are there any settings to set in Home Remote Designer? I didn’t find anything like that.

One thing I have noticed in these code samples is that there is no call to “encodeURI()”. URL data strings that contain certain characters need to have those certain chaaracters replaced with the appropriate escape characters. You may have gotten by with not doing it for now, but eventually not encoding the URL will cause issues.

It is simple syntax:

url = encodeURI(url);

The decoding of the URL is normally automatically done be the receiving system.

I finally figured out how to declare the plugin settings.
It works fine now.

Now that I get the temperature, humidity and battery level, I will try to configure the structure of a ‘TemperatureSensor’ to display them.

I also tried to use ‘encoderURI’ but I get the error

image

Sorry David, I didn’t realize that it was you who advised me to encode the URLs.
Thanks. You are absolutely right. However, I don’t understand why the function is not defined in my project.