Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bbbe39a
Refactor default value assignment in addAutomation function
adityashibu Mar 15, 2025
8910b37
Update trigger time for Test4 automation
adityashibu Mar 15, 2025
2a16fe5
Added base JSON file for the device groups
adityashibu Mar 15, 2025
2e3c9d8
Added base endpoints for groups functionality
david-g-f Mar 15, 2025
19e4807
Overloaded changeDeviceStatus function
david-g-f Mar 15, 2025
f282f46
Completed addGroup function (hopefully no bugs)
david-g-f Mar 15, 2025
6443025
Added necessary error handling
david-g-f Mar 15, 2025
afbb77c
Added deleteGroup function
david-g-f Mar 15, 2025
21903f3
Implemented addDevices function
david-g-f Mar 15, 2025
877cbf9
Add group management UI
adityashibu Mar 15, 2025
b8cb021
Merge branch 'main' of https://github.com/adityashibu/Production
adityashibu Mar 15, 2025
36fdde0
Added removeDevices and changeGroupStatus
david-g-f Mar 15, 2025
0e9c905
Merge branch 'main' of github.com:adityashibu/Production
david-g-f Mar 15, 2025
e094a9a
Refactor group management endpoints to use request models for improve…
adityashibu Mar 15, 2025
eabbe0e
Merge branch 'main' of https://github.com/adityashibu/Production
adityashibu Mar 15, 2025
bfea5e3
Update button styles and fetch device list in Groups component
adityashibu Mar 15, 2025
dc188d0
Refactor user database structure to include device groups with status…
adityashibu Mar 16, 2025
bdb1a94
Refactor group management to associate groups with selected users and…
adityashibu Mar 16, 2025
c1c4ee0
Enhance group management endpoints to associate groups with the selec…
adityashibu Mar 16, 2025
8e4802e
Add AddGroupDialog component for creating new groups with device sele…
adityashibu Mar 16, 2025
75ccd7b
Implement group editing functionality in AddGroupDialog and update re…
adityashibu Mar 16, 2025
a9076fa
Comment out test cases in test_fastAPI.py for future reference
adityashibu Mar 16, 2025
8e82967
Implement group editing functionality and update related API endpoints
adityashibu Mar 16, 2025
4da0442
Add endpoint to update group status and modify frontend to use new API
adityashibu Mar 16, 2025
95f27b1
Completed GROUPS 🙏
adityashibu Mar 16, 2025
9bad42b
Refactor onSave callback in AddGroupDialog for clarity
adityashibu Mar 16, 2025
2805efb
Remove commented-out code and add debugging notes in groups.py
adityashibu Mar 16, 2025
12aaa21
Removed hardcoded value for Automations
adityashibu Mar 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/automations.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"id": 4,
"name": "Test4",
"device_id": 8,
"triggers": "22:23",
"triggers": "23:00",
"enabled": true,
"status": "off"
}
Expand Down
2 changes: 1 addition & 1 deletion backend/automations.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def addAutomation(name, device_id, trigger_time, status):
"name": name,
"device_id": device_id,
"triggers": trigger_time,
"enabled": True, # Always set to True by default
"enabled": True,
"status": status
})
data["automations"] = automations
Expand Down
6 changes: 3 additions & 3 deletions backend/devices_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,15 @@ def changeDeviceName(id, newName):
return {"success": message}
return {"error": "ID not found!"}

def changeDeviceStatus(id):
def changeDeviceStatus(id, status): #Overloading previous function to persist change the status regardless of what it is
data = loadDevicesJSON()
devices = data.get("smart_home_devices", [])

for device in devices:
if device["id"] == id:
device["status"] = "on" if device["status"] == "off" else "off"
device["status"] = status
saveJSON(data)
message = f"Changed {device['name']} status to {device['status']}."
message = f"Changed {device['name']} status to {status}."
updates.append(message)
return {"success": message}
return {"error": "ID not found!"}
Expand Down
44 changes: 41 additions & 3 deletions backend/fastAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import users as u
import energy_json as ej
import automations as am
import groups as gr

import asyncio
import os
Expand Down Expand Up @@ -36,6 +37,18 @@ class DeviceAllocation(BaseModel):
user_id: int
device_ids: List[int]

class GroupRequestNoStatus(BaseModel):
name: str
device_ids: List[int]

class GroupRequestStatus(BaseModel):
name: str
device_ids: List[int]
status: str

class DeviceIdsRequest(BaseModel):
device_ids: List[int]

@app.on_event("startup")
async def startup_event():
"""Starts device updates when the FastAPI server starts."""
Expand All @@ -54,9 +67,9 @@ async def device_info():
return jsonData

@app.post("/device/{id}/status")
def change_device_status(id: int):
def change_device_status(id: int, status: str):
"""Changes the status of a device according to its ID."""
return dj.changeDeviceStatus(id)
return dj.changeDeviceStatus(id, status)

