slixmpp/sleekxmpp/plugins/xep_0325/device.py

125 lines
4.4 KiB
Python

"""
SleekXMPP: The Sleek XMPP Library
Implementation of xeps for Internet of Things
http://wiki.xmpp.org/web/Tech_pages/IoT_systems
Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se, bjorn.westrom@consoden.se
This file is part of SleekXMPP.
See the file LICENSE for copying permission.
"""
import datetime
class Device(object):
"""
Example implementation of a device control object.
The device object may by any custom implementation to support
specific devices, but it must implement the functions:
has_control_field
set_control_fields
"""
def __init__(self, nodeId):
self.nodeId = nodeId
self.control_fields = {}
def has_control_field(self, field, typename):
"""
Returns true if the supplied field name exists
and the type matches for control in this device.
Arguments:
field -- The field name
typename -- The expected type
"""
if field in self.control_fields and self.control_fields[field]["type"] == typename:
return True
return False
def set_control_fields(self, fields, session, callback):
"""
Starts a control setting procedure. Verifies the fields,
sets the data and (if needed) and calls the callback.
Arguments:
fields -- List of control fields in tuple format:
(name, typename, value)
session -- Session id, only used in the callback as identifier
callback -- Callback function to call when control set is complete.
The callback function must support the following arguments:
session -- Session id, as supplied in the
request_fields call
nodeId -- Identifier for this device
result -- The current result status of the readout.
Valid values are:
"error" - Set fields failed.
"ok" - All fields were set.
error_field -- [optional] Only applies when result == "error"
The field name that failed
(usually means it is missing)
error_msg -- [optional] Only applies when result == "error".
Error details when a request failed.
"""
if len(fields) > 0:
# Check availiability
for name, typename, value in fields:
if not self.has_control_field(name, typename):
self._send_control_reject(session, name, "NotFound", callback)
return False
for name, typename, value in fields:
self._set_field_value(name, value)
callback(session, result="ok", nodeId=self.nodeId)
return True
def _send_control_reject(self, session, field, message, callback):
"""
Sends a reject to the caller
Arguments:
session -- Session id, see definition in
set_control_fields function
callback -- Callback function, see definition in
set_control_fields function
"""
callback(session, result="error", nodeId=self.nodeId, error_field=field, error_msg=message)
def _add_control_field(self, name, typename, value):
"""
Adds a control field to the device
Arguments:
name -- Name of the field
typename -- Type of the field, one of:
(boolean, color, string, date, dateTime,
double, duration, int, long, time)
value -- Field value
"""
self.control_fields[name] = {"type": typename, "value": value}
def _set_field_value(self, name, value):
"""
Set the value of a control field
Arguments:
name -- Name of the field
value -- New value for the field
"""
if name in self.control_fields:
self.control_fields[name]["value"] = value
def _get_field_value(self, name):
"""
Get the value of a control field. Only used for unit testing.
Arguments:
name -- Name of the field
"""
if name in self.control_fields:
return self.control_fields[name]["value"]
return None