Beispiel #1
0
    def setUp(self):
        def humedadRelativa(x):
            return HumedadRelativa(Porcentaje(x))

        self.estadios = CicloDeVida.estadios()

        # argumentos para ensamblar los umbrales. Modificar a gusto.
        args = [[10, 30, 40, 50, 6.5, 7.5]] + [[12, 20, 40, 70, 6.0, 7.5]] * 7
        x = [10, 30, 40, 50, 6.5, 7.5]

        # armamos los umbrales para cada estadio a partir de las
        # listas de argumentos
        self.umbrales = []
        for i in range(len(self.estadios)):
            x = args[i]
            temperatura = Rango(TemperaturaEnCelsius(x[0]),
                                TemperaturaEnCelsius(x[1]))
            humedad = Rango(humedadRelativa(x[2]), humedadRelativa(x[3]))
            acidez = Rango(AcidezEnPH(x[4]), AcidezEnPH(x[5]))
            self.umbrales.append(
                UmbralOptimoDeCultivo(self.estadios[i], temperatura, humedad,
                                      acidez))

        # la lista de los nombres esperados para los estadios
        self.nombres = [
            'GERMINACION', 'DESARROLLO', 'BROTES', 'APARICION', 'FLORACION',
            'FRUTO', 'MADURACION', 'SENESCENCIA'
        ]
Beispiel #2
0
    def test_lapso_se_instancia_bien(self):
        desde = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso = Rango(desde, hasta)

        self.assertEqual(desde, lapso.desde())
        self.assertEqual(hasta, lapso.hasta())
Beispiel #3
0
    def test_pronosticoMeteorologico_se_parsea(self):
        s = ("2014-09-27 11:00:0.0\n"
             "2014-09-27 11:59:59.0\n"
             "20\n"
             "55\n"
             "60\n"
             "1010\n"
             "2014-09-27 12:00:00.0\n"
             "2014-09-27 12:59:59.0\n"
             "25\n"
             "50\n"
             "65\n"
             "1020\n")

        result = ParserPronosticoMeteorologico().parse(s)

        prediccionesEsperadas = [
            PrediccionMeteorologica(
                Rango(FechaYHora(date(2014, 9, 27), time(11, 0, 0)),
                      FechaYHora(date(2014, 9, 27), time(11, 59, 59))),
                TemperaturaEnCelsius(20), Porcentaje(55),
                HumedadRelativa(Porcentaje(60)), LuzEnLux(1010)),
            PrediccionMeteorologica(
                Rango(FechaYHora(date(2014, 9, 27), time(12, 0, 0)),
                      FechaYHora(date(2014, 9, 27), time(12, 59, 59))),
                TemperaturaEnCelsius(25), Porcentaje(50),
                HumedadRelativa(Porcentaje(65)), LuzEnLux(1020)),
        ]
        expected = PronosticoMeteorologico(prediccionesEsperadas)

        self.assertEqual(expected, result)
Beispiel #4
0
    def test_lapso_se_instancia_bien(self):
        desde = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso = Rango(desde, hasta)

        self.assertEqual(desde, lapso.desde())
        self.assertEqual(hasta, lapso.hasta())
Beispiel #5
0
    def test_lapso_contiene_fechaYHora_contenida_en_el_lapso(self):
        desde = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso = Rango(desde, hasta)

        unaFechaYHora = FechaYHora(date(2014, 9, 21), time(12, 45, 50))

        self.assertTrue(lapso.contiene(unaFechaYHora))
Beispiel #6
0
    def test_lapso_contiene_fechaYHora_contenida_en_el_lapso(self):
        desde = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso = Rango(desde, hasta)

        unaFechaYHora = FechaYHora(date(2014, 9, 21), time(12, 45, 50))

        self.assertTrue(lapso.contiene(unaFechaYHora))
Beispiel #7
0
    def test_dos_lapsos_iguales_son_iguales(self):
        desde1 = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta1 = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso1 = Rango(desde1, hasta1)

        desde2 = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta2 = FechaYHora(date(2014, 9, 22), time(10, 45, 50))
        lapso2 = Rango(desde2, hasta2)

        self.assertTrue(lapso1 == lapso2)
    def test_prediccion_se_construye_correctamente(self):
        desde = FechaYHora(date(2014, 9, 20), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 20), time(13, 45, 50))
        prediccion = PrediccionMeteorologica(Rango(desde, hasta),
                                             TemperaturaEnCelsius(25),
                                             Porcentaje(40),
                                             HumedadRelativa(Porcentaje(10)),
                                             LuzEnLux(800))

        self.assertEqual(Rango(desde, hasta), prediccion.lapso())
        self.assertEqual(TemperaturaEnCelsius(25), prediccion.temperatura())
        self.assertEqual(Porcentaje(40), prediccion.probabilidadDeLluvia())
        self.assertEqual(HumedadRelativa(Porcentaje(10)), prediccion.humedad())
        self.assertEqual(LuzEnLux(800), prediccion.luzAmbiente())
    def setUp(self):
        self.desdeLapso1 = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        self.hastaLapso1 = FechaYHora(date(2014, 9, 21), time(13, 45, 50))
        self.desdeLapso2 = FechaYHora(date(2014, 9, 20), time(10, 45, 50))
        self.hastaLapso2 = FechaYHora(date(2014, 9, 20), time(13, 45, 50))

        self.prediccion1 = PrediccionMeteorologica(
            Rango(self.desdeLapso1, self.hastaLapso1),
            TemperaturaEnCelsius(20), Porcentaje(80),
            HumedadRelativa(Porcentaje(50)), LuzEnLux(1000))
        self.prediccion2 = PrediccionMeteorologica(
            Rango(self.desdeLapso2, self.hastaLapso2),
            TemperaturaEnCelsius(25), Porcentaje(40),
            HumedadRelativa(Porcentaje(10)), LuzEnLux(800))
Beispiel #10
0
    def parse(self, unaCadena):
        # El formato es:
        # desdeLapso
        # hastaLapso
        # temp
        # lluvia
        # humedad
        # luz
        # desdeLapso
        # ...
        predicciones = []

        datosSerializados = unaCadena.split("\n")
        for i in range(0, len(datosSerializados) - 1, 6):
            desde = CadenaAFechaYHora().parse(datosSerializados[i])
            hasta = CadenaAFechaYHora().parse(datosSerializados[i + 1])
            temp = TemperaturaEnCelsius(CadenaANumero().parse(
                datosSerializados[i + 2]))
            lluvia = CadenaAPorcentaje().parse(datosSerializados[i + 3])
            humedad = HumedadRelativa(CadenaAPorcentaje().parse(
                datosSerializados[i + 4]))
            luz = LuzEnLux(CadenaANumero().parse(datosSerializados[i + 5]))

            predicciones.append(
                icherry.central_meteorologica.PrediccionMeteorologica(
                    Rango(desde, hasta), temp, lluvia, humedad, luz))

        return icherry.central_meteorologica.PronosticoMeteorologico(
            predicciones)
Beispiel #11
0
    def generar(self):
        ahora = self._ahora()

        programa = ProgramaDeSuministro(
            Rango(ahora, ahora.agregarDuracion(DuracionEnHoras(24))))

        # regar 100 mililitros una vez por hora
        for i in range(24):
            programa.programarAccion(self._shift(DuracionEnHoras(i), ahora),
                                     AccionRegado(LiquidoEnMililitros(100)))

        # poner la lámpara a 800 lux a las 5:15  y en 1000 lux a las 10:15
        programa.programarAccion(
            self._shift(DuracionEnMinutos(60 * 5 + 15), ahora),
            AccionLuz(LuzEnLux(800)))
        programa.programarAccion(
            self._shift(DuracionEnMinutos(60 * 10 + 15), ahora),
            AccionLuz(LuzEnLux(1000)))

        # aplicar fertilizante a cada 4 horas
        for i in range(6):
            programa.programarAccion(
                self._shift(DuracionEnMinutos(60 * i * 4 + 25), ahora),
                AccionFertilizante(LiquidoEnMililitros(50)))

        # aplicar antibiótico a las 12
        programa.programarAccion(self._shift(DuracionEnHoras(12), ahora),
                                 AccionAntibiotico(LiquidoEnMililitros(10)))

        self._programaDeSuministro.copiar(programa)
        self._programaDeSuministro.notificarObservers()
Beispiel #12
0
    def test_rango_interseccion(self):
        # Este test está basado en la idea de un grafo de intervalos
        # (cada vértice representa un intervalo, dos vertices son
        # adyacentes si y sólo si los intervalos respectivos se
        # intersecan).

        #     0--1--2--3--4--5--6--7--8--9
        # r1        |--------|
        # r2     |-----|
        # r3              |--------|
        # r4  |-----------------------|
        # r5                    |--------|
        #
        # dibujito del grafo:
        #
        # r1------------r3
        # | -\       /- |
        # |   -\   /-   |
        # |     -\/     |
        # |      r4-----r5
        # |   /--
        # | /-
        # r2

        # Armamos el grafo y verificamos todas las combinaciones
        # posibles de cada par de vértices. Esto hace un test
        # exhaustivo de todo el grafo (verifica tanto los pares
        # adyacentes como los no adyacentes).
        r1, r2, r3, r4, r5 = Rango(2, 5), Rango(1, 3), Rango(4, 7), Rango(0, 8), Rango(6, 9)
        vertices = {r1, r2, r3, r4, r5}
        r1.__ady = {r2, r3, r4}
        r2.__ady = {r1, r4}
        r3.__ady = {r1, r4, r5}
        r4.__ady = {r1, r2, r3, r5}
        r5.__ady = {r3, r4}
        for v in vertices:
            self.chk_eje(v, v)  # reflexividad
            for w in v.__ady:   # adyacencia dirigida
                self.chk_eje(v, w)
            for w in ((vertices - v.__ady) - {v}):  # no-adyacencia dirigida
                self.chk_no_eje(v, w)