@app.post("/device/{id}/name/{new_name}")
def change_device_name(id: int, new_name: str):
Expand Down Expand Up @@ -173,4 +186,29 @@ def update_automation_status(automation_id: int, status: bool):
@app.delete("/automations/{automation_id}")
def delete_automation(automation_id: int):
"""Delete an automation rule by ID"""
return am.deleteAutomation(automation_id)
return am.deleteAutomation(automation_id)

@app.get("/groups")
def get_groups():
"""Retrieve all groups for the selected user"""
return gr.getGroupsForSelectedUser()

@app.post("/groups/add_group")
def add_group(group: GroupRequestNoStatus):
"""Add a new group to the selected user"""
return gr.addGroup(group.name, group.device_ids)

@app.post("/groups/edit_group/{group_id}")
def edit_group(group_id: int, group: GroupRequestStatus):
"""Edit an existing group for the selected user"""
return gr.editGroup(group_id, group.name, group.device_ids, group.status)

@app.put("/groups/status")
def update_group_status(group_id: int, status: str):
"""FastAPI endpoint to update group status using query parameters"""
return gr.changeGroupStatus(group_id, status)

@app.delete("/groups/{group_id}")
def delete_group(group_id: int):
"""Delete a group from the selected user"""
return gr.deleteGroup(group_id)
153 changes: 153 additions & 0 deletions backend/groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import json
import os
import devices_json as dj

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
usersFile = os.path.abspath(os.path.join(BASE_DIR, "../database/users_db.json"))
selectedUserFile = os.path.abspath(os.path.join(BASE_DIR, "../backend/selected_user.json"))

def get_selected_user():
"""Fetch the selected user from selected_user.json"""
with open(selectedUserFile, "r") as file:
selected_data = json.load(file)
return selected_data.get("selected_user")


def load_users():
"""Load users from users_db.json"""
with open(usersFile, "r") as file:
return json.load(file)


def save_users(data):
"""Save updated user data back to users_db.json"""
with open(usersFile, "w") as file:
json.dump(data, file, indent=4)


def addGroup(name, devices):
"""Add a new group to the selected user's groups"""
if not devices:
return {"error": "No devices selected!"}

if not name:
return {"error": "No group name provided!"}

selected_user = get_selected_user()
users_data = load_users()
user = next((u for u in users_data["users"] if u["user_name"] == selected_user), None)

if not user:
return {"error": "Selected user not found!"}

groups = user.get("device_groups", [])
if any(group["name"] == name for group in groups):
return {"error": "Group name already exists!"}

new_id = max([group["id"] for group in groups] + [0]) + 1
groups.append({
"id": new_id,
"name": name,
"status": "on",
"devices": devices
})
user["device_groups"] = groups

for device in devices:
dj.changeDeviceStatus(device, "on")

save_users(users_data)
return {"success": "Group added successfully!"}


def deleteGroup(group_id):
"""Delete a group from the selected user's groups"""
selected_user = get_selected_user()
users_data = load_users()
user = next((u for u in users_data["users"] if u["user_name"] == selected_user), None)

if not user:
return {"error": "Selected user not found!"}

groups = user.get("device_groups", [])
group = next((g for g in groups if g["id"] == group_id), None)

if not group:
return {"error": "Group not found!"}

groups.remove(group)
user["device_groups"] = groups

save_users(users_data)
return {"success": "Group deleted successfully!"}


def editGroup(group_id, name=None, devices=None, status=None):
"""Edit an existing group by overwriting its details."""
selected_user = get_selected_user()
users_data = load_users()
user = next((u for u in users_data["users"] if u["user_name"] == selected_user), None)

if not user:
return {"error": "Selected user not found!"}

groups = user.get("device_groups", [])
group = next((g for g in groups if g["id"] == group_id), None)

if not group:
return {"error": "Group not found!"}

if name:
group["name"] = name
if status:
group["status"] = status
for device in group["devices"]:
dj.changeDeviceStatus(device, status)
if devices is not None:
group["devices"] = devices

save_users(users_data)
return {"success": "Group updated successfully!"}


def changeGroupStatus(group_id, status):
"""Change the status of a group"""
selected_user = get_selected_user()
users_data = load_users()
user = next((u for u in users_data["users"] if u["user_name"] == selected_user), None)

if not user:
return {"error": "Selected user not found!"}

groups = user.get("device_groups", [])
group = next((g for g in groups if g["id"] == group_id), None)

if not group:
return {"error": "Group not found!"}

group["status"] = status

for device in group["devices"]:
dj.changeDeviceStatus(device, status)

save_users(users_data)
return {"success": "Group status changed successfully!"}


def getGroupsForSelectedUser():
"""Retrieve all groups associated with the selected user."""
selected_user = get_selected_user()
users_data = load_users()
user = next((u for u in users_data["users"] if u["user_name"] == selected_user), None)

if not user:
return {"error": "Selected user not found!"}

result = {"device_groups": user.get("device_groups", [])}
# print(result)
return result

# getGroupsForSelectedUser()

# DEBUGGING SHI #
# deleteGroup(2)
Loading