OpenHausIO / backend

HTTP API for the OpenHaus SmartHome/IoT solution
https://docs.open-haus.io
6 stars 2 forks source link

Create a `flags` component? #490

Open mStirner opened 2 months ago

mStirner commented 2 months ago

A flag is a boolean value, which could be used in scenes/makros and other stuff. E.g. Toggle a command based on a flag.

Trigger scene "foo", flag is set to true & "power on" command is set, trigger scene "foo" again, flag is set to false & because the flag was true, the command to be send is now "power off".

Schema:

{
  "name": String,
  "value": Boolean,
  "labels": []
  ...
}
mStirner commented 2 months ago

Draft:

class.flag.js

const Joi = require("joi");
const mongodb = require("mongodb");

const Item = require("../../system/component/class.item.js");

module.exports = class Flag extends Item {

    constructor(obj) {

        super(obj);

        Object.defineProperty(this, "value", {
            set: (v) => {

                if (!(v instanceof Boolean)) {
                    throw new TypeError(`${v} must be instance of Boolean`);
                }

                if (v && this.ttl > 0) {
                    setTimeout(() => {
                        this.unset();
                    }, this.ttl);
                }

                obj.value = v;

                let { events } = Flag.scope;
                events.emit("changed", this);

                return true;

            },
            get() {
                return obj.value;
            },
            enumerable: true,
            writable: true
        });

    }

    set() {
        this.value = true;
    }

    unset() {
        this.value = false;
    }

    toggle() {
        this.value = !this.value;
    }

    static schema() {
        return Joi.object({
            _id: Joi.string().pattern(/^[0-9a-fA-F]{24}$/).default(() => {
                return String(new mongodb.ObjectId());
            }),
            name: Joi.string().required(),
            description: Joi.string().allow(null).default(null),
            ttl: Joi.number().allow(null).default(null),
            value: Joi.boolean().default(false)
        });
    }

    static validate(data) {
        return Flag.schema().validate(data);
    }

};

index.js

//const logger = require("../../system/logger").create("rooms");
//const COMMON_COMPONENT = require("../../system/component/common.js");
const COMPONENT = require("../../system/component/class.component.js");

const Flag = require("./class.flag.js");

class C_FLAGS extends COMPONENT {
    constructor() {

        // inject logger, collection and schema object
        super("flags", Flag.schema());

        this.hooks.post("add", (data, next) => {
            next(null, new Flag(data));
        });

        // export method from item class
        //this._exportItemMethod("customTestMethod");

    }
}

// create component instance
const instance = module.exports = new C_FLAGS();

// init component
// set items/build cache
instance.init((scope, ready) => {
    scope.collection.find({}).toArray((err, data) => {
        if (err) {

            // shit...
            ready(err);

        } else {

            data = data.map((obj) => {
                return new Flag(obj);
            });

            scope.items.push(...data);

            // init done
            ready(null);

        }
    });
});