From 7f12fa700397c55a2e7984e7398698293d13e87b Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 1 Feb 2026 17:27:44 +0300 Subject: [PATCH 1/2] Update devices.py --- app/handlers/subscription/devices.py | 38 ++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/app/handlers/subscription/devices.py b/app/handlers/subscription/devices.py index eae31393..3dbc94ff 100644 --- a/app/handlers/subscription/devices.py +++ b/app/handlers/subscription/devices.py @@ -561,7 +561,7 @@ async def execute_change_devices(callback: types.CallbackQuery, db_user: User, d subscription_service = SubscriptionService() await subscription_service.update_remnawave_user(db, subscription) - # При уменьшении лимита - сбросить лишние устройства + # При уменьшении лимита - удалить лишние устройства (последние подключённые) devices_reset_count = 0 if new_devices_count < current_devices and db_user.remnawave_uuid: try: @@ -572,16 +572,34 @@ async def execute_change_devices(callback: types.CallbackQuery, db_user: User, d devices_list = response['response'].get('devices', []) connected_count = len(devices_list) - # Если подключённых устройств больше чем новый лимит - сбросить все + # Если подключённых устройств больше чем новый лимит - удалить лишние if connected_count > new_devices_count: + devices_to_remove = connected_count - new_devices_count logger.info( - f'🔧 Сброс устройств при уменьшении лимита: ' - f'подключено {connected_count}, новый лимит {new_devices_count}' + f'🔧 Удаление лишних устройств при уменьшении лимита: ' + f'подключено {connected_count}, новый лимит {new_devices_count}, ' + f'удаляем {devices_to_remove}' ) - await api.reset_user_devices(db_user.remnawave_uuid) - devices_reset_count = connected_count + + # Сортируем по дате (последние в конце) и удаляем последние + sorted_devices = sorted( + devices_list, + key=lambda d: d.get('updatedAt') or d.get('createdAt') or '', + ) + devices_to_delete = sorted_devices[-devices_to_remove:] + + for device in devices_to_delete: + device_hwid = device.get('hwid') + if device_hwid: + try: + delete_data = {'userUuid': db_user.remnawave_uuid, 'hwid': device_hwid} + await api._make_request('POST', '/api/hwid/devices/delete', data=delete_data) + devices_reset_count += 1 + logger.info(f'✅ Удалено устройство {device_hwid}') + except Exception as del_error: + logger.error(f'Ошибка удаления устройства {device_hwid}: {del_error}') except Exception as reset_error: - logger.error(f'Ошибка сброса устройств при уменьшении лимита: {reset_error}') + logger.error(f'Ошибка удаления устройств при уменьшении лимита: {reset_error}') await db.refresh(db_user) await db.refresh(subscription) @@ -621,9 +639,9 @@ async def execute_change_devices(callback: types.CallbackQuery, db_user: User, d ).format(old=current_devices, new=new_devices_count) if devices_reset_count > 0: success_text += texts.t( - 'DEVICE_CHANGE_DEVICES_RESET', - '\n🔄 Сброшено устройств: {count}\n💡 Подключите заново нужные устройства (до {limit} шт.)\n\n', - ).format(count=devices_reset_count, limit=new_devices_count) + 'DEVICE_CHANGE_DEVICES_REMOVED', + '\n🗑 Удалено устройств: {count}\n', + ).format(count=devices_reset_count) success_text += texts.t( 'DEVICE_CHANGE_NO_REFUND_INFO', 'ℹ️ Возврат средств не производится', From bf6a9666683c6d9e66d94e901215fb496cc1b163 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 1 Feb 2026 17:28:21 +0300 Subject: [PATCH 2/2] Update subscription.py --- app/cabinet/routes/subscription.py | 47 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/app/cabinet/routes/subscription.py b/app/cabinet/routes/subscription.py index 8794f619..112ce8e4 100644 --- a/app/cabinet/routes/subscription.py +++ b/app/cabinet/routes/subscription.py @@ -3388,26 +3388,45 @@ async def reduce_devices( detail=f'Cannot reduce below minimum device limit ({min_device_limit}) for your tariff', ) - # Get connected devices count and reset if needed + # Get connected devices and remove excess (last connected ones) connected_devices_count = 0 - devices_reset = False + devices_removed_count = 0 if user.remnawave_uuid: try: service = RemnaWaveService() async with service.get_api_client() as api: response = await api._make_request('GET', f'/api/hwid/devices/{user.remnawave_uuid}') if response and 'response' in response: - connected_devices_count = response['response'].get('total', 0) + devices_list = response['response'].get('devices', []) + connected_devices_count = len(devices_list) - # If connected devices exceed new limit, reset all devices - if connected_devices_count > new_device_limit: - await api.reset_user_devices(user.remnawave_uuid) - devices_reset = True - logger.info( - f'Reset devices for user {user.id}: had {connected_devices_count}, new limit {new_device_limit}' - ) + # If connected devices exceed new limit, remove excess (last connected) + if connected_devices_count > new_device_limit: + devices_to_remove = connected_devices_count - new_device_limit + logger.info( + f'Removing {devices_to_remove} excess devices for user {user.id}: ' + f'had {connected_devices_count}, new limit {new_device_limit}' + ) + + # Sort by date (oldest first) and remove the last ones + sorted_devices = sorted( + devices_list, + key=lambda d: d.get('updatedAt') or d.get('createdAt') or '', + ) + devices_to_delete = sorted_devices[-devices_to_remove:] + + for device in devices_to_delete: + device_hwid = device.get('hwid') + if device_hwid: + try: + delete_data = {'userUuid': user.remnawave_uuid, 'hwid': device_hwid} + await api._make_request('POST', '/api/hwid/devices/delete', data=delete_data) + devices_removed_count += 1 + logger.info(f'Removed device {device_hwid} for user {user.id}') + except Exception as del_error: + logger.error(f'Error removing device {device_hwid}: {del_error}') except Exception as e: - logger.error(f'Error checking/resetting devices: {e}') + logger.error(f'Error checking/removing devices: {e}') old_device_limit = current_device_limit @@ -3425,14 +3444,16 @@ async def reduce_devices( logger.info( f'User {user.id} reduced device limit from {old_device_limit} to {new_device_limit}' - + (' (devices reset)' if devices_reset else '') + + (f' (removed {devices_removed_count} devices)' if devices_removed_count > 0 else '') ) return { 'success': True, - 'message': 'Device limit reduced successfully' + (' (devices reset)' if devices_reset else ''), + 'message': 'Device limit reduced successfully' + + (f' ({devices_removed_count} devices removed)' if devices_removed_count > 0 else ''), 'old_device_limit': old_device_limit, 'new_device_limit': new_device_limit, + 'devices_removed': devices_removed_count, }