Beispiel #13
0
    def test_acciones_removidas(self):
        # en este test verificamos que las acciones sean correctamente
        # removidas del programa de suministro. Vamos a usar cualquier
        # fruta como los datos del programa de suministro porque no
        # interesa ya demasiado el tema de las fechas y hora (eso ya
        # lo probamos antes).
        p = ProgramaDeSuministro(Rango(1, 10))
        for i in range(1, 7):
            p.programarAccion(i, str(i))

        # pequeño sanity check antes de empezar
        self.assertEqual(set(p.accionesEnHorario(p.lapso())),
                         {'1', '2', '3', '4', '5', '6'})

        def chk_remove(rango, accionesRemovidas, accionesRestantes):
            """verifica que dado un rango, el programa de suministro encuentre las
            acciones removidas, las remueva y finalmente se quede sólo
            con las acciones finales (ambos argumentos son
            conjuntos)

            """
            self.assertEqual(set(p.retirarAccionesEnHorario(rango)),
                             accionesRemovidas)

            self.assertEqual(
                set([aP.accion() for aP in p.accionesProgramadas()]),
                accionesRestantes)

        # removemos '3' y '4'
        chk_remove(Rango(3, 4), {'3', '4'}, {'1', '2', '5', '6'})

        # removemos '6,'
        chk_remove(Rango(5.5, 100), {'6'}, {'1', '2', '5'})

        # removemos '1' y '2,'
        chk_remove(Rango(-10, 2.8), {'1', '2'}, {'5'})

        # removemos '5', queda vacío
        chk_remove(Rango(-10, 10), {'5'}, set())
    def test_central_meteorologica_devuelve_pronostico(self):
        desde = FechaYHora(date(2014, 9, 21), time(10, 45, 50))
        hasta = FechaYHora(date(2014, 9, 21), time(12, 45, 50))
        predictor = PredictorMeteorologicoMock(TemperaturaEnCelsius(25),
                                               Porcentaje(40),
                                               HumedadRelativa(Porcentaje(10)),
                                               LuzEnLux(800))

        central = CentralMeteorologica(predictor, None)

        self.assertIsNone(central.ultimoPronostico())

        pronostico = central.obtenerPronostico(desdeFechaYHora=desde,
                                               cantidadDeHs=2)

        self.assertEqual(desde, pronostico.fechaInicio())
        self.assertEqual(hasta, pronostico.fechaFin())

        prediccion1 = pronostico.prediccionPara(
            FechaYHora(date(2014, 9, 21), time(11, 40, 50)))
        self.assertEqual(
            Rango(desde, desde.agregarDuracion(DuracionEnHoras(1))),
            prediccion1.lapso())
        self.assertEqual(TemperaturaEnCelsius(25), prediccion1.temperatura())
        self.assertEqual(Porcentaje(40), prediccion1.probabilidadDeLluvia())
        self.assertEqual(HumedadRelativa(Porcentaje(10)),
                         prediccion1.humedad())
        self.assertEqual(LuzEnLux(800), prediccion1.luzAmbiente())

        prediccion2 = pronostico.prediccionPara(
            FechaYHora(date(2014, 9, 21), time(12, 40, 50)))
        self.assertEqual(
            Rango(desde.agregarDuracion(DuracionEnHoras(1)), hasta),
            prediccion2.lapso())
        self.assertEqual(TemperaturaEnCelsius(25), prediccion2.temperatura())
        self.assertEqual(Porcentaje(40), prediccion2.probabilidadDeLluvia())
        self.assertEqual(HumedadRelativa(Porcentaje(10)),
                         prediccion2.humedad())
        self.assertEqual(LuzEnLux(800), prediccion2.luzAmbiente())
Beispiel #15
0
    def obtenerPronostico(self, desdeFechaYHora, cantidadDeHs):
        predicciones = []
        desde = desdeFechaYHora

        for i in range(cantidadDeHs):
            hasta = desde.agregarHoras(1)
            predicciones.append(
                self.__predictorMeteorologico.prediccionPara(
                    Rango(desde, hasta)))
            desde = desde.agregarHoras(1)

        self.__ultimoPronostico = PronosticoMeteorologico(predicciones)
        self.notificarObservers()
        return self.__ultimoPronostico
    def planificarAcciones(self, fechaYHora):
        """Ejecuta todas las acciones del programa de suministro que recaigan
        en el lapso que comienza en la fechaYHora parámetro y dura
        tanto como se haya especificado en la duración de
        planificación (i.e. el lapso [f,f+δ] donde 'δ' es la duración
        y 'f' el parámetro fechaYHora). Todas estas acciones son
        retiradas del programa de suministro.

        """
        desde = fechaYHora
        hasta = fechaYHora.agregarDuracion(self._duracionDePlanificacion)
        lapso = Rango(desde, hasta)
        accionesAEjecutar = self._programaDeSuministro.retirarAccionesEnHorario(
            lapso)
        for accion in accionesAEjecutar:
            self._ejecutor.ejecutarAccion(accion)
        self._programaDeSuministro.notificarObservers()
