def handle_measurement(self, parent, meas):
        """
        eval a measurement value, see what actions, if any, it will trigger

        args:
            - the Action instance that is our parent
            - a Measurement instance
        returns:
            None
        """

        now = datetime.datetime.utcnow().replace(second=0, microsecond=0)
        trigger = None
        if parent.triggers:
            trigger = parent.triggers[0]

        def make_trigger():
            closed = now + datetime.timedelta(minutes=self.on_minutes)
            if parent.sleep_minutes:
                closed = closed + datetime.timedelta(
                    minutes=parent.sleep_minutes)

            opts = {
                'action_id': parent.id,
                'created': now,
                'closed': closed,
            }

            t = Trigger(**opts)
            db_session.add(t)
            db_session.commit()

        if not trigger and eval_condition(
                meas.value, " ".join(
                    ('value', self.on_condition, self.on_value))):
            oc = OutletController()
            success = oc.turn_on(self.outlet)
            if success:
                make_trigger()

                # create an action that our ActionRouter handler will recognize
                # to switch the outlet off at a future time
                data = {'outlet': {'state': 0}}
                data['outlet'].update(self.outlet)

                future_time = now + datetime.timedelta(minutes=self.on_minutes)
                sa = SingularAction(
                    utc_runtime=future_time,
                    action=json.dumps(data),
                )
                db_session.add(sa)
                db_session.commit()

            return
예제 #2
0
    def post(self):
        """Accept post data to switch outlet state to 1 (on) or 0 (off)."""

        data, errors = GenericOutletSchema().load(request.get_json())
        if errors:
            return errors, 400

        oc = OutletController()
        result = oc.switch_outlet(data)

        if result:
            return data, 200
        else:
            return {'msg': 'failed to switch outlet'}, 500
예제 #3
0
    def html_interface(self):
        """
        Return html data used by web gui to present and validate input data.
        Each element must have an ID that is like "plugin_" + attribute_name

        The MVC Controller function that handles the form must strip the
        plugin_ prefix from the id names as required.

        args:
            - none
        returns:
            str: html data
        raises:
            none
        """

        oc = OutletController()
        outlets = oc.available_outlets()
        conditions = [('lt', 'less than'), ('gt', 'greater than')]
        template = Template("""
            <div class="row">
              Outlet <select id="plugin_outlet">
                {% for o in outlets %}
                  <option value={{ o | tojson }}>{{ o['name'] }}</option>
                {% endfor %}
              </select>
            </div>

            <div class="row">
              ON Condition <select id="plugin_on_condition">
              {% for c in conditions %}
                <option value="{{ c[0] }}">{{ c[1] }}</option>
              {% endfor %}
              </select>
              ON Value <input type="text" id="plugin_on_threshold">
            </div>

            <div class="row">
              OFF Condition <select id="plugin_off_condition">
                {% for c in conditions %}
                  <option value="{{ c[0] }}">{{ c[1] }}</option>
                {% endfor %}
              </select>
              OFF Value <input type="text" id="plugin_off_threshold">
            </div>
        """)

        return template.render(outlets=outlets, conditions=conditions)
예제 #4
0
    def interface(self):
        """Return JSON descriptor of input interface."""

        oc = OutletController()
        outlets = oc.available_outlets()
        conditions = [('lt', 'less than'), ('gt', 'greater than')]
        data = [
            {'outlet': {
                'type': 'select',
                'choices': outlets,
                'required': True,
                'label': 'Outlet',
                'id': 'plugin_outlet',
                }
            },
            {'on_condition': {
                'type': 'select',
                'choices': conditions,
                'required': True,
                'label': 'On Condition',
                'id': 'plugin_on_condition',
                },
            'on_value': {
                'type': 'int',
                'required': True,
                'label': 'On Value',
                'id': 'plugin_on_value'
                }
            },
            {'off_condition': {
                'type': 'select',
                'choices': conditions,
                'required': True,
                'label': 'Off Condition',
                'id': 'plugin_off_condition',
                },
            'off_value': {
                'type': 'int',
                'required': True,
                'label': 'Off Value',
                'id': 'plugin_off_value',
                }
            }
        ]

        return json.dumps(data)
예제 #5
0
    def handle_measurement(self, parent, meas):
        """
        Eval a measurement value, see what actions, if any, it will trigger

        args:
            - the Action instance that is our parent
            - a Measurement instance
        returns:
            a dict of action details, or None
        """

        logger.debug("handling measurement {}, {}".format(parent, meas))
        now = datetime.datetime.utcnow().replace(second=0, microsecond=0)
        trigger = None
        if parent.triggers:
            trigger = parent.triggers[0]


        def make_trigger():
            opts = {
                'action_id': parent.id,
                'created': now,
            }
            if parent.sleep_minutes:
                opts['closed'] = now + datetime.timedelta(minutes=parent.sleep_minutes)

            t = Trigger(**opts)
            db_session.add(t)
            db_session.commit()


        if eval_condition(meas.value, " ".join(('value', self.on_condition, self.on_value))):
            logger.debug("turning outlet '{}' ON".format(self.outlet))
            oc = OutletController()
            result = oc.turn_on(self.outlet)
            # create a trigger only if action was successful
            if result:
                if trigger is None:
                    make_trigger()

            return

        if eval_condition(meas.value, " ".join(('value', self.off_condition, self.off_value))):
            logger.debug("turning outlet '{}' OFF".format(self.outlet))
            oc = OutletController()
            result = oc.turn_off(self.outlet)
            if result and trigger and trigger.closed == None:
                trigger.closed = now
                db_session.commit()

            return
예제 #6
0
from flask import Blueprint, request, current_app
from flask_restful import Api, Resource
from flask_jwt_extended import jwt_required

from potnanny_core.models.outlet import OutletController, Outlet
from potnanny_core.models.wireless import WirelessInterface
from potnanny_core.schemas.outlet import GenericOutletSchema, OutletSchema

bp = Blueprint('outlet_api', __name__, url_prefix='/api/1.0/outlets')
api = Api(bp)
oc = OutletController()


class OutletListApi(Resource):
    """Class to interface with Generic Power Outlets."""
    @jwt_required
    def get(self):
        """Get list of all available outlets."""

        results = oc.available_outlets()
        if not results:
            return {'msg': 'no outlets found'}, 404

        data, errors = GenericOutletSchema(many=True).load(results)
        if errors:
            return errors, 400

        return data, 200

    @jwt_required
    def post(self):