示例#1
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"
示例#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
示例#3
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
示例#4
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
示例#5
0
 def device_watcher(self):
     for device in self._connected_devices.values():
         if not device.is_alive():
             session = Session()
             session.query(Device).filter_by(id=device.id) \
                                  .update({Device.connected: False})
             session.commit()
             device.shutdown()
             del self._connected_devices[device.id]
     return
示例#6
0
 def __init__(self, context, endpoint, service):
     """Overridden initializer for MDPWorker.
     Adds the device_timer to manage connected devices
     """
     session = Session()
     session.query(Device).update({Device.connected: False})
     session.commit()
     self.device_timer = None
     super(DeviceServiceManager, self).__init__(context, endpoint, service)
     return
示例#7
0
def delete_wifi_network(id):

    session = Session()

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

    session.close()

    return
示例#8
0
def set_interfaces(eth0=None, wlan0=None, wlan1=None):

    session = Session()
    wifi_ap_present = False

    if eth0:
        try:
            db_eth = session.query(InterfaceDefinition).filter_by(interface='eth0').one()
        except NoResultFound:
            db_eth = InterfaceDefinition('eth0')
            session.add(db_eth)

        db_eth.is_active = True
        db_eth.is_for_fm = eth0['is_for_fm']
        db_eth.state = eth0['state']

    if wlan0:
        try:
            db_wlan0 = session.query(InterfaceDefinition).filter_by(interface='wlan0').one()
        except NoResultFound:
            db_wlan0 = InterfaceDefinition('wlan0')
            session.add(db_wlan0)

        db_wlan0.is_active = True
        db_wlan0.is_for_fm = wlan0['is_for_fm']
        db_wlan0.state = wlan0['state']
        if wlan0['state'] == 'ap':
            wifi_ap_present = True
        if wlan0['wifi']:
            set_wifi(db_wlan0, session, wlan0['wifi'])

    if wlan1:
        try:
            db_wlan1 = session.query(InterfaceDefinition).filter_by(interface='wlan1').one()
        except NoResultFound:
            db_wlan1 = InterfaceDefinition('wlan1')
            session.add(db_wlan1)

        db_wlan1.is_active = True
        db_wlan1.is_for_fm = wlan1['is_for_fm']
        db_wlan1.state = wlan1['state']
        if wlan1['state'] == 'ap':
            wifi_ap_present = True
        if wlan1['wifi']:
            set_wifi(db_wlan1, session, wlan1['wifi'])

    session.commit()

    if wifi_ap_present:
        set_ap_mode()
    else:
        set_wpa_mode()

    return
示例#9
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
示例#10
0
def create_backup(user_created=True):

    session = Session()

    software_version = session.query(SoftwareDefinition.software_version).scalar()
    serial_number = session.query(HardwareDefinition.serial_number).scalar()
    timestamp = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
    filepath = base_path + serial_number + '.fd.' + timestamp + '/'
    zip_filepath = filepath[:-1] + '.zip'

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

    if not os.path.exists(filepath + 'database/'):
        os.makedirs(filepath + 'database/')

    backup = Backup(serial_number, 'farm_device', zip_filepath)

    backup.software_version = software_version
    backup.user_created = user_created

    _backup_database(filepath)
    backup.database = True

    # _backup_data(filepath)
    # backup.data = True

    # zip the entire backup into one file
    zipf = zipfile.ZipFile(zip_filepath, 'w', zipfile.ZIP_DEFLATED)

    for root, dirs, files in os.walk(filepath):
        for file in files:
            filename = os.path.join(root, file)
            zipf.write(filename, os.path.relpath(filename, filepath))

    zipf.close()

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

    backup.sha256 = sha256.hexdigest()

    # Remove the folder. Just use the zipfile
    shutil.rmtree(filepath)

    session.add(backup)
    session.commit()

    return backup.index
示例#11
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
示例#12
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()
示例#13
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
示例#14
0
def delete_backup(backup_index, backup_type, serial_number):

    session = Session()

    backup = session.query(Backup).filter_by(index=backup_index,
                                             backup_type=backup_type,
                                             serial_number=serial_number).first()

    if backup:
        if os.path.isfile(backup.filepath):
            try:
                os.remove(backup.filepath)
            except OSError as ex:
                print(ex)
        session.delete(backup)
        session.commit()
    return
