Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run actions #53

Closed
spicchio72 opened this issue Dec 8, 2021 · 6 comments
Closed

Run actions #53

spicchio72 opened this issue Dec 8, 2021 · 6 comments
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed

Comments

@spicchio72
Copy link

Is there any way to execute actions on devices? I succesfully integrated some read states for the Mi Smart Air Fryer (careli.fryer.maf02). This machine though has actions (AIID) to run a cooking and I can't understand how and if I can use them.

@Pittini
Copy link
Owner

Pittini commented Dec 8, 2021

and I can't understand how and if I can use them.

Welcome in the club. As there is no good documentation in node-mihome and the Dev don't answers to issues, pr's or questions, i see no way to implement actions. So, at last, its not an issue here, rather then node-mihome direct.

@spicchio72
Copy link
Author

I understand. I've also tried the Homebridge adapter for iobroker togheter with the homebridge-miot plugin. It recognizes without any configuration both the device and actions available (shows information in the log file) and tells it's ready to be controlled, but since I discovered that this plugin doesen't create any datapoint it's useless for iobroker.

@spicchio72
Copy link
Author

Just some notes to help other people that are looking for a way to run actions from Iobroker with the Pittini's nodemihome script, and until someone else will find out how to extend the node-mihome module for actions:

Actions need the MI Cloud support and can't be run on local LAN with the miio protocol. The only way that I found to run an action from iobroker is through a CLI python script that has the Mi cloud protocol support for actions:

https://github.com/Yonsm/MiService

I've been able in this way to configure and run all the actions present in the Mi Smart Air Fryer.

Immagine2

Steps:

  1. Install the python module by running this command from a shell:
    pip3 install miservice

  2. In Pittini's script create the commons for your actions in the DefineDevice[x] by following normal rules like you would when setting a PIID but keep them write only and set the type to boolean (to control actions through a pushbutton later in vis).
    example:

    { name: "air-fryer.start-cook", type: "boolean", read: false, write: true, min: false, max: true}]

  3. Create a setter for each common related to an action in this way:

     "air-fryer.start-cook": function () { exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"406614713","siid":2,"aiid":1,"in":[]}'", function (error, stdout, stderr) {
    		    console.log(stdout);
    		});
  1. Find out the did for your device, the AIID (action ID) and SIID (service ID) to be included in this call. To find them I used the https://home.miot-spec.com website. The "in" parameter passed in the call are extra options for this action and might be an empty array or include values from other PIIDs (parameter IDs) present in the same SIID.

Immagine

Next an example of a setter to start cooking that shows how those extra parameters have been used.

    "custom.start-custom-cook": function (){ exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"406614713","siid":3,"aiid":1,"in":["",2,40,0,0,0]}'", function (error, stdout, stderr) {
    		console.log(stdout);
		});

In short, the action 'start-custom-cook', or Action ID 1 (AIID 1) for Service ID 3 (SIID 3) has as 'in' parameter an array of values defined by the values of the indicated PIIDs. The 'in' value will be then an array of parameters like this: ["", 2, 40, 0, 0, 0]

  1. Now you can connect this action to a button is VIS or execute it from a script to start the cooking.

The downside of this simple method to run actions is that the function setDevices() in Pittini's script will be executed at the same time. Since it won't run anything useful it doesen't create problems, but Pittini himself has surely better skills than me to eventually modify the script and include the execution of actions in this way without affecting the normal behaviour of the setDevice() function.

@Pittini Pittini pinned this issue Dec 14, 2021
@Pittini Pittini self-assigned this Dec 14, 2021
@Pittini Pittini added documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed labels Dec 14, 2021
@spicchio72
Copy link
Author

spicchio72 commented Dec 14, 2021

Next the device definition for the careli.fryer.maf02 (modify <your_did> with the DID for your device and <your_parameters> with the parameters you like as options for the action:

DefineDevice[1] = { // Tested and working
    info: {},
    model: "careli.fryer.maf02",// https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:air-fryer:0000A0A4:careli-maf02:1
    description: "Xiaomi Air Fryer",
    setter: {
        "air-fryer.target-time": async function (obj, val) { await device[obj].setTargetTime(val) },
        "air-fryer.target-temperature": async function (obj, val) { await device[obj].setTargetTemperature(val) },
        "air-fryer.start-cook": function () { exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"<your_did>","siid":2,"aiid":1,"in":[]}'", function (error, stdout, stderr) {
    		    console.log(stdout);
    		});
         },
        "air-fryer.cancel-cooking": function () { exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"<your_did>","siid":2,"aiid":2,"in":[]}'", function (error, stdout, stderr) {
    		    console.log(stdout);
    		});
         },
        "air-fryer.pause": function () { exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"<your_did>","siid":2,"aiid":3,"in":[]}'", function (error, stdout, stderr) {
    	    	    console.log(stdout);
    		});
         },
        "custom.start-custom-cook": function (){ exec("export MI_USER=username && export MI_PASS=password && micli.py action '{"did":"<your_did>","siid":3,"aiid":1,"in":[<your_parameters>]}'", function (error, stdout, stderr) {
        	   console.log(stdout);
    		});
        }
    },
    common:
        [{ name: "air-fryer.status", type: "number", read: true, write: false, min: 0, max: 9, states: { 0: "Shutdown", 1: "Standby", 2: "Pause", 3: "Appointment", 4: "Cooking", 5: "Preheat", 6: "Cooked", 7: "Preheat Finish", 8: "Preheat Pause", 9: "Pause2" }},
         { name: "air-fryer.target-time", type: "number", read: true, write: true, min: 1, max: 1440, unit: "min" },
         { name: "air-fryer.target-temperature", type: "number", read: true, write: true, min: 40, max: 200, unit: "°C." },
         { name: "air-fryer.left-time", type: "number", read: true, write: false, min: 0, max: 1440, unit: "min"},
         { name: "air-fryer.start-cook", type: "boolean", read: false, write: true, min: false, max: true},
         { name: "air-fryer.cancel-cooking", type: "boolean", read: false, write: true, min: false, max: true},
         { name: "air-fryer.pause", type: "boolean", read: false, write: true, min: false, max: true},
         { name: "custom.recipe-id", type: "string", read: true, write: false},
         { name: "custom.appoint-time", type: "number", read: true, write: false, min: 0, max: 1440, unit: "min"},
         { name: "custom.food-quanty", type: "number", read: true, write: false, min: 0, max: 4, states: {0: "Null", 1: "Single", 2: "Double", 3: "Half", 4: "Full"}},
         { name: "custom.preheat-switch", type: "number", read: true, write: true, min: 0, max: 2, states: { 0: "Null", 1: "On", 2: "Off"}},
         { name: "custom.appoint-time-left", type: "number", read: false, write: false, min: 0, max: 1440, unit: "min"},
         { name: "custom.turn-pot", type: "number", read: true, write: true, min: 0, max: 2, states: { 0: "Not Turn Pot", 1: "Switch Off", 2: "Turn Pot"}},
         { name: "custom.start-custom-cook", type: "boolean", read: false, write: true, min: false, max: true}]
};

@spicchio72
Copy link
Author

and the content for the device file that has to be added to /node-mihome/lib/devices folder (rename it as careli.fryer.maf02.js):

careli.fryer.maf02.js.txt

@Pittini
Copy link
Owner

Pittini commented Dec 22, 2021

Really great work.
But I do not integrate this in the script, because its very special, needs a separate installation and so on. But I have pinned this, so if somebody needs it, he can find it. Tnx for your time and work.

@Pittini Pittini closed this as completed Dec 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants