class Column: """ Describes a column in a table table with all available columns: _________________________________________________ | module | node | name | label | n_index | data | | | | | | | | | | | | | | | """ def __init__(self, name, origin_table=None, type="varchar"): self.name = name self.origin_table = origin_table self.type = type # the column name name = attr(str) # the table this column will be derived from when creating views # this is needed if the same column appears in two tables that are used to create a view # and the column will be present in the view origin_table = attr(object) # what type (sqlite) of data this column will hold type = attr(str) # the table this column belongs to table = ref()
class Environment: ''' This class encapsulates the specification of the environment for an NSD. Environment refers to the physical quantities sensed by the sensors in the WSN. ''' nsd = ref() type = attr(str, nullable=False) required(type) physical_measures = attr(set) # These two dicts map physical measure to index # and back pm_index = attr(dict) index_pm = attr(dict) def __init__(self): self.physical_measures = set() self.pm_index = {} self.index_pm = {} def index_physical_measures(self): i = 0 for pm in self.physical_measures: self.pm_index[pm] = i self.index_pm[i] = pm def numPhysicalProcesses(self): return len(self.physical_measures)
class NodeType: # index for nodes in this node type index = attr(slice) # the NSD node def nodeDef = attr(NodeDef) # the top-level model castalia_model = ref() # the omnetpp section where this type is configured section = attr(Section) # the node module (dummy) nodes = attr(CastaliaModule) # the communication submodule comm = attr(Communication) def __init__(self, cm, nodeDef, index): self.castalia_model = cm self.nodeDef = nodeDef self.index = index self.nodes = Node(cm.network.base(), 'node', index) self.comm = Communication(self.nodes)
class VLMapping: "Combine a physical process' index with " env = ref() pm_index = attr(int, nullable=False) sensor = attr(str) required(sensor) variable = attr(str) required(variable)
class Function: def __init__(self, name, isinline, isaggregate=False): self.name = name self.isinline = isinline self.isaggregate = isaggregate # name of function name = attr(str, nullable=False) isinline = attr(bool, nullable=False) isaggregate = attr(bool, nullable=False)
class Application: """ Models application code and parameters. """ requires = attr(list, default=[]) moduleType = attr(str) required(moduleType) parameters = attr(dict) required(parameters)
class ACEntry: '''Access control entry''' acl = ref() allow = attr(bool, nullable=False, default=True) # allow or deny role = attr(Role, nullable=False) priv = attr(Privilege, nullable=False) def __init__(self, role, priv, allow=True): self.allow = allow self.role = role self.priv = priv def matches(self, roles, priv): return priv in self.priv.implies and self.role in roles
class Sensor: """ Models a sensor device. """ pwr_consuption = attr(float) # energy consumed per reading sensor_type = attr(str) # quantity e.g. "temperature" max_sample_rate = attr(float) # samples per sec bias = attr(float) # added to value drift = attr(float) # not used currently (not used) noise_sigma = attr(float) # sigma of gaussian noise added to value resolution = attr(float) # sensed value is a multiple of this saturation = attr(float) # the max. physical value measured hysterisis = attr(float) # delay in sensor measuring change (not used) sensitivity = attr(float) # the minimum physical value measured
class User: username = attr(str, nullable=False) CheckedConstraint(LEGAL_USER_NAME)(username) password = attr(str) is_admin = attr(bool, nullable=False, default=False) def __init__(self, username, password, is_admin): self.username = username self.password = password self.is_admin = is_admin def __repr__(self): return "User(%s)" % (self.username + "[admin]" if self.is_admin else self.username)
class Named: name = attr(str, nullable=False) def __init__(self, name): self.name = name self.add_instance(self) self.implies.add(self) # An 'implies' relationship, # which is reflexive and transitive implies = refs() implied_by = refs(inv=implies) # # a <<== b means "declare that b implies a" # def __ilshift__(self, other): for p in self.implies: for q in other.implied_by: p.implied_by.add(q) return self @classmethod def add_instance(cls, obj): if not hasattr(cls, 'by_name'): cls.by_name = {} cls.by_name[obj.name] = obj def __repr__(self): return "%s(%s)" % (self.__class__.__name__, self.name)
class Operator(Expression): def __init__(self, function, operands): self.function = function self.operands = operands function = attr(Function) operands = ref_list(inv=Expression.parent)
class ConnectivityMatrix: "The Connectivity matrix from the topology simulator." plan = ref(inv=Plan.connectivityMatrix) rfSimId = attr(str) connectivity = ref_list() descend(connectivity)
class FetchField(Named): entity = ref() # the entity this belongs to fkey = attr(Field, nullable=False) # the foreign key to use def __init__(self, name, fkey, multiple=False): super().__init__(name) self.fkey = fkey self.entity = fkey.entity
class Parameters: "NSD parameters" nsd = ref() # The time reached when the simulation terminates (sec) sim_time_limit = attr(float) required(sim_time_limit) # Simulation time resolution exponent, The default is -9 (nanosec) simtime_scale = attr(int, default=-9) # CPU time limit, simulation stops when reached. The default is no limit. cpu_time_limit = attr(int, default=None) # seed to initialize RNG, or 0 to initialize it randomly random_seed = attr(int, nullable=False, default=0)
class CtpNoe(Routing): """ int maxNetFrameSize = default (0); // bytes int netDataFrameOverhead = default (10); // bytes int netBufferSize = default (32); // number of messages """ Ctp = attr(CastaliaModule) CtpForwardingEngine = attr(CastaliaModule) CtpRoutingEngine = attr(CastaliaModule) LinkEstimator = attr(CastaliaModule) DualBuffer = attr(CastaliaModule) def __init__(self, parent): super().__init__(parent, "CtpNoe") self.maxNetFrameSize = 0 self.netDataFrameOverhead = 10 self.netBufferSize = 32
class DerivedTable(Table): """ Describes a table that derives from one or more other tables """ def __init__(self, name, columns, base_tables, table_filter, groupby=None): super().__init__(name, columns) self.base_tables = base_tables self.table_filter = table_filter self.groupby = groupby #the tables from which this one derived base_tables = attr(list) #the table's filter, decides which columns/values will be left in this derived table table_filter = attr(Expression) # group-by columns groupby = attr(list)
class FunctionalBlock: blockDefId = attr(str) blockName = attr(str) blockCode = attr(str) isReprogrammable = attr(str) isConfigurable = attr(str) nature = attr(str) noInstances = attr(int) blockInstanceId = attr(int) nodeType = ref()
class CastaliaModel: ''' The top-level model, contains a ''' # omnetpp sections omnetpp = ref_list(inv=Section.castalia_model) # node types nodeTypes = refs(inv=NodeType.castalia_model) #main network definition network = attr(Network)
class ColumnExpr(Column): """ A column in a derived table, defined by an expression. """ def __init__(self, name, expression, alias=None, type="varchar", origin_table=None): super().__init__(name, origin_table, type) self.expr = expression if alias: self.alias = alias else: self.alias = name # the expression defining the column of a derived table expr = attr(Expression) # the alias for this column alias = attr(str)
class NodeDef: """ The Planning Tool's node definition. """ # some code word code = attr(str) # human-readable description = attr(str) # NODE/ROOT/NID nature = attr(str, nullable=False) required(nature) functionalBlocks = refs(inv=FunctionalBlock.nodeType) descend(functionalBlocks) name = attr(str, nullable=False) motes = refs() nsd = ref() ns_nodedef = ref() # couch entities _id = attr(str) _rev = attr(str)
class General(Section): ''' A simple model for omnetpp.ini parameters ''' # Simulation time in sec sim_time_limit = attr(float) # Simulation time resolution exponent, The default is -9 (nanosec) simtime_scale = attr(int, default=-9) # CPU time limit, simulation stops when reached. The default is no limit. cpu_time_limit = attr(int, default=None) # 11 random seeds seeds = attr(list) # The path to Castalia castalia_path = attr(str) def __init__(self, cm): super().__init__(cm, None)
class Communication(CastaliaModule): """ string MACProtocolName = default ("BypassMAC"); string RoutingProtocolName = default ("BypassRouting"); """ MACProtocolName = parameter(str) RoutingProtocolName = parameter(str) Radio = attr(Radio) MAC = attr(Mac) Routing = attr(Routing) def __init__(self, parent): super().__init__(parent, "Communication") def validate_instance(self, nodeType): """ Pass self to the validation routine of the instances, in case they want to validate something """ self.Radio.validate_instance(nodeType) self.MAC.validate_instance(nodeType) self.Routing.validate_instance(nodeType)
class Section: ''' A config section in the omnetpp.ini file ''' # the section name, or None for the general section name = attr(str, nullable=True, default=None) # the supersections (and subsections) extends = ref_list() extended_by = refs(inv=extends) # the top-level model castalia_model = ref() # module declarations for this section modules = attr(list) def __init__(self, cm, name, extends=[]): self.name = name self.castalia_model = cm self.extends = extends self.modules = []
class VectorlEnvironment(Environment): vectorl_id = attr(str, nullable=False) json_name('vectrol_id')(vectorl_id) required(vectorl_id) mapping = ref_list(inv=VLMapping.env) descend(mapping) def variable_for(self, pm): "Return vectorl variable name for a physical measure, or None" for vlm in self.mapping: if pm == vlm.sensor: return vlm.variable return None
class Node(CastaliaModule): ''' //node location is defined by five parameters below double xCoor = default (0); double yCoor = default (0); double zCoor = default (0); double phi = default (0); double theta = default (0); double startupOffset = default (0); //node startup offset (i.e. delay), in seconds double startupRandomization = default (0.05); //node startup randomisation, in seconds // Node will become active startupOffset + random(startupRandomization) // seconds after the start of simulation string ApplicationName; //the name of the implemented Application Module string MobilityManagerName = default ("NoMobilityManager"); //the name of the implemented Mobility Module ''' xCoor = parameter(float) yCoor = parameter(float) zCoor = parameter(float) ApplicationName = parameter(str) name = attr(str, nullable=False) mote = attr(Mote, nullable=False)
class IndexView(CouchView): # when key==null, the view is on doc._id key = attr(Field, nullable=True) @property def key(self): if self.__key is None: self.__key = self.design.entity.idfield return self.__key def __init__(self, name, key=None): super().__init__(name) self.__key = key def to_object(self): return {'map': gen_map_func(self.design.entity, self.key)}
class MoteType: """ Models the mote device. """ # resources ramSize = attr(float, nullable=True) # in kbytes flashSize = attr(float, nullable=True) # in kbytes flashWriteCost = attr(float, nullable=True) flashReadCost = attr(float, nullable=True) imageSize = attr(float, nullable=True) initialEnergy = attr(float, default=18720.0) baselineNodePower = attr(float, default=6.0)
class NsNodeDef: """ The NetSim library node definition. """ nodedef = ref(inv=NodeDef.ns_nodedef) app = attr(object) mote = attr(object) sensors = attr(list) routing = attr(object) mac = attr(object) radio = attr(object) # couch entities _id = attr(str) _rev = attr(str)
class ConstraintUnique(Named): ''' Declare a uniqueness constraint on a number of attributes. ''' entity = ref() fields = ref_list(inv=Field.constraints) primary_key = attr(bool, default=False) def __init__(self, name, entity, keys, primary_key=False): super().__init__(name) self.entity = entity self.primary_key = primary_key assert len(keys) > 0 for key in keys: if isinstance(key, str): key = entity.get_field(key) self.fields.append(key) def names(self): return [f.name for f in self.fields]
class Channel: "A channel is an entry to the connectivity matrix" cm = ref(inv=ConnectivityMatrix.connectivity) channelId = attr(int) required(channelId) nodeId1 = attr(int) required(nodeId1) RSSnodeId1 = attr(float) required(RSSnodeId1) TXpowerNodeId1 = attr(float) required(TXpowerNodeId1) nodeId2 = attr(int) required(nodeId2) RSSnodeId2 = attr(float) required(RSSnodeId2) TXpowerNodeId2 = attr(float) required(TXpowerNodeId2) strengthDb = attr(float) required(strengthDb)