示例#15
0
class TagAttributeHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, entity_type_id, ident=None):
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        if ident is None:
            return [
                tag.to_dict() for tag in get_all(
                    self.session, TagAttribute, entity_type=entity_type)
            ]
        else:
            return get_one(self.session,
                           TagAttribute,
                           entity_type=entity_type,
                           id=ident).to_dict()

    @requires_validation(assert_attribute_does_not_exist(TagAttribute),
                         with_route_params=True)
    @requires_validation(Schema({Required('name'): non_empty_string}))
    def post(self, entity_type_id):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        tag = TagAttribute(entity_type=entity_type, name=data['name'])
        self.session.add(tag)

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True, 'ID': tag.id}

    def delete(self, entity_type_id, ident):
        entity_type = get_one(self.session, EntityType,
                              id=entity_type_id)  # check if route is correct
        tag = get_one(self.session,
                      TagAttribute,
                      entity_type=entity_type,
                      id=ident)
        now = time.time()
        tag.delete_ts = now
        for entity_tag in get_all(self.session, EntityTag, attribute=tag):
            entity_tag.delete_ts = now

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}
示例#16
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
示例#17
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()
示例#18
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"
示例#19
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
示例#20
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
示例#21
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
示例#22
0
class MetaAttributeHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, entity_type_id, ident=None):
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        if ident is None:
            return [meta.to_dict() for meta in get_all(self.session, MetaAttribute, entity_type=entity_type)]
        else:
            return get_one(self.session, MetaAttribute, entity_type=entity_type, id=ident).to_dict()

    @requires_validation(assert_attribute_does_not_exist(MetaAttribute), with_route_params=True)
    @requires_validation(Schema({Required('name'): non_empty_string}))
    def post(self, entity_type_id):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        meta = MetaAttribute(entity_type=entity_type, name=data['name'])
        self.session.add(meta)

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': meta.id
        }

    @requires_validation(assert_attribute_does_not_exist(MetaAttribute), with_route_params=True)
    @requires_validation(Schema({'name': non_empty_string}))
    def put(self, entity_type_id, ident):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=entity_type_id)  # check if route is correct
        meta = get_one(self.session, MetaAttribute, entity_type=entity_type, id=ident)

        if 'name' in data:
            meta.name = data['name']

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': meta.id,
        }

    def delete(self, entity_type_id, ident):
        entity_type = get_one(self.session, EntityType, id=entity_type_id)  # check if route is correct
        meta = get_one(self.session, MetaAttribute, entity_type=entity_type, id=ident)
        now = time.time()
        meta.delete_ts = now
        for entity_meta in get_all(self.session, EntityMeta, attribute=meta):
            entity_meta.delete_ts = now

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}
示例#23
0
class SeriesAttributeHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, entity_type_id, ident=None):
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        if ident is None:
            return [
                series.to_dict() for series in get_all(
                    self.session, SeriesAttribute, entity_type=entity_type)
            ]
        else:
            return get_one(self.session,
                           SeriesAttribute,
                           entity_type=entity_type,
                           id=ident).to_dict()

    @requires_validation(assert_attribute_does_not_exist(SeriesAttribute),
                         with_route_params=True)
    @requires_validation(
        Schema({
            Required('name'): non_empty_string,
            'type': Or('real', 'enum'),
            'refresh_time': Or(int, None),
            'is_favourite': bool,
        }))
    def post(self, entity_type_id):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        series = SeriesAttribute(entity_type=entity_type,
                                 name=data['name'],
                                 type=data.get('type', 'real'),
                                 refresh_time=data.get('refresh_time'),
                                 is_favourite=data.get('is_favourite', False))
        self.session.add(series)

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True, 'ID': series.id}

    @requires_validation(
        Schema({
            'refresh_time': Or(int, None),
            'is_favourite': bool,
        }))
    def put(self, entity_type_id, ident):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=entity_type_id)
        series = get_one(self.session,
                         SeriesAttribute,
                         entity_type=entity_type,
                         id=ident)
        if 'refresh_time' in data:
            series.refresh_time = data['refresh_time']
        if 'is_favourite' in data:
            series.is_favourite = data['is_favourite']

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True, 'ID': series.id}

    def delete(self, entity_type_id, ident):
        now = time.time()
        entity_type = get_one(self.session, EntityType,
                              id=entity_type_id)  # check if route is correct
        series = get_one(self.session,
                         SeriesAttribute,
                         entity_type=entity_type,
                         id=ident)
        series.delete_ts = now
        for alert in series.alerts:
            alert.delete_ts = now

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}
示例#24
0
class AlertHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, ident=None):
        if ident is None:
            return [alert.to_dict() for alert in get_all(self.session, Alert)]
        else:
            return get_one(self.session, Alert, id=ident).to_dict()

    @requires_validation(
        Schema({
            Required('entity_id'):
            int,
            Required('series_id'):
            int,
            Required('alert_predicate_type'):
            Or('data_delay', 'value_too_low', 'value_too_high'),
            Required('value'):
            float,
            Required('is_enabled'):
            bool,
            Required('alert_recipient_email'):
            Email,
        }))
    def post(self):
        data = self.request.data
        entity = get_one(self.session, Entity, id=data['entity_id'])
        series = get_one(self.session, SeriesAttribute, id=data['series_id'])
        alert = Alert(entity=entity,
                      series=series,
                      alert_predicate_type=data['alert_predicate_type'],
                      value=data['value'],
                      is_enabled=data['is_enabled'],
                      alert_recipient_email=data['alert_recipient_email'])
        self.session.add(alert)

        self.session.commit()
        return {'success': True, 'ID': alert.id}

    @requires_validation(
        Schema({
            'entity_id':
            int,
            'series_id':
            int,
            'alert_predicate_type':
            Or('data_delay', 'value_too_low', 'value_too_high'),
            'value':
            float,
            'is_enabled':
            bool,
            'alert_recipient_email':
            Email,
        }))
    def put(self, ident):
        data = self.request.data
        alert = get_one(self.session, Alert, id=ident)
        if 'entity_id' in data:
            entity = get_one(self.session, Entity, id=data['entity_id'])
            alert.entity_id_fk = entity.id
        if 'series_id' in data:
            series = get_one(self.session,
                             SeriesAttribute,
                             id=data['series_id'])
            alert.series_id_fk = series.id
        if 'alert_predicate_type' in data:
            alert.alert_predicate_type = data['alert_predicate_type']
        if 'value' in data:
            alert.value = data['value']
        if 'is_enabled' in data:
            alert.is_enabled = data['is_enabled']
        if 'alert_recipient_email' in data:
            alert.alert_recipient_email = data['alert_recipient_email']
        # reset last check status
        alert.last_check_status = None
        self.session.commit()
        return {
            'success': True,
            'ID': alert.id,
        }

    def delete(self, ident):
        alert = get_one(self.session, Alert, id=ident)
        now = time.time()
        alert.delete_ts = now

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}
示例#25
0
class EntityTypeHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, ident=None):
        if ident is None:
            return [
                entity_type.to_dict()
                for entity_type in get_all(self.session, EntityType)
            ]
        else:
            return get_one(self.session, EntityType, id=ident).to_dict()

    @requires_validation(
        Schema({
            Required('name'): non_empty_string,
            Required('tags'): And([non_empty_string], Unique()),
            Required('meta'): And([non_empty_string], Unique()),
            Required('series'): And([non_empty_string], Unique()),
        }))
    def post(self):
        data = self.request.data
        entity_type = EntityType(name=data['name'])
        self.session.add(entity_type)

        # add tags, meta and series
        for tag in data['tags']:
            self.session.add(TagAttribute(
                entity_type=entity_type,
                name=tag,
            ))
        for meta in data['meta']:
            self.session.add(
                MetaAttribute(
                    entity_type=entity_type,
                    name=meta,
                ))
        for series in data['series']:
            self.session.add(
                SeriesAttribute(
                    entity_type=entity_type,
                    name=series,
                ))

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': entity_type.id,
        }

    @requires_validation(_assert_objects_were_not_created,
                         with_route_params=True)
    @requires_validation(
        Schema({
            'name': non_empty_string,
            'tags': And([non_empty_string], Unique()),
            'meta': And([non_empty_string], Unique()),
            'series': And([non_empty_string], Unique()),
        }))
    def put(self, ident):
        data = self.request.data
        entity_type = get_one(self.session, EntityType, id=ident)
        if 'name' in data:
            entity_type.name = data['name']

        # add tags, meta and series
        if 'tags' in data:
            for tag in data['tags']:
                self.session.add(
                    TagAttribute(
                        entity_type=entity_type,
                        name=tag,
                    ))
        if 'meta' in data:
            for meta in data['meta']:
                self.session.add(
                    MetaAttribute(
                        entity_type=entity_type,
                        name=meta,
                    ))
        if 'series' in data:
            for series in data['series']:
                self.session.add(
                    SeriesAttribute(
                        entity_type=entity_type,
                        name=series,
                    ))

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': entity_type.id,
        }

    def delete(self, ident):
        entity_type = get_one(self.session, EntityType, id=ident)
        now = time.time()
        entity_type.delete_ts = now
        for tag in entity_type.tags:
            tag.delete_ts = now
        for series in entity_type.series:
            series.delete_ts = now
            for alert in series.alerts:
                alert.delete_ts = now
        for meta in entity_type.meta:
            meta.delete_ts = now
        for entity in entity_type.nodes:
            entity.delete_ts = now
            for tag in entity.tags:
                tag.delete_ts = now
            for meta in entity.meta:
                meta.delete_ts = now
            for child in entity.children:
                child.parent = entity.parent

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}
示例#26
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
示例#27
0
class EntityHandler(Handler):
    def __init__(self):
        self.session = Session()

    def get(self, ident=None):
        if ident is None:
            return [
                entity.to_dict(deep=False)
                for entity in get_all(self.session, Entity)
            ]
        else:
            return get_one(self.session, Entity, id=ident).to_dict(deep=False)

    @staticmethod
    def _assert_got_all_needed_tag_and_meta_ids(entity_type, tag_ids,
                                                meta_ids):
        expected_tag_ids = sorted(tag.id for tag in entity_type.tags
                                  if tag.delete_ts is None)
        expected_meta_ids = sorted(meta.id for meta in entity_type.meta
                                   if meta.delete_ts is None)
        if tag_ids != expected_tag_ids:
            raise HTTP_400('Expected tag IDs {}, got {}'.format(
                expected_tag_ids, tag_ids))
        if meta_ids != expected_meta_ids:
            raise HTTP_400('Expected meta IDs {}, got {}'.format(
                expected_meta_ids, meta_ids))

    @requires_validation(
        Schema(
            {
                Required('parent_id'): Or(int, None),
                Required('entity_type_id'): int,
            },
            extra=ALLOW_EXTRA))
    def post(self):
        data = self.request.data
        entity_type = get_one(self.session,
                              EntityType,
                              id=data['entity_type_id'])

        # check if we got all tags and meta
        tag_ids = sorted(
            int(key.split('_')[1]) for key in data if 'tag_' in key)
        meta_ids = sorted(
            int(key.split('_')[1]) for key in data if 'meta_' in key)
        self._assert_got_all_needed_tag_and_meta_ids(entity_type, tag_ids,
                                                     meta_ids)

        entity = Entity(
            entity_type=entity_type,
            parent=None if data['parent_id'] is None else get_one(
                self.session, Entity, id=data['parent_id']),
        )
        self.session.add(entity)

        # add tags and meta
        for key in data:
            if 'tag_' in key:
                self.session.add(
                    EntityTag(
                        entity=entity,
                        attribute=get_one(self.session,
                                          TagAttribute,
                                          id=int(key.split('_')[1])),
                        value=data[key],
                    ))
            elif 'meta_' in key:
                self.session.add(
                    EntityMeta(
                        entity=entity,
                        attribute=get_one(self.session,
                                          MetaAttribute,
                                          id=int(key.split('_')[1])),
                        value=data[key],
                    ))

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': entity.id,
        }

    def put(self, ident):
        data = self.request.data
        entity = get_one(self.session, Entity,
                         id=ident)  # to ensure that the entity exists

        if 'parent_id' in data:
            get_one(self.session, Entity, id=data['parent_id'])
            entity.parent_id_fk = data['parent_id']

        # add tags and meta
        for key in data:
            if 'tag_' in key:
                tag = get_one(self.session,
                              EntityTag,
                              entity=entity,
                              tag_id_fk=key.split('_')[1])
                tag.value = data[key]
            elif 'meta_' in key:
                meta = get_one(self.session,
                               EntityMeta,
                               entity=entity,
                               meta_id_fk=key.split('_')[1])
                meta.value = data[key]

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {
            'success': True,
            'ID': entity.id,
        }

    def delete(self, ident):
        entity = get_one(self.session, Entity, id=ident)
        now = time.time()
        entity.delete_ts = now
        for tag in entity.tags:
            tag.delete_ts = now
        for meta in entity.meta:
            meta.delete_ts = now
        for alert in entity.alerts:
            alert.delete_ts = now
        for child in entity.children:
            child.parent = entity.parent

        self.session.commit()
        update_last_data_modification_ts(self.session)
        return {'success': True}