Beispiel #17
0
    def test_rango_interseccion(self):
        # Este test está basado en la idea de un grafo de intervalos
        # (cada vértice representa un intervalo, dos vertices son
        # adyacentes si y sólo si los intervalos respectivos se
        # intersecan).

        #     0--1--2--3--4--5--6--7--8--9
        # r1        |--------|
        # r2     |-----|
        # r3              |--------|
        # r4  |-----------------------|
        # r5                    |--------|
        #
        # dibujito del grafo:
        #
        # r1------------r3
        # | -\       /- |
        # |   -\   /-   |
        # |     -\/     |
        # |      r4-----r5
        # |   /--
        # | /-
        # r2

        # Armamos el grafo y verificamos todas las combinaciones
        # posibles de cada par de vértices. Esto hace un test
        # exhaustivo de todo el grafo (verifica tanto los pares
        # adyacentes como los no adyacentes).
        r1, r2, r3, r4, r5 = Rango(2, 5), Rango(1, 3), Rango(4, 7), Rango(
            0, 8), Rango(6, 9)
        vertices = {r1, r2, r3, r4, r5}
        r1.__ady = {r2, r3, r4}
        r2.__ady = {r1, r4}
        r3.__ady = {r1, r4, r5}
        r4.__ady = {r1, r2, r3, r5}
        r5.__ady = {r3, r4}
        for v in vertices:
            self.chk_eje(v, v)  # reflexividad
            for w in v.__ady:  # adyacencia dirigida
                self.chk_eje(v, w)
            for w in ((vertices - v.__ady) - {v}):  # no-adyacencia dirigida
                self.chk_no_eje(v, w)
Beispiel #18
0
def demo():
    ahora = FechaYHora(date(1998, 7, 10), time(17, 0, 0))  # modificar a gusto!

    class CentralMeteorologicaMock:
        def __init__(self, fechaYHora=ahora):
            self.redefinirFechaYHora(fechaYHora)

        def redefinirFechaYHora(self, FechaYHora):
            self._ahora = FechaYHora

        def obtenerFechaYHora(self):
            return self._ahora

    def mostrar(gps, cm):
        print("==== Programa de Suministro ====")
        print("A partir de fecha/hora : %s" % cm.obtenerFechaYHora())
        aps = programa.accionesProgramadas()
        for ap in aps:
            fh = ap.fechaYHora()
            print("%s : %s %s" % (fh.fecha(), fh.hora(), ap.accion().nombre()))
        print("%d acciones en total" % len(aps))

    cm = CentralMeteorologicaMock()

    programa = ProgramaDeSuministro(
        Rango(ahora, ahora.agregarDuracion(DuracionEnHoras(24))))

    gps = GeneradorDeProgramaDeSuministroFijo24(planMaestro=None,
                                                estadoDePlanta=None,
                                                centralMeteorologica=cm,
                                                programaDeSuministro=programa)

    gps.generar()
    mostrar(gps, cm)
    cm.redefinirFechaYHora(
        ahora.agregarDuracion(DuracionEnMinutos(60 * 10 + 15)))
    gps.generar()
    mostrar(gps, cm)
Beispiel #19
0
 def lapso(desde, hasta):
     return Rango(diaN(desde), diaN(hasta))
Beispiel #20
0
    # contando desde 0
    return FechaYHora(_dia0 + timedelta(days=n), _hora)


# una lista de pares para interpretar como lista de acciones. Lo único
# que realmente interesa son los horarios (que en este caso son
# instancias de fechaYHora, pero incluso podrían ser números (como fue
# la primera versión de este test)), las 'acciones' las suplantamos
# con cualquier banana (magia del mundo dinámico) porque no hacen nada
# por ahora.
_lista = [(diaN(0), 'primera'), (diaN(1), 'segunda'), (diaN(2), 'tercera'),
          (diaN(3), 'cuarta'), (diaN(4), 'quinta'), (diaN(5), 'sexta')]

# el lapso en el que trabajamos (alcanza con que abarque a los
# horarios de la lista, puede tener exceso).
_lapso = Rango(diaN(-2), diaN(8))


