summaryrefslogtreecommitdiff
path: root/sleekxmpp/plugins/xep_0325/device.py
blob: 1cb99510721d9f20637c547a6188b4ae860f4890 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""
    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;