Fundamentals of programming Smart Home objects in MajorDoMo

    image

    MajorDoMo system combines various components, the action of many of which involves reading or changing data. An object model was created to organize effective data exchange between parts of the system. This model is largely consistent with the paradigm of Object-Oriented Programming (OOP) and people familiar with this paradigm will not be difficult to understand the existing model. However, knowledge of OOP principles is not necessary at all, as the model built into the system is quite simplified and can be applied without deep knowledge of any programming language or as a first step in learning this concept. The article describes the main components of this model.

    Part 1. Theory.


    Classes

    A class is a description of the basic properties that all objects belonging to this class should possess. A class is not an object and cannot in itself contain the values ​​of these properties; it only describes the signs and behaviors of objects. A physical analogy can be represented by an example of a simple classification - for example, the “Door to the bathroom” object can belong to the “Doors” class, while the “Doors” can have a description of the “Status” property (the door is open or closed), but its immediate value be set only for a specific object, but not for a class.

    An important feature of classes is the ability to create subclasses that inherit all the properties and methods of the "parent" class, but at the same time are able to have their own properties and methods. Or having their own special implementation of the "parent" methods.

    Example:
    image

    The objects

    An object is a state of a real (or virtual) object. The properties of an object can have specific values ​​(for example, “status”, “temperature”, etc.). In addition, properties can be set in the object itself that complement the set of properties of the class to which the object belongs. Also, an object may be given its own implementation of the methods described in the class.

    Example: An
    image

    object belonging to a class, which, in turn, is a subclass, inherits the properties and methods of all parent classes.

    The properties

    A property is a specific parameter that describes the state of an object. As already mentioned above, classes can only describe properties (name, description, etc.), but the value of a property can only be set for a specific object.

    Example (description of the properties of the object class):
    image

    Example (setting / reading the properties of the object):
    setGlobal('myObject.myProperty',12345);
    $value=getGlobal('myObject.myProperty');


    Methods

    Methods are a description of the possible actions of an object (or actions on an object). Returning to the physical analogy, we can indicate that the class “Doors” can have the methods “Open” and “Close”, i.e. all objects of the class will also have this method, and we can open the door by calling the "Door to the bathroom. Open" method. The method implementation itself is a script in the PHP programming language. In this case, part of the script may be setting the “Status” property to the “Open” state.

    Example (object method):
    image

    Example (method code):
    if ($this->getProperty('status')) {
     say("Движение в гараже");
    }


    Example (method call):
    callMethod('myObject.myMethod',$params); // $params не обязательный массив параметров


    Part 2. Practice.


    In the second part of the article I will give an example of “embedding” real equipment in the MajorDoMo object system. As an example of equipment, I will use the components of the nooLite system, which has already been repeatedly presented on Habré , therefore, in general, many people know about the capabilities of these components. All the actions described below are performed in the MajorDoMo control panel in the Objects section without making any changes to the source code or system configuration files.

    So, for examples, we will use:

    • Multiple executive power modules (regular + adjustable / dimmable)
    • USB transmitter for sending signals


    Item Plan:
    1. We create abstract classes for our tasks.
    2. We create more specific classes for the supported equipment.
    3. Add objects
    4. We are managing!


    Point 1

    We will proceed from the fact that in our Smart House the task of turning on / off some equipment will often arise, therefore we will create the Relays class with the status property (1/0 - on / off) at the highest level, and same with the methods turnOff, turnOn, switch and refresh.

    TurnOff method code (device shutdown):
    $this->setProperty("status",0);


    TurnOn method code (turning on the device):
    $this->setProperty("status",1);


    Code of the switch method (device switching):
    $status=$this->getProperty("status");
    if ($status) {
     $this->callMethod('turnOff');
    } else {
     $this->callMethod('turnOn');
    }

    The code of the refresh method (device status update):
    $status=$this->getProperty("status");
    if ($status) {
     $this->callMethod('turnOn');
    } else {
     $this->callMethod('turnOff');
    }


    We assume that this is a necessary minimum that will be inherent in all managed objects.

    Point 2

    Next, we will add support for the nooLite equipment we need through the creation of a nooLite child class. To differ from the parent, it will be a specific property of the channel (executive module control channel). In addition, a new sendCommand method (sending a command) will be added and the code of the turnOff and turnOn methods will be redefined.

    Code for the new sendCommand method (sending a command to a Noolite device):
    $cmdline='"c:\Program Files\nooLite\nooLiteCMD.exe" -api '.$params['command'];
    safe_exec($cmdline);


    The code of the overridden method turnOff:
    $this->setProperty("status",0);
    $this->callMethod("sendCommand",array('command'=>'-off_ch'.$this->getProperty("channel")));


    The code of the overridden method turnOn:
    $this->setProperty("status",1);
    $this->callMethod("sendCommand",array('command'=>'-on_ch'.$this->getProperty("channel")));


    We do not touch other methods - they remain unchanged and work as expected with the new class (thanks OOP!).

    Actually, now we can add arbitrarily many objects of a given class without additional costs for programming the behavior of each of them.

    Point 3

    We add the object noo1, indicating in the description of the object that it is “Lighting the ceiling in the living room”, go to the setting of its properties and indicate the value of the property noo1.channel = 1, i.e. this power module is located on the first control channel.

    Point 4

    Now we can enable / disable this module from any scenario with the following code:
    callMethod('noo1.turnOn'); // включаем
    callMethod('noo1.turnOff'); // выключаем


    Or, you can prescribe the control of this module from the menu in the following form:
    image

    Having obtained the following control element:
    image

    We fix what we learned by going through points 2-4 to add another device - the nooLite power unit with dimming support.

    Point 2.

    From the nooLite class created above, we create a child class, nooLiteDimmer, adding an additional property brightness. We also add a new dim method and rewrite the code of the refresh, turnOn, turnOff methods.

    The code of the new dim method:
    if ($params['value']) {
     $this->setProperty("brightness",$params['value']);
     $this->callMethod("refresh");
    }


    The code of the overridden refresh method:
    $value=$this->getProperty("brightness");
    $this->callMethod("sendCommand",array('command'=>'-set_ch'.$this->getProperty("channel").' -'.$value));
    if ($value>0) {
     $this->setProperty('status',1);
    } else {
     $this->setProperty('status',0);
    }


    The code of the overridden method turnOff:
    $this->setProperty("status",0);
    $this->setProperty("brightness",0);
    $this->callMethod("refresh");


    The code of the overridden method turnOn:
    $this->setProperty("status",1);
    $this->setProperty("brightness",100);
    $this->callMethod("refresh");


    Point 3. It is

    almost similar to the previous option - add the object noo2, set the control channel in the properties (2). The object is ready.

    Point 4.

    Object noo2 can be controlled in the same way as noo1, but in addition we can use the dim method to set the brightness:
    callMethod('noo2.dim',array('value'=>50)); // устанавливаем яркость в 50%


    To control the lamp in the menu, create the following element:
    image

    The type of control for the user is already shown above in the example of controlling a conventional power unit.

    There is still such a three-channel dimmer in Nootehnika for controlling RGB-backlight:

    I will leave its integration behind the scenes (or as a “homework”, if you like), but as a result of simple manipulations like the ones described above, you can get this interface:
    image

    Instead of an afterword

    An object system is especially convenient to use when we have a number of objects of the same type (for example, sensors or actuators) that have the same properties and behaviors. At the same time, we can specify one class and add only objects that differ in names or some separate features, but at the same time have only one implementation of the behavior scenario described in the class method.

    In addition, all available modules that provide the connection of the system with specific “iron” (and not so) protocols allow you to specify the “binding” of the parameters of the supported equipment to the properties or methods of certain objects, which allows you to have the current status of all connected systems (SNMP, ZWave, 1-wire and more).

    Well, at the very end, I would like to say that it’s easiest to learn many things with examples of specific implementations, for which a special CONNECT project was launched, with which you can exchange ready-made configurations of your Smart Home. On the example of my profile, I show the components used, the configuration of the control menu, the created scripts, classes and MajorDoMo objects. The profile does not publish information about the values ​​of the properties of objects and, of course, there is no way to manage equipment - all information is provided for informational purposes only.

    Successful automation!

    Also popular now: