Esempio n. 1
0
class SimulatorSource(PointSource):
    def __init__(self, entity_id, measurements):
        self._entity_id = entity_id
        self._measurements = measurements

    def __enter__(self):
        self._session = Session()
        self._entity = get_one(self._session, Entity, id=self._entity_id)
        self._entity_measurement_names = {}
        for measurement_id in self._measurements:
            if measurement_id not in self._entity_measurement_names:
                measurement_name = get_one(self._session, SeriesAttribute, id=measurement_id).name
                self._entity_measurement_names[measurement_id] = measurement_name
        return self

    def __exit__(self, *args):
        self._entity = None
        self._entity_measurement_names = {}
        self._session.close()

    def get_values(self) -> Iterable[dict]:
        result = []
        for measurement_id in self._measurements:
            series_measurements = self._measurements[measurement_id]
            for (point_ts, point_val) in series_measurements:
                result.append({
                    'timestamp': convert_timestamp(create_data_timestamp(point_ts)),
                    'measurements': [(self._entity_measurement_names[measurement_id], float(point_val))]
                })
        return result

    def get_entity(self) -> Entity:
        return self._entity
Esempio n. 2
0
def add_wifi_network(wifi_name, wifi_password, interface=None):

    session = Session()

    if interface is None:
        interfaces = session.query(InterfaceDefinition).all()
        for x in interfaces:
            if x.interface != 'eth0':
                if x.state == 'dhcp':
                    interface = x.interface

    if interface is None:
        logger.error("No interface available to add new wifi network")
        return None

    # have an interface. now create a WifiDefinition entry
    new_wifi = WifiDefinition()
    new_wifi.wifi_name = wifi_name
    new_wifi.wifi_password = wifi_password
    new_wifi.wifi_mode = 'dhcp'
    new_wifi.interface = interface

    session.add(new_wifi)
    session.commit()

    session.close()

    return new_wifi
Esempio n. 3
0
def set_wpa_mode():

    logger.debug("setting all wlan into wpa mode")
    session = Session()

    # get the info for the wpa_supplicant file
    wifi_defs = session.query(WifiDefinition).filter(WifiDefinition.wifi_mode != 'ap').all()
    networks = []
    for wifi in wifi_defs:
        new_network = {}
        new_network['ssid'] = wifi.wifi_name
        new_network['password'] = wifi.wifi_password
        networks.append(new_network)

    iptables_file(None, None, flush_only=True)
    interface_file()
    wpa_supplicant_file(networks)
    dhcpcd_file()

    install_root = session.query(RoutingDefiniton.route).filter_by(name='install_root').scalar()
    session.close()

    path = install_root + 'farm_device/network/wpa_script.sh'

    command = ['sudo', 'sh', path]
    subprocess.check_call(command)

    return
Esempio n. 4
0
    def create(self):

        self.timestamp = time()

        session = Session()
        device = session.query(Device).first()

        self.id = device.id
        self.software_version = device.software_version
        self.interior_temp = temperature(device.interior_sensor)
        self.exterior_temp = temperature(device.exterior_sensor)
        self.device_temp = getCPUtemperature()

        self.uptime = get_uptime_seconds()
        self.current_time = datetime.datetime.now()
        self.load_avg = os.getloadavg()

        storage = get_storage()
        self.disk_total = storage['disk_total']
        self.disk_used = storage['disk_used']
        self.disk_free = storage['disk_free']

        session.close()

        return
Esempio n. 5
0
def set_software_info(software_version, device_service=None, grainbin_service=None):
    """
    Set the software version info into the SoftwareDefinition table.
    software_version is a string representing what revison of software
    device_service is a Boolean indicating if the device service is enabled
    grainbin_service is a Boolean indicating if the grainbin service is enabled
    """
    logger.debug("setting version: {0} device: {1} grainbin {2}".format(software_version,
                                                                        device_service,
                                                                        grainbin_service))
    session = Session()

    try:
        sd = session.query(SoftwareDefinition).one()
        sd.software_version = software_version
        if device_service is not None:
            sd.device_service = device_service
        if grainbin_service is not None:
            sd.grainbin_service = grainbin_service

    except NoResultFound:
        sd = SoftwareDefinition()
        sd.software_version = software_version
        if device_service is not None:
            sd.device_service = device_service
        if grainbin_service is not None:
            sd.grainbin_service = grainbin_service
        session.add(sd)

    session.commit()
    session.close()

    return
Esempio n. 6
0
    def on_create(self, did, msg):
        imported_device = pickle.loads(msg[0])

        device = Device(imported_device['id'],
                        version=imported_device['version'])

        device.connected = True
        device.user_configured = False
        device.database_service = imported_device['database_service']
        device.device_service = imported_device['device_service']
        device.grainbin_service = imported_device['grainbin_service']
        device.grainbin_count = imported_device['grainbin_count']

        session = Session()
        session.add(device)

        if device.grainbin_service:
            grainbins = []
            for x in range(device.grainbin_count):
                id = device.id + '.' + str(x).zfill(2)
                grainbin = Grainbin(id, device.id, x)
                grainbins.append(grainbin)
            session.add_all(grainbins)

        session.commit()
        session.close()

        return "added"
Esempio n. 7
0
def subscriber_manager(context):

    global subscriber
    global publisher
    global subscriber_topics

    session = Session()

    # Set up forwarder device
    logger.debug("Configuring forwarder device")
    forwarder_subscriber_address = session.query(RoutingDefiniton.route) \
                                          .filter_by(name="internal_pub") \
                                          .scalar()
    forwarder_publisher_address = session.query(RoutingDefiniton.route) \
                                         .filter_by(name="internal_sub") \
                                         .scalar()

    forwarder = ProcessDevice(zmq.FORWARDER, zmq.SUB, zmq.PUB)
    forwarder.connect_in(forwarder_subscriber_address)
    forwarder.setsockopt_in(zmq.SUBSCRIBE, "")
    logger.debug("forwarder connect in: {0}".format(forwarder_subscriber_address))

    forwarder.bind_out(forwarder_publisher_address)
    logger.debug("forwarder bind out: {0}".format(forwarder_publisher_address))

    # Set up subscriber listening to Farm-Monitor server
    subscriber_address = session.query(RoutingDefiniton.route)\
                                .filter_by(name="subscriber_address").scalar()
    subscriber_port = session.query(RoutingDefiniton.route)\
                             .filter_by(name="subscriber_port").scalar()
    subscriber_address = "tcp://" + subscriber_address + ":" + subscriber_port
    device_id = session.query(HardwareDefinition.serial_number).scalar()
    subscriber_topics.append(device_id)

    subscriber = Subscriber(context, subscriber_address, subscriber_topics)
    subscriber.subscriber.on_recv(callback=server_subscriber_recv)
    logger.debug("Subscriber listening to: {0} topics: {1}".format(subscriber_address,
                                                                   subscriber_topics))

    # Set up publisher to forward messages from Farm-Monitor to internal
    publisher_address = session.query(RoutingDefiniton.route)\
                               .filter_by(name="internal_pub").scalar()
    publisher = Publisher(context, publisher_address)
    logger.debug("Publisher configured to: {0}".format(publisher_address))

    session.close()
    try:
        logger.info("starting forwarder, Subscriber, and Publisher")
        # Start the forwarder
        forwarder.start()
        IOLoop.instance().start()

    except KeyboardInterrupt:
        logger.info("stopping forwarder, Subscriber, and Publisher")
        IOLoop.instance().stop()
        subscriber.shutdown()
        publisher.shutdown()

    return