class TestProgramaDeSuministro(unittest.TestCase):
    # def sortAccionesProgramadas(self, lista):
    #     return sorted(lista)

    def accionesProgramadas2tuplas(self, lista):
        return [(aP.fechaYHora(), aP.accion()) for aP in lista]

    def chk_accionesProgramadas(self, programa, lista1):
        """verifica que la lista de acciones programadas, ordenadas por
        horario, es igual que la lista pasada como argumento.

        """
        lista2 = [(aP.fechaYHora(), aP.accion())
    def test_planificador_planifica_ejecucion_hora_por_hora(self):
        hora = FechaYHora(date(1998, 7, 10), time(17, 0, 0))
        kit = KitEjecucion()

        # inicializamos un programa de suministro vacío
        programa = ProgramaDeSuministro(
            Rango(hora, hora.agregarDuracion(DuracionEnHoras(3))))

        # programamos las acciones que entran en la primer hora
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(15)),
                                 AccionRegado(LiquidoEnMililitros(200)))
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(20)),
                                 AccionLuz(LuzEnLux(800)))
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(35)),
                                 AccionFertilizante(LiquidoEnMililitros(100)))
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(40)),
                                 AccionRegado(LiquidoEnMililitros(20)))
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(50)),
                                 AccionAntibiotico(LiquidoEnMililitros(10)))
        # programamos las acciones que entran en la segunda hora
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(75)),
                                 AccionRegado(LiquidoEnMililitros(100)))
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(90)),
                                 AccionLuz(LuzEnLux(500)))
        # programamos las acciones que entran en la tercer hora
        programa.programarAccion(hora.agregarDuracion(DuracionEnMinutos(130)),
                                 AccionAntibiotico(LiquidoEnMililitros(10)))

        # ok, está cargado el programa. Creamos entonces el
        # planificador, lo configuramos para que ejecute sobre el kit
        # con el programa dado a intervalos de una hora. Obviamente no
        # hay temporizadores acá así que vamos a llamarlo manualmente
        # por cada hora.

        planificador = PlanificadorDeEjecucion(DuracionEnHoras(1), programa,
                                               kit.ejecutor)

        # WARNING. los números están clavados. si se cambian arriba,
        # deben cambiarse acá abajo (sumando todo con cuidado).

        # ejecutamos la primer hora
        cuantasAntes = len(programa.accionesProgramadas())
        planificador.planificarAcciones(hora)
        self.assertEqual(kit.fertilizante(), 100)
        self.assertEqual(kit.luz(), 800)
        self.assertEqual(kit.agua(), 220)
        self.assertEqual(kit.antibiotico(), 10)
        cuantasDespues = len(programa.accionesProgramadas())
        self.assertEqual(cuantasAntes - cuantasDespues, 5)

        # ejecutamos la segunda hora
        cuantasAntes = len(programa.accionesProgramadas())
        planificador.planificarAcciones(
            hora.agregarDuracion(DuracionEnHoras(1)))
        self.assertEqual(kit.fertilizante(), 100 + 0)
        self.assertEqual(kit.luz(), 800 + 500)
        self.assertEqual(kit.agua(), 220 + 100)
        self.assertEqual(kit.antibiotico(), 10 + 0)
        cuantasDespues = len(programa.accionesProgramadas())
        self.assertEqual(cuantasAntes - cuantasDespues, 2)

        # ejecutamos la tercer hora
        cuantasAntes = len(programa.accionesProgramadas())
        planificador.planificarAcciones(
            hora.agregarDuracion(DuracionEnHoras(2)))
        self.assertEqual(kit.fertilizante(), 100 + 0 + 0)
        self.assertEqual(kit.luz(), 800 + 500 + 0)
        self.assertEqual(kit.agua(), 220 + 100 + 0)
        self.assertEqual(kit.antibiotico(), 10 + 0 + 10)
        cuantasDespues = len(programa.accionesProgramadas())
        self.assertEqual(cuantasAntes - cuantasDespues, 1)

        # verificamos que el programa esté vacío
        self.assertEqual(programa.accionesProgramadas(), [])