-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathproperty.py
More file actions
122 lines (94 loc) · 3.27 KB
/
property.py
File metadata and controls
122 lines (94 loc) · 3.27 KB
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
"""High-level Property base class implementation."""
from copy import deepcopy
from jsonschema import validate
from jsonschema.exceptions import ValidationError
from .errors import PropertyError
class Property:
"""A Property represents an individual state value of a thing."""
def __init__(self, thing, name, value, metadata=None):
"""
Initialize the object.
thing -- the Thing this property belongs to
name -- name of the property
value -- Value object to hold the property value
metadata -- property metadata, i.e. type, description, unit, etc.,
as a dict
"""
self.thing = thing
self.name = name
self.value = value
self.href_prefix = ''
self.href = '/properties/{}'.format(self.name)
self.metadata = metadata if metadata is not None else {}
# Add the property change observer to notify the Thing about a property
# change.
self.value.on('update', lambda _: self.thing.property_notify(self))
def validate_value(self, value):
"""
Validate new property value before setting it.
value -- New value
"""
if 'readOnly' in self.metadata and self.metadata['readOnly']:
raise PropertyError('Read-only property')
try:
validate(value, self.metadata)
except ValidationError:
raise PropertyError('Invalid property value')
def as_property_description(self):
"""
Get the property description.
Returns a dictionary describing the property.
"""
description = deepcopy(self.metadata)
if 'forms' not in description:
description['forms'] = []
# TODO: The assumption is that all properties are at least readable - but that's probably not true
op = ['readproperty']
if not self.metadata.get('readOnly'):
op.append('writeproperty')
if self.metadata.get('observable'):
op.extend(('observeproperty', 'unobserveproperty'))
description['forms'].append(
{
'op': op,
'href': self.href_prefix + self.href,
}
)
return description
def set_href_prefix(self, prefix):
"""
Set the prefix of any hrefs associated with this property.
prefix -- the prefix
"""
self.href_prefix = prefix
def get_href(self):
"""
Get the href of this property.
Returns the href.
"""
return self.href_prefix + self.href
def get_value(self):
"""
Get the current property value.
Returns the value.
"""
return self.value.get()
def set_value(self, value):
"""
Set the current value of the property.
value -- the value to set
"""
self.validate_value(value)
self.value.set(value)
def get_name(self):
"""
Get the name of this property.
Returns the name.
"""
return self.name
def get_thing(self):
"""Get the thing associated with this property."""
return self.thing
def get_metadata(self):
"""Get the metadata associated with this property."""
return self.metadata