Esempio n. 8
0
    def backup(self):

        backup_index = create_backup()

        session = Session()
        backup = session.query(Backup).filter_by(index=backup_index).first()

        standalone_configuration = session.query(SystemSetup.standalone_configuration).scalar()

        if self.device_state == 'connected':

            failed_attempts = 0

            # don't send the file if we are a combined configuration
            if standalone_configuration:
                logger.info("Sending device backup file to FarmMonitor")
                file_size = os.path.getsize(backup.filepath)
                bytes_sent = 0
                zip_file = open(backup.filepath, 'r')

                while bytes_sent < file_size and failed_attempts < 3:
                    zip_file.seek(bytes_sent)
                    data = zip_file.read(512)
                    logger.debug("Sending {0} bytes of backup file".format(len(data)))
                    message = FileMessage(self.device_id, 'farm_monitor', 'backup')
                    message.set_file(backup.filepath, data)
                    reply = self.send([pickle.dumps(message)])

                    if reply:
                        # only mark the data received if a reply is recieved
                        bytes_sent += len(data)
                        failed_attempts = 0
                        reply_message = pickle.loads(reply[1])
                        logger.debug("Update reply: {0}".format(reply_message.reply))
                    else:
                        logger.warn("Failed attempt in sending backup file")
                        failed_attempts += 1

                zip_file.close()

            # only send the database object if the file was sent correctly
            if failed_attempts == 0:
                logger.info("Sending device backup database object to FarmMonitor")
                message = FileMessage(self.device_id, 'farm_monitor', 'backup')
                message.set_db_object(pickle.dumps(backup))
                reply = self.send([pickle.dumps(message)])

                if reply:
                    reply_message = pickle.loads(reply[1])
                    logger.debug("Update response: {0}".format(reply_message.reply))

            else:
                logger.warn("To many failed attempts. Backup failed to send to Farm Monitor")

        session.close()

        return
Esempio n. 9
0
    def create(self):

        session = Session()
        grainbins = session.query(Grainbin).all()

        for grainbin in grainbins:
            self.grainbins.append(GrainbinModel(grainbin, read_temperature=False))

        session.close()
        return
Esempio n. 10
0
def delete_wifi_network(id):

    session = Session()

    session.query(WifiDefinition).filter_by(id=id).delete()
    session.commit()

    session.close()

    return
Esempio n. 11
0
def set_ap_mode():

    logger.debug("setting wifi into ap mode")
    session = Session()

    # get the wlan0 and wlan1 dhcp states
    try:
        ap_interface = session.query(InterfaceDefinition).filter_by(state='ap').first()
        ap_ssid = ap_interface.credentials[0].wifi_name
        ap_password = ap_interface.credentials[0].wifi_password

    except NoResultFound:
        # error. abort
        logger.warn("No interface with state set to 'ap'. Aborting")
        return

    # get info for interface file
    if ap_interface.interface == 'wlan0':
        wlan0_dhcp = False
        wlan1_dhcp = True

    else:
        wlan0_dhcp = True
        wlan1_dhcp = False

    # get the info for the wpa_supplicant file
    wifi_defs = session.query(WifiDefinition).filter(WifiDefinition.wifi_mode != 'ap').all()
    networks = []
    for wifi in wifi_defs:
        new_network = {}
        new_network['ssid'] = wifi.wifi_name
        new_network['password'] = wifi.wifi_password
        networks.append(new_network)

    # get the information for the iptables_file
    internal_interface = ap_interface.interface
    external_interface = get_external_interface()

    iptables_file(external_interface, internal_interface)
    interface_file(wlan0_dhcp=wlan0_dhcp, wlan1_dhcp=wlan1_dhcp)
    wpa_supplicant_file(networks)
    dhcpcd_file(interface=ap_interface.interface)
    dnsmasq_file(interface=ap_interface.interface)
    hostapd_file(ap_interface.interface, ap_ssid, ap_password)

    install_root = session.query(RoutingDefiniton.route).filter_by(name='install_root').scalar()
    session.close()

    path = install_root + 'farm_device/network/ap_script.sh'

    command = ['sudo', 'sh', path, ap_interface.interface]
    subprocess.check_call(command)

    return
