+class SensorCalibrado(Sensor):
+
+ valorBruto = SyncProp("Valor en bruto leido del dispositivo.")
+ valorBajo = SyncProp("Valor bajo de calibrado como tupla (valorBruto, " \
+ "valorCalibrado).")
+ valorAlto = SyncProp("Valor alto de calibrado como tupla (valorBruto, " \
+ "valorCalibrado).")
+
+ def __init__(self, valorBajo, valorAlto, sigma, periodo):
+ self.valorBajo = valorBajo
+ self.valorAlto = valorAlto
+ Sensor.__init__(self, sigma, periodo)
+
+ def getValor(self):
+ "Simula la medición del dispositivo físico."
+ self.valorBruto = self.mu = Sensor.getValor(self)
+ (x1, y1) = self.valorBajo
+ (x2, y2) = self.valorAlto
+ return (y2 - y1) / (x2 - x1) * (self.mu - x1) + y1
+
+ def __repr__(self):
+ return "<%s valorActual=%s valorBruto=%f valorBajo=%s valorAlto=%s>" \
+ % (self.__class__.__name__, self, self.valorBruto, self.valorBajo,
+ self.valorAlto)
+
+
+class SensorHistorico(SensorCalibrado):
+
+ def __init__(self, valorBajo, valorAlto, sigma, periodo):
+ # Listado de los valores de las últimas 24hs (inicializado con None)
+ self.historial = [(None, None) for i in xrange(int(24 * 60 * 60 / periodo))]
+ SensorCalibrado.__init__(self, valorBajo, valorAlto, sigma, periodo)
+
+ def getValor(self):
+ "Simula la medición del dispositivo físico."
+ nuevo = SensorCalibrado.getValor(self)
+ hora = time.strftime("%c")
+ self.actualizarHistorial(nuevo, hora)
+ return nuevo
+
+ def actualizarHistorial(self, valor, hora):
+ self.historial.pop(0)
+ self.historial.append((valor, hora))
+ actualizarHistorial = synchronized('historialLock')(actualizarHistorial)
+
+ def getMin(self):
+ minimo = (None, None)
+ for (valor, hora) in self.historial:
+ if minimo[0] is None or valor <= minimo[0]:
+ minimo = (valor, hora)
+ return minimo
+ getMin = synchronized('historialLock')(getMin)
+
+ def getMax(self):
+ maximo = (None, None)
+ for (valor, hora) in self.historial:
+ if valor >= maximo[0]:
+ maximo = (valor, hora)
+ return maximo
+ getMax = synchronized('historialLock')(getMax)
+
+ valorMinimo = property(getMin, doc="Mínimo de las últimas 24hs como " \
+ "tupla (minimo, hora).")
+ valorMaximo = property(getMax, doc="Máximo de las últimas 24hs como " \
+ "tupla (maximo, hora).")
+
+
+class SensorHumedad(SensorHistorico):
+
+ def __init__(self):
+ SensorHistorico.__init__(self, (0.0, 0.0), (100.0, 100.0), 0.3, 300.0)
+
+ def initMu(self):
+ return self.rnd.gauss(70.0, 5.0)
+
+
+class SensorVelocidadViento(SensorHistorico):
+
+ def __init__(self):
+ SensorHistorico.__init__(self, (0.0, 0.0), (100.0, 100.0), 0.1, 0.5)
+
+ def initMu(self):
+ return self.rnd.gauss(30.0, 8.0)
+
+
+class SensorTendencia(SensorHistorico):
+
+ def __init__(self, cantidadTendencia, valorBajo, valorAlto, sigma, periodo):
+ """cantidadTendencia es la cantidad de valores del historial a tomar al
+ calcular la tendencia."""
+ # Listado de los valores de las últimas 24hs (inicializado con None)
+ self.cantidadTendencia = cantidadTendencia
+ SensorHistorico.__init__(self, valorBajo, valorAlto, sigma, periodo)
+
+ def getValoresTendencia(self):
+ return [
+ (x, y[0])
+ for (x, y) in enumerate(self.historial[-self.cantidadTendencia:])
+ if y[0] is not None
+ ]
+ getValoresTendencia = synchronized('historialLock')(getValoresTendencia)
+
+ def getTendencia(self):
+ def sumatoria(valores):
+ suma = 0
+ for i in valores:
+ suma += i
+ return suma
+ valores = self.getValoresTendencia()
+ suma_xy = sumatoria([x*y for (x, y) in valores])
+ suma_x = sumatoria([x for (x, y) in valores])
+ suma_y = sumatoria([y for (x, y) in valores])
+ suma_x2 = sumatoria([x**2 for (x, y) in valores])
+ n = len(valores)
+ pendiente = (n * suma_xy - suma_x * suma_y) / (n * suma_x2 - suma_x**2)
+ return math.atan(pendiente) * 2 / math.pi
+
+ tendencia = property(getTendencia, doc="Tendencia de las últimas 24hs " \
+ "(como valor de punto flotante entre 1 y -1).")
+
+
+class SensorTemperatura(SensorTendencia):
+
+ def __init__(self):
+ SensorTendencia.__init__(self, 10, (0.0, -20.0), (100.0, 80.0), 0.2, 300)
+
+ def initMu(self):
+ return self.rnd.gauss(35.0, 5.0)
+
+
+class SensorPresion(SensorTendencia):
+
+ def __init__(self):
+ SensorTendencia.__init__(self, 10, (0.0, 1000.0), (100.0, 1048.0), 1, 300)
+
+ def initMu(self):
+ return self.rnd.gauss(50.0, 5.0)
+
+