ctrlX Data Layer API for Python  3.3.0
The ctrlX Data Layer API allows access to the ctrlX Data Layer with Python
metadata_utils.py
1 """
2  This module provides helper classes to deal with metadata flatbuffers.
3 """
4 from enum import IntEnum
5 
6 import flatbuffers
7 from comm.datalayer import (AllowedOperations, DisplayFormat, Extension, Metadata, NodeClass, Reference, LocaleText)
8 
9 from ctrlxdatalayer.variant import Variant
10 
11 
12 class ReferenceType:
13  """ List of reference types as strings. """
14 
15  @classmethod
16  def read(cls):
17  """ Type when reading a value (absolute node address). """
18  return "readType"
19 
20  @classmethod
21  def read_in(cls):
22  """ Input type when reading a value. """
23  return "readInType"
24 
25  @classmethod
26  def read_out(cls):
27  """ Output type when reading a value. """
28  return "readOutType"
29 
30  @classmethod
31  def write(cls):
32  """ Type when writing a value (absolute node address). Input/Output type are the same. """
33  return "writeType"
34 
35  @classmethod
36  def write_in(cls):
37  """ Input type when writing a value. """
38  return "writeInType"
39 
40  @classmethod
41  def write_out(cls):
42  """ Output type when writing a value. """
43  return "writeOutType"
44 
45  @classmethod
46  def create(cls):
47  """ Type when creating a value (absolute node address). """
48  return "createType"
49 
50  @classmethod
51  def uses(cls):
52  """ Referenced (list of) absolute node addresses. """
53  return "uses"
54 
55  @classmethod
56  def has_save(cls):
57  """
58  Reference to a save node address which needs to be called after
59  node change to persist the new value (must be <technology>/admin/cfg/save).
60  """
61  return "hasSave"
62 
63 
64 class AllowedOperation(IntEnum):
65  """
66  Allowed Operation Flags
67  """
68  NONE = 0x00000
69  READ = 0x00001
70  WRITE = 0x00010
71  CREATE = 0x00100
72  DELETE = 0x01000
73  BROWSE = 0x10000
74  ALL = READ | WRITE | CREATE | DELETE | BROWSE
75 
76 
77 class MetadataBuilder:
78  """ Builds a flatbuffer provided with the metadata information for a Data Layer node. """
79 
80  @staticmethod
81  def create_metadata(name: str, description: str, unit: str, description_url: str, node_class: NodeClass,
82  read_allowed: bool, write_allowed: bool, create_allowed: bool, delete_allowed: bool,
83  browse_allowed: bool, type_path: str, references: dict = None) -> Variant:
84  """
85  Creates a metadata Variant object from the given arguments.
86  `type_path` is used in conjunction with the allowed operations of the object.
87  `references` allow the user to set own references in the metadata object. Set `type_path` to ""
88  for full control over references.
89 
90  Returns:
91  Variant: Metadata
92  """
93  if references is None:
94  references = {}
95  builder = MetadataBuilder(allowed=AllowedOperation.NONE, description=description,
96  description_url=description_url)
97  allowed = AllowedOperation.NONE
98  if read_allowed:
99  allowed = allowed | AllowedOperation.READ
100  if len(type_path) != 0:
101  builder.add_reference(ReferenceType.read(), type_path)
102  if write_allowed:
103  allowed = allowed | AllowedOperation.WRITE
104  if len(type_path) != 0:
105  builder.add_reference(ReferenceType.write(), type_path)
106  if create_allowed:
107  allowed = allowed | AllowedOperation.CREATE
108  if len(type_path) != 0:
109  builder.add_reference(ReferenceType.create(), type_path)
110  if delete_allowed:
111  allowed = allowed | AllowedOperation.DELETE
112  if browse_allowed:
113  allowed = allowed | AllowedOperation.BROWSE
114 
115  builder.set_operations(allowed)
116  builder.set_display_name(name)
117  builder.set_node_class(node_class)
118  builder.set_unit(unit)
119 
120  # Add the custom references
121  for key, val in references.items():
122  builder.add_reference(key, val)
123 
124  return builder.build()
125 
126  def __init__(self, allowed: AllowedOperation = AllowedOperation.BROWSE, description: str = "",
127  description_url: str = ""):
128  """
129  generate MetadataBuilder
130  """
131  self.__name__name = ""
132  self.__description__description = description
133  self.__description_url__description_url = description_url
134  self.__unit__unit = ""
135  self.__node_class__node_class = NodeClass.NodeClass.Node
136  self.__allowed__allowed = AllowedOperation.ALL
137  self.__displayformat__displayformat = DisplayFormat.DisplayFormat.Auto
138  self.set_operationsset_operations(allowed)
139  self.__references__references = dict([])
140  self.__extensions__extensions = dict([])
141  self.__descriptions__descriptions = dict([])
142  self.__displaynames__displaynames = dict([])
143 
144  def build(self) -> Variant:
145  """Build Metadata as Variant
146 
147  Returns:
148  Variant: Metadata
149  """
150  # print(version("flatbuffers"))
151  return self.__buildV2__buildV2()
152 
153  def __buildV2(self) -> Variant:
154  """
155  build function flatbuffers 2.x
156  """
157  builder = flatbuffers.Builder(1024)
158 
159  # Serialize AllowedOperations data
160  operations = self.__build_operations__build_operations()
161 
162  references = self.__build_references__build_references()
163 
164  extensions = self.__build_extensions__build_extensions()
165 
166  descriptions = self.__build_descriptions__build_descriptions()
167 
168  displaynames = self.__build_display_names__build_display_names()
169 
170  meta = Metadata.MetadataT()
171  meta.description = self.__description__description
172  meta.descriptionUrl = self.__description_url__description_url
173  meta.displayName = self.__name__name
174  meta.unit = self.__unit__unit
175  meta.displayFormat = self.__displayformat__displayformat
176 
177  meta.nodeClass = self.__node_class__node_class
178  meta.operations = operations
179  meta.references = references
180  meta.extensions = extensions
181  meta.descriptions = descriptions
182  meta.displayNames = displaynames
183  # Prepare strings
184 
185  metadata_internal = meta.Pack(builder)
186 
187  # Closing operation
188  builder.Finish(metadata_internal)
189 
190  metadata = Variant()
191  metadata.set_flatbuffers(builder.Output())
192  return metadata
193 
194  def set_unit(self, unit: str):
195  """
196  set the unit
197  """
198  self.__unit__unit = unit
199  return self
200 
201  def set_display_name(self, name: str):
202  """
203  set the display name
204  """
205  self.__name__name = name
206  return self
207 
208  def set_node_class(self, node_class: NodeClass):
209  """
210  set the node class
211  """
212  self.__node_class__node_class = node_class
213  return self
214 
215  def set_operations(self, allowed: AllowedOperation = AllowedOperation.NONE):
216  """
217  set allowed operations
218  """
219  self.__allowed__allowed = allowed
220  return self
221 
222  def set_display_format(self, f: DisplayFormat.DisplayFormat.Auto):
223  """
224  set display format
225  """
226  self.__displayformat__displayformat = f
227  return self
228 
229  def add_reference(self, t: ReferenceType, addr: str):
230  """
231  add reference
232  """
233  self.__references__references[t] = addr
234 
235  def add_extensions(self, key: str, val: str):
236  """
237  add extension
238  """
239  self.__extensions__extensions[key] = val
240 
241  def add_localization_description(self, ident: str, txt: str):
242  """
243  add localization of descriptions
244  """
245  self.__descriptions__descriptions[ident] = txt
246 
247  def add_localization_display_name(self, ident: str, txt: str):
248  """
249  add localization of display names
250  """
251  self.__displaynames__displaynames[ident] = txt
252 
253  def __is_allowed(self, allowed: AllowedOperation) -> bool:
254  return (self.__allowed__allowed & allowed) == allowed
255 
256  def __build_operations(self):
257  op = AllowedOperations.AllowedOperationsT()
258  op.read = self.__is_allowed__is_allowed(AllowedOperation.READ)
259  op.write = self.__is_allowed__is_allowed(AllowedOperation.WRITE)
260  op.create = self.__is_allowed__is_allowed(AllowedOperation.CREATE)
261  op.delete = self.__is_allowed__is_allowed(AllowedOperation.DELETE)
262  op.browse = self.__is_allowed__is_allowed(AllowedOperation.BROWSE)
263  return op
264 
265  def __add_reference(self, t: ReferenceType, addr: str):
266  ref = Reference.ReferenceT()
267  ref.type = t
268  ref.targetAddress = addr
269  return ref
270 
271  def __build_references(self):
272  refs = []
273  for key in sorted(self.__references__references):
274  addr = self.__references__references[key]
275  ref = self.__add_reference__add_reference(key, addr)
276  refs.append(ref)
277  return refs
278 
279  def __add_extension(self, key: str, val: str):
280  ex = Extension.ExtensionT()
281  ex.key = key
282  ex.value = val
283  return ex
284 
285  def __build_extensions(self):
286  exts = []
287  for key in sorted(self.__extensions__extensions):
288  val = self.__extensions__extensions[key]
289  ex = self.__add_extension__add_extension(key, val)
290  exts.append(ex)
291  return exts
292 
293  def __add_local_text(self, ident: str, txt: str):
294  lt = LocaleText.LocaleTextT()
295  lt.id = ident
296  lt.text = txt
297  return lt
298 
299  def __build_local_texts(self, lst):
300  descs = []
301  for i in sorted(lst):
302  text = lst[i]
303  ex = self.__add_local_text__add_local_text(i, text)
304  descs.append(ex)
305  return descs
306 
307  def __build_descriptions(self):
308  return self.__build_local_texts__build_local_texts(self.__descriptions__descriptions)
309 
310  def __build_display_names(self):
311  return self.__build_local_texts__build_local_texts(self.__displaynames__displaynames)
Builds a flatbuffer provided with the metadata information for a Data Layer node.
def set_unit(self, str unit)
set the unit
def set_display_format(self, DisplayFormat.DisplayFormat.Auto f)
set display format
def set_display_name(self, str name)
set the display name
def __add_reference(self, ReferenceType t, str addr)
def set_node_class(self, NodeClass node_class)
set the node class
def __add_local_text(self, str ident, str txt)
def add_extensions(self, str key, str val)
add extension
Variant build(self)
Build Metadata as Variant.
def __init__(self, AllowedOperation allowed=AllowedOperation.BROWSE, str description="", str description_url="")
generate MetadataBuilder
def __add_extension(self, str key, str val)
def add_localization_display_name(self, str ident, str txt)
add localization of display names
def set_operations(self, AllowedOperation allowed=AllowedOperation.NONE)
set allowed operations
bool __is_allowed(self, AllowedOperation allowed)
def add_reference(self, ReferenceType t, str addr)
add reference
def add_localization_description(self, str ident, str txt)
add localization of descriptions
List of reference types as strings.
def write_out(cls)
Output type when writing a value.
def read(cls)
Type when reading a value (absolute node address).
def read_out(cls)
Output type when reading a value.
def read_in(cls)
Input type when reading a value.
def write(cls)
Type when writing a value (absolute node address).
def uses(cls)
Referenced (list of) absolute node addresses.
def create(cls)
Type when creating a value (absolute node address).
def write_in(cls)
Input type when writing a value.
Variant is a container for a many types of data.
Definition: variant.py:150