Esempio n. 12
0
def set_sensor_info(interior):
    """
    there should be two 1W sensors connected directly to the device.
    This gets the sensors and sets which one is interior and exterior
    into the HardwareDefinition table.
    interior should be '1' or '2' and specifies which of the two sensors
    is the interior one.
    """

    logger.debug("setting sensor info for device")
    interior = int(interior)
    # get the 1W sensors that are connected directly to the device
    # theses are the interior and exterior temp sensors
    sensors = get_connected_sensors()

    int_sensor = "no_sensor_selected"
    ext_sensor = "no_sensor_selected"

    # there should be two sensors
    if len(sensors) == 2:
        if interior == 1:
            int_sensor = sensors[0]
            ext_sensor = sensors[1]
        elif interior == 2:
            int_sensor = sensors[1]
            ext_sensor = sensors[0]

    elif len(sensors) == 1:
        if interior == 1:
            int_sensor = sensors[0]
            ext_sensor = "no_sensor_detected"
        elif interior == 2:
            int_sensor = "no_sensor_detected"
            ext_sensor = sensors[0]

    logger.debug("interior sensor is: {0}".format(int_sensor))
    logger.debug("exterior sensor is: {0}".format(ext_sensor))
    # now set the sensor info into the tables
    session = Session()
    try:
        hd = session.query(HardwareDefinition).one()
        hd.interior_sensor = int_sensor
        hd.exterior_sensor = ext_sensor

    except NoResultFound:
        hd = HardwareDefinition()
        hd.interior_sensor = int_sensor
        hd.exterior_sensor = ext_sensor
        session.add(hd)

    session.commit()
    session.close()

    return
Esempio n. 13
0
def delete_release(repo, name):

    session = Session()
    release = session.query(Update).filter_by(repo=repo, name=name).first()

    if release:
        if os.path.isdir(release.filepath):
            shutil.rmtree(release.filepath)
        session.delete(release)
        session.commit()

    session.close()
    return
Esempio n. 14
0
def check_all_alerts(
        on_state_change: Iterable[Callable[[Alert, str], Any]]) -> None:
    session = Session()
    for alert in get_all(session, Alert, is_enabled=True):
        status = check_alert(alert)
        if status and not alert.last_check_status:
            [callback(alert, str(status)) for callback in on_state_change
             ]  # call all callbacks in on_state_change
            alert.last_check_status = True
        if alert.last_check_status is None or (not status
                                               and alert.last_check_status):
            [callback(alert, str(status)) for callback in on_state_change]
            alert.last_check_status = False

    session.commit()
    session.close()
Esempio n. 15
0
def post_update(update_id):

    session = Session()

    # update the software info
    update = session.query(Update).filter_by(id=update_id).one()
    device = session.query(Device).one()

    device.software_version = update.name

    delete_release(update.repo, update.name)

    session.commit()
    session.close()

    return
Esempio n. 16
0
    def __init__(self, context):
        socket = context.socket(zmq.ROUTER)
        socket.setsockopt(zmq.LINGER, 0)
        identity = 'router'
        socket.identity = identity.encode('ascii')

        session = Session()
        router_internal = session.query(RoutingDefiniton.route) \
                                 .filter_by(name="internal_router") \
                                 .scalar()
        session.close()
        socket.bind(router_internal)

        ioloop = IOLoop.instance()
        self.internal_router = ZMQStream(socket, ioloop)
        self.internal_router.on_recv(callback=self.router_recv)
        return
Esempio n. 17
0
    def __init__(self, context, identity):
        self.socket = context.socket(zmq.DEALER)
        self.socket.identity = identity.encode('ascii')
        self.socket.setsockopt(zmq.LINGER, 0)

        session = Session()
        dealer_internal = session.query(RoutingDefiniton.route) \
                                 .filter_by(name="internal_dealer") \
                                 .scalar()

        session.close()
        self.socket.connect(dealer_internal)

        self.poll = zmq.Poller()
        self.poll.register(self.socket, zmq.POLLIN)

        return
Esempio n. 18
0
    def create(self):
        session = Session()
        device = session.query(Device).first()

        self.id = device.id
        self.hardware_version = device.hardware_version
        self.software_version = device.software_version
        self.database_service = device.database_service
        self.device_service = device.device_service
        self.grainbin_service = device.grainbin_service

        if device.grainbin_service:
            self.grainbin_count = device.grainbin_count
            self.grainbin_data = GrainbinInfo(self.source, self.destination)
            self.grainbin_data.create()

        session.close()

        return
Esempio n. 19
0
    def on_heartbeat(self, did):
        if did in self._connected_devices:
            if self._connected_devices[did].is_alive():
                self._connected_devices[did].on_message_received()
            return self._connected_devices[did].get_state()
        else:
            session = Session()
            device = session.query(Device).filter_by(id=did).first()

            if not device:
                session.close()
                # signals the device to send a create message
                return 'unknown'
            else:
                self._connected_devices[did] = DeviceRep(did,
                                                         state='connected')
                device.connected = True
                session.commit()
                return 'connected'
        return
Esempio n. 20
0
def device_service(context):
    global connection
    global subscriber
    global internal_router

    session = Session()

    client_address = session.query(RoutingDefiniton.route)\
                            .filter_by(name="client_address").scalar()
    client_port = session.query(RoutingDefiniton.route)\
                         .filter_by(name="client_port").scalar()
    client_address = "tcp://" + client_address + ":" + client_port
    device_id = session.query(HardwareDefinition.serial_number).scalar()

    subscriber_address = session.query(RoutingDefiniton.route)\
                                .filter_by(name="internal_sub").scalar()
    session.close()
    subscriber_topics = ["device"]

    connection = DeviceConnection(context, device_id, client_address)
    logger.debug("DeviceConnection connecting to: {0}".format(client_address))
    logger.debug("DeviceConnection device id is: {0}".format(device_id))

    subscriber = DeviceSubscriber(context,
                                  subscriber_address,
                                  subscriber_topics)
    logger.debug("DeviceSubscriber subscribing to: {0}".format(subscriber_address))
    logger.debug("DeviceSubscriber topics: {0}".format(subscriber_topics))

    internal_router = DeviceRouter(context)

    try:
        logger.info("starting DeviceConnection, DeviceSubscriber, and DeviceRouter")
        IOLoop.instance().start()
    except KeyboardInterrupt:
        logger.info("stoping DeviceConnection, DeviceSubscriber, and DeviceRouter")
        IOLoop.instance().stop()
        internal_router.shutdown()
        subscriber.shutdown()
        connection.shutdown()
    return
Esempio n. 21
0
def push_new_measurements(directory, pattern):
    session = Session()
    files = os.listdir(directory)
    for node in get_all(session, Entity):
        to_read = [
            directory + '/' + f for f in files
            if re.match(pattern.format(ID=node.id), f) and
            os.path.getmtime(directory + '/' + f) >= node.last_data_fetch_ts
        ]
        # get input files sorted by modification time
        for file in sorted(to_read, key=os.path.getmtime):
            try:
                InfluxWriter().write(
                    PointGenerator(node, FileParser(node.id,
                                                    file)).generate_points())
                node.last_data_fetch_ts = int(os.path.getmtime(file))
                session.commit()
            except Exception as err:
                logging.error(err)

    session.close()
Esempio n. 22
0
def grainbin_service(context):
    global service
    global subscriber
    global internal_dealer

    session = Session()

    client_address = session.query(RoutingDefiniton.route)\
                            .filter_by(name="client_address").scalar()
    client_port = session.query(RoutingDefiniton.route)\
                         .filter_by(name="client_port").scalar()
    client_address = "tcp://" + client_address + ":" + client_port
    device_id = session.query(HardwareDefinition.serial_number).scalar()

    subscriber_address = session.query(RoutingDefiniton.route)\
                                .filter_by(name="internal_sub").scalar()
    session.close()
    subscriber_topics = ["grainbin"]

    service = GrainBinService(context, device_id, client_address)
    logger.debug("GrainbinService connecting to: {0}".format(client_address))

    subscriber = GrainBinSubscriber(context,
                                    subscriber_address,
                                    subscriber_topics)
    logger.debug("GrainbinSubscriber subscribing to: {0}".format(subscriber_address))
    logger.debug("GrainbinSubscriber topics: {0}".format(subscriber_topics))

    internal_dealer = GrainBinDealer(context, 'grainbin')
    logger.debug("GrainbinDealer has id 'grainbin'")
    try:
        logger.info("starting GrainbinService, GrainbinSubscriber, and GrainbinDealer")
        IOLoop.instance().start()
    except KeyboardInterrupt:
        logger.info("stopping GrainbinService, GrainbinSubscriber, and GrainbinDealer")
        IOLoop.instance().stop()
        internal_dealer.shutdown()
        subscriber.shutdown()
        service.shutdown()
    return
