This document provides the detailed steps and Python code required to set up and manage the Schlage smart lock system for multi-lock access control, dynamic PIN management, and member revocation.
This system integrates a Schlage smart lock system with a REST API for member management. It includes:
- Dynamic 8-Digit PIN Management:
- Format:
- 1st digit: Lock ID.
- 2nd–4th digits: User ID.
- 5th–8th digits: Unique PIN for each user.
- Format:
- Multi-Lock Support:
- Each lock is identified by a unique single-digit
lock_id
.
- Each lock is identified by a unique single-digit
- Member Revocation:
- Members marked as inactive in the REST API will have their PINs removed from the specified lock.
- Member PIN Updates:
- Allows members to change their PINs securely.
-
Python Libraries:
pyschlage
: For Schlage lock management.requests
: For interacting with the REST API. Install dependencies:
pip install pyschlage requests
-
REST API:
- Endpoint:
GET /api/members
. - JSON Response:
[ {"name": "Amber Simons", "user_id": "139", "active": true}, {"name": "Mark Walters", "user_id": "455", "active": false}, {"name": "Maggie Campbell", "user_id": "122", "active": true} ]
- Endpoint:
- Schlage WiFi locks, integrated with the
pyschlage
Python library.
import random
import requests
from pyschlage import Auth, Schlage
from pyschlage.code import AccessCode
# API endpoint for member data
API_URL = "https://example.com/api/members"
# Authentication for Schlage lock
AUTH = Auth(username="your_username", password="your_password")
schlage = Schlage(AUTH)
# Retrieve a lock by lock_id
def get_lock_by_id(lock_id):
for lock in schlage.locks():
if lock.name.endswith(str(lock_id)): # Assuming lock names include the lock ID
return lock
raise Exception(f"Lock with ID {lock_id} not found.")
# Fetch current members from REST API
def fetch_members():
response = requests.get(API_URL)
response.raise_for_status()
return response.json()
# Generate a unique 4-digit PIN
def generate_unique_pin(existing_pins):
while True:
pin = f"{random.randint(1000, 9999)}"
if pin not in existing_pins:
return pin
# Update lock with member PINs
def update_pins(lock_id):
lock = get_lock_by_id(lock_id)
members = fetch_members()
existing_pins = []
updated_pins = []
for member in members:
full_pin = None
if member["active"]:
# Generate or reuse a PIN for active members
four_digit_pin = generate_unique_pin(existing_pins)
existing_pins.append(four_digit_pin)
# Create the 8-digit PIN
full_pin = f"{lock_id}{member['user_id']}{four_digit_pin}"
# Update or add the access code
access_code = AccessCode(name=member["name"], code=full_pin)
lock.add_access_code(access_code)
updated_pins.append({"name": member["name"], "pin": full_pin})
else:
# Revoke access for inactive members
for code_id, access_code in lock.access_codes.items():
if access_code.name == member["name"]:
access_code.delete()
# Save updated pins to a file
with open(f"lock_{lock_id}_pins.txt", "w") as file:
for pin_info in updated_pins:
file.write(f"{pin_info['name']} - PIN: {pin_info['pin']}\n")
print(f"Pins updated for lock ID {lock_id}. Saved to 'lock_{lock_id}_pins.txt'.")
# Change a member's PIN
def change_member_pin(lock_id, user_id, current_full_pin, new_four_digit_pin):
lock = get_lock_by_id(lock_id)
# Create the new 8-digit PIN
new_full_pin = f"{lock_id}{user_id}{new_four_digit_pin}"
# Fetch existing access codes
for code_id, access_code in lock.access_codes.items():
if access_code.code == current_full_pin:
# Update the access code with the new PIN
access_code.code = new_full_pin
access_code.save()
print(f"PIN for user ID {user_id} updated successfully in lock ID {lock_id}.")
return
raise Exception("Current PIN not found or invalid.")
To update all member PINs for a specific lock:
update_pins(lock_id=1)
- This will:
- Fetch the member list from the REST API.
- Generate 8-digit PINs for active members.
- Remove access for inactive members.
- Save the updated PINs to
lock_1_pins.txt
.
To change a member’s PIN for a specific lock:
change_member_pin(lock_id=1, user_id="139", current_full_pin="11394827", new_four_digit_pin="5678")
- Inputs:
lock_id
: Lock ID for the target lock.user_id
: 3-digit user ID.current_full_pin
: Current 8-digit PIN.new_four_digit_pin
: New 4-digit PIN for the user.
After running update_pins
, the file lock_1_pins.txt
might look like:
Amber Simons - PIN: 11394827
Maggie Campbell - PIN: 11229145
-
Secure REST API Access:
- Use HTTPS for the REST API.
- Authenticate API requests with tokens.
-
PIN Management:
- Ensure PIN uniqueness.
- Encrypt
lock_{lock_id}_pins.txt
or restrict its access.
-
Audit Logs:
- Enable and monitor lock logs for PIN usage.
-
Periodic PIN Rotation:
- Regularly update member PINs for enhanced security.
This system ensures efficient and secure access control with support for multi-lock management, dynamic PIN updates, and real-time member revocation. For questions or setup assistance, feel free to reach out!