Source code for coherence.upnp.core.variable

# Licensed under the MIT license
# http://opensource.org/licenses/mit-license.php

# Copyright (C) 2006 Fluendo, S.A. (www.fluendo.com).
# Copyright 2006, Frank Scholz <coherence@beebits.net>

import time

from coherence.upnp.core import utils

try:
    # FIXME:  there is some circular import,
    # service imports variable, variable imports service
    # how is this done properly?
    from coherence.upnp.core import service
except ImportError:
    from . import service

from coherence import log

import coherence.extern.louie as louie


[docs]class StateVariable(log.LogAble): logCategory = 'variable' def __init__(self, upnp_service, name, implementation, instance, send_events, data_type, allowed_values): log.LogAble.__init__(self) self.service = upnp_service self.name = name self.implementation = implementation self.instance = instance self.send_events = utils.means_true(send_events) self.never_evented = False self.data_type = data_type self.allowed_values = allowed_values if self.allowed_values is None: self.allowed_values = [] self.has_vendor_values = False self.allowed_value_range = None self.dependant_variable = None self.default_value = '' self.old_value = '' self.value = '' self.last_time_touched = None self._callbacks = [] if isinstance(self.service, service.ServiceServer): self.moderated = self.service.is_variable_moderated(name) self.updated = False
[docs] def as_tuples(self): r = [] r.append(('Name', self.name)) if self.send_events: r.append(('Evented', 'yes')) else: r.append(('Evented', 'no')) r.append(('Data Type', self.data_type)) r.append(('Default Value', self.default_value)) r.append(('Current Value', str(self.value))) if self.allowed_values is not None and \ len(self.allowed_values) > 0: r.append(('Allowed Values', ','.join(self.allowed_values))) return r
[docs] def set_default_value(self, value): self.update(value) self.default_value = self.value
[docs] def set_allowed_values(self, values): if not isinstance(values, (list, tuple)): values = [values] self.allowed_values = values
[docs] def set_allowed_value_range(self, **kwargs): self.allowed_value_range = kwargs
[docs] def get_allowed_values(self): return self.allowed_values
[docs] def set_never_evented(self, value): self.never_evented = utils.means_true(value)
[docs] def update(self, value): self.info("variable check for update %s %s %s", self.name, value, self.service) if not isinstance(self.service, service.Service): if self.name == 'ContainerUpdateIDs': old_value = self.value if self.updated: if isinstance(value, tuple): v = old_value.split(',') i = 0 while i < len(v): if v[i] == str(value[0]): del v[i:i + 2] old_value = ','.join(v) break i += 2 if len(old_value): new_value = old_value + ',' + str( value[0]) + ',' + str(value[1]) else: new_value = str(value[0]) + ',' + str(value[1]) else: if len(old_value): new_value = str(old_value) + ',' + str(value) else: new_value = str(value) else: if isinstance(value, tuple): new_value = str(value[0]) + ',' + str(value[1]) else: new_value = value else: if self.data_type == 'string': if isinstance(value, str): value = value.split(',') if (isinstance(value, tuple) or isinstance(value, set)): value = list(value) if not isinstance(value, list): value = [value] new_value = [] for v in value: if type(v) == str: v = v # .encode('utf-8') else: v = str(v) if len(self.allowed_values): if self.has_vendor_values: new_value.append(v) elif v.upper() in [x.upper() for x in self.allowed_values]: new_value.append(v) else: self.warning( "Variable %s update, %r value %s " "doesn't fit in %r", self.name, self.has_vendor_values, v, self.allowed_values) new_value = 'Coherence_Value_Error' else: new_value.append(v) new_value = ','.join(new_value) elif self.data_type == 'boolean': new_value = utils.generalise_boolean(value) elif self.data_type == 'bin.base64': new_value = value else: new_value = int(value) else: if self.data_type == 'string': if type(value) != str: value = str(value) if len(self.allowed_values): if self.has_vendor_values: new_value = value elif value.upper() in [v.upper() for v in self.allowed_values]: new_value = value else: self.warning( "Variable %s NOT updated, value %s doesn't fit", self.name, value) new_value = 'Coherence_Value_Error' else: new_value = value elif self.data_type == 'boolean': new_value = utils.generalise_boolean(value) elif self.data_type == 'bin.base64': new_value = value else: try: new_value = int(value) except ValueError: new_value = 'Coherence_Value_Error' if new_value == 'Coherence_Value_Error': return if new_value == self.value: self.info("variable NOT updated, no value change %s %s", self.name, self.value) return self.old_value = self.value self.value = new_value self.last_time_touched = time.time() # print("UPDATED %s %r %r %r %r %r" % ( # self.name, self.service, # isinstance(self.service, service.Service), # self.instance, self.value, self._callbacks)) self.notify() if isinstance(self.service, service.Service): # self.notify() pass else: self.updated = True if self.service.last_change is not None: self.service.last_change.updated = True self.info("variable updated %s %s", self.name, self.value)
[docs] def subscribe(self, callback): self._callbacks.append(callback) callback(self)
[docs] def notify(self): if self.name.startswith('A_ARG_TYPE_'): return self.info("Variable %s sends notify about new value >%r<", self.name, self.value) # if self.old_value == '': # return louie.send( signal='Coherence.UPnP.StateVariable.%s.changed' % self.name, sender=self.service, variable=self) louie.send( signal='Coherence.UPnP.StateVariable.changed', sender=self.service, variable=self) # print("CALLBACKS %s %r %r" % ( # self.name, self.instance, self._callbacks)) for callback in self._callbacks: callback(self)
def __repr__(self): return "Variable: %s, %s, %d, %s, %s, %s, %s, %s, %s, %s" % \ (self.name, str(self.service), self.instance, self.implementation, self.data_type, str(self.allowed_values), str(self.default_value), str(self.old_value), str(self.value), str(self.send_events))