Esempio n. 23
0
    def on_update(self, did, msg):

        session = Session()
        device = session.query(Device).filter_by(id=did).first()

        if device:
            if device.user_configured:
                update = pickle.loads(msg[0])
                device.interior_temp = update['interior_temp']
                device.exterior_temp = update['exterior_temp']
                session.commit()
                session.close()

                values = {'interior_temp': update['interior_temp'],
                          'exterior_temp': update['exterior_temp']}
                rrd = RRD(did, 'device')
                print(values)
                print(update['timestamp'])
                rrd.update(values, timestamp=update['timestamp'])

                return "updated"
            else:
                session.close()
                return 'device_unconfigured'
        else:
            session.close()
            return 'no_device'
        return
Esempio n. 24
0
def get_external_interface():

    session = Session()

    if ethernet_connected():
        ethernet = session.query(InterfaceDefinition).filter_by(interface='eth0').first()
        ethernet.is_external = True
        session.commit()
        session.close()
        return 'eth0'

    # now check if it is either wlan0 or wlan1
    interfaces = session.query(InterfaceDefinition).filter_by(state='dhcp').all()

    for interface in interfaces:
        if interface.interface != 'eth0':
            interface.is_external = True
            session.commit()
            session.close()
            return interface.interface

    return "None"
Esempio n. 25
0
def preform_update(update_id, update_type):

    session = Session()

    try:
        update = session.query(Update).filter_by(id=update_id).one()
    except NoResultFound:
        session.close()
        return

    if update_type == 'farm_device':
        # now stage and preform the update
        file_path = update.filepath + update.filename

        updater_path = session.query(RoutingDefiniton.route).filter_by(name='updater_path').scalar()

        # launch the updater script in a seperate process. The bash file just calls another
        # python script in a detached process
        Popen(['sh', updater_path, str(update_id), file_path, "farm_device", "farm_device"],
              preexec_fn=os.setpgrp)
        session.close()

    return
Esempio n. 26
0
def refresh_interfaces():

    session = Session()
    ap_present = False

    interfaces = get_interfaces()

    # update all interfaces to be False by default
    session.query(InterfaceDefinition).update({InterfaceDefinition.is_active: False})
    session.commit()

    for my_interface in interfaces:
        try:
            interface = session.query(InterfaceDefinition).filter_by(interface=my_interface).one()

            interface.is_active = True
            # see if there is an interface that is configured for an ap
            if interface.state == 'ap':
                ap_present = True

        # must be a new interface so lets add it
        except NoResultFound:
            new_interface = InterfaceDefinition(my_interface)
            new_interface.is_active = True
            new_interface.is_for_fm = False
            new_interface.state = 'dhcp'
            session.add(new_interface)

    session.commit()
    session.close()

    if ap_present:
        set_ap_mode()
    else:
        set_wpa_mode()

    return
Esempio n. 27
0
    def create(self, bus_number="ALL"):

        self.timestamp = time()

        session = Session()

        if bus_number == "ALL":
            grainbins = session.query(Grainbin).all()

            for grainbin in grainbins:
                grainbin_data = GrainbinModel(grainbin, read_temperature=True)
                self.grainbins.append(grainbin_data)
                grainbin.average_temp = grainbin_data.average_temp
        else:
            grainbin = session.query(Grainbin).filter_by(bus_number=bus_number).first()

            if grainbin:
                grainbin_data = GrainbinModel(grainbin, read_temperature=True)
                self.grainbins.append(grainbin_data)
                grainbin.average_temp = grainbin_data.average_temp

        session.commit()
        session.close()
        return
