def delete_all_devices_for_user(): """ delete all active devices for the given user """ try: username = get_jwt_identity() with session_scope() as session: user = user_service.get_user(username, session) device_count = user.devices.count() if device_count == 0: resp = { "status": "error", "msg": "no devices found for '%s'" % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) LOGGER.info("Deleting all devices for '%s'" % username) for device in user.devices: device_service.delete_device(user.username, device.device_id, session) LOGGER.info("Deleted " + device.device_name + ", with device id = " + device.device_id + "!") LOGGER.info("Deleted all devices for '%s'" % username) resp = { "status": "success", "msg": "deleted %d devices for '%s'" % (device_count, username) } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_active_devices_for_user(): """ show active devices for the given user """ try: username = get_jwt_identity() with session_scope() as session: user = user_service.get_user(username, session) if user.devices.count() == 0: resp = { "status": "error", "msg": "no devices found for '%s' " % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) active_devices = [] for device in user.devices: if device_service.is_device_active(device) and device_service.is_device_simulating(device): active_devices.append(device.serialize()) resp = { "status": "success", "msg": "found {} active devices for '{}'".format(len(active_devices), username), "data": active_devices } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_user(): """ get a user return: details of the user with the given username """ try: with session_scope() as session: user = user_service.get_user(get_jwt_identity(), session) if user is None: resp = { "status": "error", "msg": "user not found" } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "user found", "data": user.serialize() } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_all_devices_for_all_users(): """ :return: a list of all devices """ try: with session_scope() as session: devices = device_service.get_all_devices_for_all_users(session) if len(devices) == 0: resp = { "status": "error", "msg": "no devices found in db" } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "found {} devices in db".format(len(devices)), "data": [device.serialize() for device in devices] } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_all_users(): """ return: list of registered users """ try: with session_scope() as session: users = user_service.get_all_users(session) if not len(users) > 0: resp = { "success": "error", "msg": "no users found" } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "found {} users".format(len(users)), "data": [user.serialize() for user in users] } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def turn_off_device(): """ turn off the given device """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) LOGGER.info("stop signal received for device_id:" + device_id) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with device_id '%s' found for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) if not device_service.is_device_active(device): resp = { "status": "error", "msg": "device with device_id '%s' not active. you need to activate it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) if not device_service.is_device_simulating(device): resp = { "status": "error", "msg": "device with device_id '%s' not simulating. you need to start simulating it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) if device_service.is_device_turned_off(device): resp = { "status": "success", "msg": "device with device_id '%s' already turned off" % device_id } return make_response(jsonify(resp), status.HTTP_200_OK) device_service.turn_off_device(device, session) resp = { "status": "success", "msg": "turned off device with device_id '%s'" % device_id } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def revoke_role(): """ :return: """ try: username = request.json.get("username", get_jwt_identity()) role_to_revoke = request.json.get("role", None) if not role_to_revoke: resp = { "status": "error", "msg": "you must provide a role" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: user = user_service.get_user(username, session) if user is None: resp = { "status": "error", "msg": "User '{}' doesn't exist".format(username), } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) if role_to_revoke not in [role.name.value for role in user.roles]: resp = { "status": "error", "msg": "'{}' role not present for '{}'".format(role_to_revoke, username), } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) updated_user = user_service.revoke_role(username, role_to_revoke, session) resp = { "status": "success", "msg": "revoked '{}' role from '{}'".format(role_to_revoke, username), "data": { "updated_roles": [role.serialize() for role in updated_user.roles] } } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "{}".format(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def create_device(): """ start simulating a new device for the given user """ try: username = get_jwt_identity() # retrieve model parameters from request body and validate them req_params = AttrDict(json.loads(request.data)) is_valid, resp = device_service.validate_device_params(req_params) if not is_valid: return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: user = user_service.get_user(username, session) if user.devices.count() == user.max_devices: resp = { "status": "error", "msg": "max active device limit reached for '{}'".format(username) } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) # create the device device = device_service.create_device(username, req_params.device_name, session) # add model to device model = DeviceModel(req_params.model_name, req_params.params) device_service.add_device_model(device, model, session) # start a simulating a new device device_service.start_simulation(device, session) # also turn it on device_service.turn_on_device(device, session) resp = { "status": "success", "msg": "created new device", "data": device.serialize() } return make_response( jsonify(resp), status.HTTP_201_CREATED, {'location': url_for(".get_device", device_id=device.device_id, _external=True)} ) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_device(): """ :return a single device for the current user if 'device_id' provided in request body else return all devices for user """ try: username = get_jwt_identity() with session_scope() as session: # return only requested device if 'device_id' was sent in req body if request.data and "device_id" in AttrDict(json.loads(request.data)): device_id = AttrDict(json.loads(request.data)).get("device_id") device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with id '%s' exists for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "device found", "data": device.serialize() } return make_response(jsonify(resp), status.HTTP_200_OK) else: # return all devices for the user current_user_devices = device_service.get_all_devices(username, session) if len(current_user_devices) == 0: resp = { "status": "error", "msg": "no devices exists for '%s'" % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "{} devices found for {}".format(len(current_user_devices), username), "data": [device.serialize() for device in current_user_devices] } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def delete_device(): """ delete active devices by: i)- first terminating their respective threads by setting the shutdown flag on thread to trigger a clean shutdown ii)- after stopping simulation, the device is deleted from db """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no such device exists for '%s'" % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) is_deleted = device_service.delete_device(username, device_id, session) if is_deleted: resp = { "status": "success", "msg": "deleted device with device_id '%s'" % device_id } return make_response(jsonify(resp), status.HTTP_200_OK) else: resp = { "status": "error", "msg": "failed ot delete device with device_id '%s'" % device_id } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def __init__(self): self.user_repo = user_repo # Ensure that admin users exists with session_scope() as session: if self.user_repo.find_by_username("admin", session) is None: self.add_user("admin", "password", "Admin", "User", "*****@*****.**", session) self.add_role("admin", "admin", session) self.add_role("admin", "developer", session) self.add_role("admin", "end-user", session) if self.user_repo.find_by_username("aau_foa", session) is None: self.add_user("aau_foa", "password", "AAU", "FOA", "*****@*****.**", session) self.update_max_allowed_devices("aau_foa", 5000, session)
def get_device_state(): """ get the on/off or active/inactive status for the given device """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with device_id '%s' found for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) if not device_service.is_device_simulating(device): resp = { "status": "error", "msg": "device with device_id '%s' not simulating. you need to start simulating it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) resp = { "status": "success", "msg": "device power state fetched", "data": { "power_state": device.device_state.value } } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_dev_token(): username = request.authorization["username"] with session_scope() as session: user = user_service.get_user(username, session) # create authentication token # Identity can be any data that is json serializable exp_delta = datetime.datetime.utcnow() + datetime.timedelta(days=7, hours=0, minutes=0) access_token = create_access_token( identity=user, expires_delta=datetime.timedelta(days=7, hours=0, minutes=0) ) resp = { "token": access_token, "exp": exp_delta, "username": user.username } return make_response(jsonify(resp), status.HTTP_200_OK)
def activate_device(): """ activate device by adding its id to running simulations dict() and also change device state in db """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no such device exists for '%s'" % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) is_activated, resp = device_service.activate_device(device, session) if is_activated: return make_response(jsonify(resp), status.HTTP_200_OK) else: resp = { "status": "error", "msg": "failed ot activate device with device_id '%s'" % device_id } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def update_user(): """ updates a user return: a message indicating the result of the update operation """ try: with session_scope() as session: user = user_service.get_user(get_jwt_identity(), session) if user is None: resp = { "success": "error", "msg": "user not found" } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) if not request.json: abort(400) req_body = AttrDict(json.loads(request.data)) updated_user, resp = user_service.update_user(user, req_body, session) if updated_user is None: return make_response(jsonify(resp), status.HTTP_409_CONFLICT) resp = { "status": "success", "msg": "user updated", "data": { "user": updated_user.serialize() } } LOGGER.debug(resp) return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = {"msg": "error: %s" % str(e)} return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def delete_user(): """ delete a user return: a message indicating the deletion result """ try: username = get_jwt_identity() with session_scope() as session: devices = user_service.get_devices(username, session) for device in devices: device_service.delete_device(username, device.device_id, session) is_deleted = user_service.delete_user(username, session) if not is_deleted: resp = { "status": "error", "msg": "no user with username: '******' found to delete" % username } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "deleted user with username: '******'" % username } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def store_device_consumption_data(): """ stores power consumption for each active device :return: """ global t2 if len(DeviceSimulator.running_simulations) > 0: with session_scope() as session: try: LOGGER.info("Storing device consumption data") for device_id in DeviceSimulator.running_simulations: device = device_repo.find_device_by_id( device_id, session) if device.device_state != DeviceTypeEnum.ON: continue measurement = DeviceSimulator.running_simulations[ device_id].get_measurements() power = measurement["power"] energy = measurement["energy"] state = DeviceSimulator.running_simulations[ device_id].get_power_state() device_consumption = DeviceConsumption( power, energy, state, datetime.datetime.now()) if device is not None: device_repo.add_device_consumption( device, device_consumption, session) LOGGER.debug("completed storing device consumption data") except Exception as e: LOGGER.error(e) t2 = threading.Timer(params.device.storage_interval, DeviceService.store_device_consumption_data) t2.start()
def find_interrupted_device_simulations(): """ :return: """ try: with session_scope() as session: num_interrupted_devices = device_service.find_interrupted_device_simulations(session) resp = { "status": "info", "msg": "found {} devices whose simulation is interrupted due to system crash/restart".format( num_interrupted_devices) } LOGGER.debug(resp) return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def restore_device_simulations(self): """ fetch all devices from the database, and start the device simulation if device state is 'active' but simulation is not running :return: """ LOGGER.info('Restoring device simulations') lock = threading.Lock() lock.acquire() with session_scope() as session: all_devices = self.get_all_devices_for_all_users(session) for device in all_devices: if device.device_state != DeviceTypeEnum.INACTIVE \ and device.device_id not in DeviceSimulator.running_simulations: LOGGER.debug( "device_id={}, device_state={}, is_device__simulation_running={}" .format( device.device_id, device.device_state, device.device_id in DeviceSimulator.running_simulations)) self.start_simulation(device, session) if device.device_state == DeviceTypeEnum.ON: self.turn_on_device(device, session) lock.release()
def user_loader_callback(username): with session_scope() as session: user = UserService.get_user(username, session) return user
def verify_password(username, password): with session_scope() as session: if not user_service.is_user_valid(username, password, session): return False return True
def update_device(): """ updates a given device :return details of the updated device """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with id '%s' exists for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) # retrieve model parameters from request body and validate them is_valid, resp = device_service.validate_device_params(req_params) if not is_valid: return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) # stop simulation if running DeviceService.stop_simulation(device) # update device_name updated_device = device_service.update_device(username, device_id, req_params.device_name, session) # add model to device new_model = DeviceModel(req_params.model_name, req_params.params) updated_device = device_service.update_device_model(updated_device, new_model, session) # restart simulating the updated device device_service.start_simulation(device, session) resp = { "status": "success", "msg": "updated device", "data": updated_device.serialize() } return make_response( jsonify(resp), status.HTTP_200_OK, {'location': url_for(".get_device", device_id=device.device_id)} ) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def register_user(): """ register a new user """ try: if not request.json: abort(400) username = request.json.get('username', None) password = request.json.get('password', None) first_name = request.json.get('first_name', None) last_name = request.json.get('last_name', None) email = request.json.get('email', None) if username is None or password is None: abort(status.HTTP_400_BAD_REQUEST) with session_scope() as session: new_user, resp = user_service.add_user(username, password, first_name, last_name, email, session) if new_user is None: return make_response(jsonify(resp), status.HTTP_409_CONFLICT) # other roles should be added by users with admin privileges user_service.add_role(new_user.username, "end-user", session) if username == "admin": user_service.add_role(new_user.username, "admin", session) # create authentication token exp_delta = datetime.datetime.utcnow() + datetime.timedelta(days=jwt_days, hours=jwt_hours, minutes=jwt_minutes) access_token = create_access_token( identity=new_user, expires_delta=datetime.timedelta(days=jwt_days, hours=jwt_hours, minutes=jwt_minutes) ) resp = { "status": "success", "msg": "new user created", "data": { "user": new_user.serialize(), "auth": { "token": access_token, "exp": exp_delta, } } } LOGGER.debug(resp) return make_response( jsonify(resp), status.HTTP_201_CREATED, {'location': url_for('.get_user', username=new_user.username, _external=True)} ) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_device_consumption(): """ get all historical power consumption data for a device """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with device_id '%s' found for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) if not device_service.is_device_active(device): resp = { "status": "error", "msg": "device with device_id '%s' not active. you need to activate it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) if not device_service.is_device_simulating(device): resp = { "status": "error", "msg": "device with device_id '%s' not simulating. you need to start simulating it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) consumption = device_service.get_device_consumption(device) if consumption is None: resp = { "status": "error", "msg": "no power consumption data found for device with device_id '%s'" % device_id, } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "fetched {} consumption data records for device with device_id '{}'".format(len(consumption), device_id), "data": { "consumption": consumption } } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_device_live_power(): """ get live power consumption (W) for the given device directly from simulation """ try: username = get_jwt_identity() req_params = AttrDict(json.loads(request.data)) device_id = req_params.get("device_id") if device_id is None: resp = { "status": "error", "msg": "request body must contain 'device_id'" } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) with session_scope() as session: device = device_service.get_device(username, device_id, session) if device is None: resp = { "status": "error", "msg": "no device with device_id '%s' found for '%s'" % (device_id, username) } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) if not device_service.is_device_active(device): resp = { "status": "error", "msg": "device with device_id '%s' not active. you need to activate it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) if not device_service.is_device_simulating(device): resp = { "status": "error", "msg": "device with device_id '%s' not simulating. you need to start simulating it first" % device_id } return make_response(jsonify(resp), status.HTTP_400_BAD_REQUEST) measurements = device_service.get_consumption_from_simulation(device) if measurements is None: resp = { "status": "error", "msg": "no simulator class instance associated with device_id '%s'" % device_id } return make_response(jsonify(resp), status.HTTP_404_NOT_FOUND) resp = { "status": "success", "msg": "fetched device live power consumption directly from simulation (i.e., not from db)", "data": { "live_power": measurements["power"] } } return make_response(jsonify(resp), status.HTTP_200_OK) except Exception as e: resp = { "status": "error", "msg": "%s" % str(e) } return make_response(jsonify(resp), status.HTTP_500_INTERNAL_SERVER_ERROR)