diff --git a/easy-asterisk-v0.10.0.sh b/easy-asterisk-v0.10.0.sh
index 6adfdb2..c890bdc 100644
--- a/easy-asterisk-v0.10.0.sh
+++ b/easy-asterisk-v0.10.0.sh
@@ -4090,6 +4090,136 @@ def remove_device_from_room(room_ext, device_ext):
return update_room_members(room_ext, new_members)
return False, "Room not found"
+def change_device_category(extension, new_category):
+ """Change a device's category in pjsip.conf"""
+ if not os.path.exists(PJSIP_CONF):
+ return False, "Config file not found"
+
+ with open(PJSIP_CONF, 'r') as f:
+ lines = f.readlines()
+
+ new_lines = []
+ found = False
+ in_device = False
+
+ for line in lines:
+ stripped = line.strip()
+
+ # Match device comment line: ; === Device: Name (category) ===
+ if stripped.startswith('; === Device:') and f'[{extension}]' in ''.join(lines[lines.index(line):lines.index(line)+3]):
+ # Parse and update category in comment
+ match = re.match(r'^; === Device: (.+?) \(([^)]+)\)(.*?)===', stripped)
+ if match:
+ name = match.group(1)
+ old_cat = match.group(2)
+ rest = match.group(3)
+ new_lines.append(f'; === Device: {name} ({new_category}){rest}===\n')
+ found = True
+ in_device = True
+ continue
+
+ new_lines.append(line)
+
+ if found:
+ with open(PJSIP_CONF, 'w') as f:
+ f.writelines(new_lines)
+ subprocess.run(['asterisk', '-rx', 'pjsip reload'], capture_output=True)
+ return True, "Category changed"
+ return False, "Device not found"
+
+def create_room(extension, name, room_type='ring', timeout='60'):
+ """Create a new room in rooms.conf"""
+ if not os.path.exists(ROOMS_FILE):
+ with open(ROOMS_FILE, 'w') as f:
+ f.write('# Format: ext|name|members|timeout|type(ring/page)\n')
+
+ # Check if extension already exists
+ with open(ROOMS_FILE, 'r') as f:
+ for line in f:
+ if line.strip() and not line.startswith('#'):
+ parts = line.split('|')
+ if len(parts) >= 1 and parts[0] == extension:
+ return False, "Room extension already exists"
+
+ # Add new room
+ with open(ROOMS_FILE, 'a') as f:
+ f.write(f'{extension}|{name}||{timeout}|{room_type}\n')
+
+ # Rebuild dialplan
+ subprocess.run(['/usr/local/bin/easy-asterisk', '--rebuild-dialplan'], capture_output=True)
+ return True, "Room created"
+
+def delete_room(extension):
+ """Delete a room from rooms.conf"""
+ if not os.path.exists(ROOMS_FILE):
+ return False, "Rooms file not found"
+
+ with open(ROOMS_FILE, 'r') as f:
+ lines = f.readlines()
+
+ new_lines = []
+ found = False
+ for line in lines:
+ stripped = line.strip()
+ if stripped and not stripped.startswith('#'):
+ parts = stripped.split('|')
+ if len(parts) >= 1 and parts[0] == extension:
+ found = True
+ continue
+ new_lines.append(line)
+
+ if found:
+ with open(ROOMS_FILE, 'w') as f:
+ f.writelines(new_lines)
+ subprocess.run(['/usr/local/bin/easy-asterisk', '--rebuild-dialplan'], capture_output=True)
+ return True, "Room deleted"
+ return False, "Room not found"
+
+def create_category(cat_id, name, auto_answer='', description=''):
+ """Create a new category in categories.conf"""
+ if not os.path.exists(CATEGORIES_FILE):
+ with open(CATEGORIES_FILE, 'w') as f:
+ f.write('# Format: id|name|auto_answer|description\n')
+
+ # Check if category already exists
+ with open(CATEGORIES_FILE, 'r') as f:
+ for line in f:
+ if line.strip() and not line.startswith('#'):
+ parts = line.split('|')
+ if len(parts) >= 1 and parts[0] == cat_id:
+ return False, "Category ID already exists"
+
+ # Add new category
+ with open(CATEGORIES_FILE, 'a') as f:
+ f.write(f'{cat_id}|{name}|{auto_answer}|{description}\n')
+
+ return True, "Category created"
+
+def delete_category(cat_id):
+ """Delete a category from categories.conf"""
+ if not os.path.exists(CATEGORIES_FILE):
+ return False, "Categories file not found"
+
+ with open(CATEGORIES_FILE, 'r') as f:
+ lines = f.readlines()
+
+ new_lines = []
+ found = False
+ for line in lines:
+ stripped = line.strip()
+ if stripped and not stripped.startswith('#'):
+ parts = stripped.split('|')
+ if len(parts) >= 1 and parts[0] == cat_id:
+ found = True
+ continue
+ new_lines.append(line)
+
+ if found:
+ with open(CATEGORIES_FILE, 'w') as f:
+ f.writelines(new_lines)
+ return True, "Category deleted"
+ return False, "Category not found"
+
def generate_password(length=16):
"""Generate a random password"""
import secrets
@@ -4379,22 +4509,12 @@ HTML_TEMPLATE = '''