Esempio n. 28
0
def set_hardware_info(hardware_version, gb_reader_count):
    """
    Set the hardware info into the HardwareDefinition table.
    hardware_version is a string representing what revison of hardware
    wifi_chip is the chip of the wifi adapter
    gb_reader_count is the number of 1Wire readerchips the FarmDevice has
    """

    logger.debug("setting vers: {0} grainbin_reader: {1}".format(hardware_version,
                                                                 gb_reader_count))
    session = Session()

    device_name = get_device_name()
    serial_number = getserial()

    try:
        hd = session.query(HardwareDefinition).one()
        hd.hardware_version = hardware_version
        hd. wifi_chip = None
        hd.device_name = device_name
        hd.serial_number = serial_number
        hd.grainbin_reader_count = int(gb_reader_count)

    except NoResultFound:
        hd = HardwareDefinition()
        hd.hardware_version = hardware_version
        hd.wifi_chip = None
        hd.device_name = device_name
        hd.serial_number = serial_number
        hd.grainbin_reader_count = int(gb_reader_count)
        session.add(hd)

    session.commit()
    session.close()

    return
Esempio n. 29
0
    def on_update(self, did, msg):

        session = Session()
        device = session.query(Device).filter_by(id=did).first()

        if device:
            if device.user_configured:
                update = pickle.loads(msg[0])
                process_grainbin_update(session, update)
            else:
                session.close()
                return 'device unconfigured'
        else:
            session.close()
            return 'no device'

        session.close()
        return 'updated'
Esempio n. 30
0
    def perform_update(self, update_id):

        session = Session()
        standalone_configuration = session.query(SystemSetup.standalone_configuration).scalar()

        if self.device_state == 'connected':

            # request the update db_object
            logger.info("Requesting update with id: {0} from FarmMonitor".format(update_id))
            message = [self.device_id, 'perform_update', 'db_object', update_id]
            message = FileMessage(self.device_id, 'farm_monitor', 'perform_update')
            message.set_db_object(update_id)
            reply = self.send([pickle.dumps(message)])

            if reply:
                reply_message = pickle.loads(reply[1])
                logger.debug("Update response from farm_monitor")

                if reply_message.data:
                    update = pickle.loads(reply_message.data)

                else:
                    logger.warn("incorrect response in perform_update: {0}".format(reply[0]))
                    session.close()
                    return

                failed_attempts = 0

                # don't request the file if we are a combined configuration
                if standalone_configuration:

                    if not os.path.exists(update.filepath):
                        os.makedirs(update.filepath)

                    bytes_received = 0
                    more_to_send = True
                    new_file = open(update.filepath + update.filename, 'a')

                    while more_to_send and failed_attempts < 3:
                        logger.info("Requesting update file from FarmMonitor")
                        message = FileMessage(self.device_id, 'farm_monitor', 'perform_update')
                        message.request_file(update_id, str(bytes_received))
                        reply = self.send([pickle.dumps(message)])

                        if reply:
                            reply_message = pickle.loads(reply[1])
                            logger.debug("Update response from FarmMonitor")
                            failed_attempts = 0
                            # in this case, reply_message.filepath is really a boolean.
                            # reusing the FileMessage object
                            more_to_send = reply_message.filepath
                            data = reply_message.data

                            new_file.seek(bytes_received)
                            new_file.write(data)
                            bytes_received += len(data)

                        else:
                            logger.warn("Failed attempt in requesting update file")
                            failed_attempts += 1

                    new_file.close()

                # compare the hash of the file
                sha256 = hashlib.sha256()
                with open(update.filepath + update.filename, 'rb') as f:
                    for block in iter(lambda: f.read(2048), b''):
                        sha256.update(block)

                if update.sha256 == sha256.hexdigest():
                    logger.info("Update file successfully received")
                    print('update received good')
                    session.merge(update)
                    session.commit()
                else:
                    logger.warn("Update file hash does not match. Update failed")
                    session.close()
                    return

                # now perform the actual update
                run_update(update.id, 'farm_device')

            else:
                logger.warn("No reply when requesting update db_object from FarMonitor.")

        session.close()
        return