opensignalbox-interface 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opensignalbox/interface/__init__.py +42 -0
- opensignalbox/interface/adapters/__init__.py +3 -0
- opensignalbox/interface/adapters/base.py +148 -0
- opensignalbox/interface/adapters/controller.py +286 -0
- opensignalbox/interface/adapters/modbus/__init__.py +3 -0
- opensignalbox/interface/adapters/modbus/adapter.py +485 -0
- opensignalbox/interface/assets/favicon.ico +0 -0
- opensignalbox/interface/interfaces/__init__.py +3 -0
- opensignalbox/interface/interfaces/base.py +170 -0
- opensignalbox/interface/interfaces/basicio/__init__.py +3 -0
- opensignalbox/interface/interfaces/basicio/connections.py +239 -0
- opensignalbox/interface/interfaces/basicio/handler.py +1096 -0
- opensignalbox/interface/interfaces/basicio/models.py +165 -0
- opensignalbox/interface/interfaces/bell/__init__.py +3 -0
- opensignalbox/interface/interfaces/bell/connections.py +279 -0
- opensignalbox/interface/interfaces/bell/handler.py +802 -0
- opensignalbox/interface/interfaces/bell/models.py +103 -0
- opensignalbox/interface/interfaces/controller.py +467 -0
- opensignalbox/interface/main.py +187 -0
- opensignalbox/interface/models.py +155 -0
- opensignalbox/interface/routes/__init__.py +4 -0
- opensignalbox/interface/routes/adapters.py +119 -0
- opensignalbox/interface/routes/interfaces.py +104 -0
- opensignalbox/interface/routes.py +204 -0
- opensignalbox/interface/utils.py +29 -0
- opensignalbox/interface/version.py +5 -0
- opensignalbox/interface/web_ui/.gitignore +24 -0
- opensignalbox/interface/web_ui/README.md +5 -0
- opensignalbox/interface/web_ui/WEB_UI_REFACTORING.md +136 -0
- opensignalbox/interface/web_ui/components.json +17 -0
- opensignalbox/interface/web_ui/dist/assets/index-DhsEc6uo.css +2020 -0
- opensignalbox/interface/web_ui/dist/assets/index-t__5JZjf.js +39056 -0
- opensignalbox/interface/web_ui/dist/assets/index-t__5JZjf.js.map +1 -0
- opensignalbox/interface/web_ui/dist/index.html +14 -0
- opensignalbox/interface/web_ui/index.html +13 -0
- opensignalbox/interface/web_ui/package-lock.json +3710 -0
- opensignalbox/interface/web_ui/package.json +39 -0
- opensignalbox/interface/web_ui/src/App.vue +32 -0
- opensignalbox/interface/web_ui/src/assets/favicon.ico +0 -0
- opensignalbox/interface/web_ui/src/assets/index.css +83 -0
- opensignalbox/interface/web_ui/src/components/SharedVariablePicker.vue +112 -0
- opensignalbox/interface/web_ui/src/components/adapters/AdapterList.vue +183 -0
- opensignalbox/interface/web_ui/src/components/adapters/types.ts +35 -0
- opensignalbox/interface/web_ui/src/components/interfaces/InterfaceList.vue +200 -0
- opensignalbox/interface/web_ui/src/components/ui/badge/Badge.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/badge/index.ts +25 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/Breadcrumb.vue +13 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbItem.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbLink.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbList.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbPage.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
- opensignalbox/interface/web_ui/src/components/ui/breadcrumb/index.ts +7 -0
- opensignalbox/interface/web_ui/src/components/ui/button/Button.vue +26 -0
- opensignalbox/interface/web_ui/src/components/ui/button/index.ts +35 -0
- opensignalbox/interface/web_ui/src/components/ui/card/Card.vue +21 -0
- opensignalbox/interface/web_ui/src/components/ui/card/CardContent.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/card/CardDescription.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/card/CardFooter.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/card/CardHeader.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/card/CardTitle.vue +18 -0
- opensignalbox/interface/web_ui/src/components/ui/card/index.ts +6 -0
- opensignalbox/interface/web_ui/src/components/ui/checkbox/Checkbox.vue +33 -0
- opensignalbox/interface/web_ui/src/components/ui/checkbox/index.ts +1 -0
- opensignalbox/interface/web_ui/src/components/ui/collapsible/Collapsible.vue +15 -0
- opensignalbox/interface/web_ui/src/components/ui/collapsible/CollapsibleContent.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/collapsible/CollapsibleTrigger.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/collapsible/index.ts +3 -0
- opensignalbox/interface/web_ui/src/components/ui/command/Command.vue +30 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandDialog.vue +21 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandEmpty.vue +20 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandGroup.vue +29 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandInput.vue +33 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandItem.vue +26 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandList.vue +27 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandSeparator.vue +23 -0
- opensignalbox/interface/web_ui/src/components/ui/command/CommandShortcut.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/command/index.ts +9 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/Dialog.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogClose.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogContent.vue +50 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogDescription.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogFooter.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogHeader.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogScrollContent.vue +59 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogTitle.vue +29 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/DialogTrigger.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/dialog/index.ts +9 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenu.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuContent.vue +38 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuItem.vue +28 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +41 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +33 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
- opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/index.ts +16 -0
- opensignalbox/interface/web_ui/src/components/ui/form/FormControl.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/form/FormDescription.vue +20 -0
- opensignalbox/interface/web_ui/src/components/ui/form/FormItem.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/form/FormLabel.vue +23 -0
- opensignalbox/interface/web_ui/src/components/ui/form/FormMessage.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/form/index.ts +7 -0
- opensignalbox/interface/web_ui/src/components/ui/form/injectionKeys.ts +4 -0
- opensignalbox/interface/web_ui/src/components/ui/form/useFormField.ts +30 -0
- opensignalbox/interface/web_ui/src/components/ui/input/Input.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/input/index.ts +1 -0
- opensignalbox/interface/web_ui/src/components/ui/label/Label.vue +27 -0
- opensignalbox/interface/web_ui/src/components/ui/label/index.ts +1 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/NumberField.vue +23 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldContent.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldDecrement.vue +25 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldIncrement.vue +25 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldInput.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/number-field/index.ts +5 -0
- opensignalbox/interface/web_ui/src/components/ui/popover/Popover.vue +15 -0
- opensignalbox/interface/web_ui/src/components/ui/popover/PopoverContent.vue +48 -0
- opensignalbox/interface/web_ui/src/components/ui/popover/PopoverTrigger.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/popover/index.ts +3 -0
- opensignalbox/interface/web_ui/src/components/ui/radio-group/RadioGroup.vue +25 -0
- opensignalbox/interface/web_ui/src/components/ui/radio-group/RadioGroupItem.vue +39 -0
- opensignalbox/interface/web_ui/src/components/ui/radio-group/index.ts +2 -0
- opensignalbox/interface/web_ui/src/components/ui/scroll-area/ScrollArea.vue +29 -0
- opensignalbox/interface/web_ui/src/components/ui/scroll-area/ScrollBar.vue +30 -0
- opensignalbox/interface/web_ui/src/components/ui/scroll-area/index.ts +2 -0
- opensignalbox/interface/web_ui/src/components/ui/select/Select.vue +15 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectContent.vue +53 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectGroup.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectItem.vue +44 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectItemText.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectLabel.vue +13 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectScrollDownButton.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectScrollUpButton.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectSeparator.vue +17 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectTrigger.vue +31 -0
- opensignalbox/interface/web_ui/src/components/ui/select/SelectValue.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/select/index.ts +11 -0
- opensignalbox/interface/web_ui/src/components/ui/separator/Separator.vue +35 -0
- opensignalbox/interface/web_ui/src/components/ui/separator/index.ts +1 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/Sheet.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetClose.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetContent.vue +56 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetDescription.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetFooter.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetHeader.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetTitle.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/SheetTrigger.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/sheet/index.ts +31 -0
- opensignalbox/interface/web_ui/src/components/ui/table/Table.vue +16 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableBody.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableCaption.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableCell.vue +21 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableEmpty.vue +37 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableFooter.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableHead.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableHeader.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/TableRow.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/table/index.ts +9 -0
- opensignalbox/interface/web_ui/src/components/ui/tabs/Tabs.vue +15 -0
- opensignalbox/interface/web_ui/src/components/ui/tabs/TabsContent.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/tabs/TabsList.vue +25 -0
- opensignalbox/interface/web_ui/src/components/ui/tabs/TabsTrigger.vue +29 -0
- opensignalbox/interface/web_ui/src/components/ui/tabs/index.ts +4 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInput.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputInput.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItem.vue +22 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItemDelete.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItemText.vue +19 -0
- opensignalbox/interface/web_ui/src/components/ui/tags-input/index.ts +5 -0
- opensignalbox/interface/web_ui/src/components/ui/textarea/Textarea.vue +24 -0
- opensignalbox/interface/web_ui/src/components/ui/textarea/index.ts +1 -0
- opensignalbox/interface/web_ui/src/components/ui/tooltip/Tooltip.vue +14 -0
- opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipContent.vue +31 -0
- opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipProvider.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
- opensignalbox/interface/web_ui/src/components/ui/tooltip/index.ts +4 -0
- opensignalbox/interface/web_ui/src/libs/utils.ts +6 -0
- opensignalbox/interface/web_ui/src/main.ts +141 -0
- opensignalbox/interface/web_ui/src/views/Overview.vue +11 -0
- opensignalbox/interface/web_ui/src/views/Settings.vue +6 -0
- opensignalbox/interface/web_ui/src/views/SleafordEast.vue +205 -0
- opensignalbox/interface/web_ui/src/views/adapters/modbus/ModbusAdapterEdit.vue +343 -0
- opensignalbox/interface/web_ui/src/views/adapters/modbus/ModbusAdapterView.vue +270 -0
- opensignalbox/interface/web_ui/src/views/interfaces/InterfaceCreate.vue +0 -0
- opensignalbox/interface/web_ui/src/views/interfaces/basicio/BasicIOInterfaceEdit.vue +795 -0
- opensignalbox/interface/web_ui/src/views/interfaces/basicio/BasicIOInterfaceView.vue +648 -0
- opensignalbox/interface/web_ui/src/views/interfaces/bell/BellInterfaceEdit.vue +790 -0
- opensignalbox/interface/web_ui/src/views/interfaces/bell/BellInterfaceView.vue +437 -0
- opensignalbox/interface/web_ui/src/vite-env.d.ts +1 -0
- opensignalbox/interface/web_ui/tailwind.config.js +94 -0
- opensignalbox/interface/web_ui/tsconfig.app.json +27 -0
- opensignalbox/interface/web_ui/tsconfig.json +30 -0
- opensignalbox/interface/web_ui/tsconfig.node.json +12 -0
- opensignalbox/interface/web_ui/tsconfig.tsbuildinfo +1 -0
- opensignalbox/interface/web_ui/vite.config.d.ts +2 -0
- opensignalbox/interface/web_ui/vite.config.js +60 -0
- opensignalbox/interface/web_ui/vite.config.ts +62 -0
- opensignalbox_interface-0.1.0.dist-info/METADATA +49 -0
- opensignalbox_interface-0.1.0.dist-info/RECORD +209 -0
- opensignalbox_interface-0.1.0.dist-info/WHEEL +4 -0
- opensignalbox_interface-0.1.0.dist-info/entry_points.txt +2 -0
- opensignalbox_interface-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API routes for the opensignalbox-interface module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Annotated, List, Optional
|
|
7
|
+
|
|
8
|
+
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
|
9
|
+
from opensignalbox.common.variables import SharedVariableCollection
|
|
10
|
+
from opensignalbox.interface.adapters.controller import AdapterController
|
|
11
|
+
from opensignalbox.interface.interfaces.controller import InterfaceController
|
|
12
|
+
from opensignalbox.interface.models import (
|
|
13
|
+
AdapterPublic,
|
|
14
|
+
AdapterTypeInfo,
|
|
15
|
+
InterfacePublic,
|
|
16
|
+
InterfaceTypeInfo,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
def get_adapter_controller(request: Request) -> AdapterController:
|
|
22
|
+
return request.app.state.adapters
|
|
23
|
+
|
|
24
|
+
AdapterControllerDependency = Annotated[AdapterController, Depends(get_adapter_controller)]
|
|
25
|
+
|
|
26
|
+
def get_interface_controller(request: Request) -> InterfaceController:
|
|
27
|
+
return request.app.state.interfaces
|
|
28
|
+
|
|
29
|
+
InterfaceControllerDependency = Annotated[InterfaceController, Depends(get_interface_controller)]
|
|
30
|
+
|
|
31
|
+
def get_shared_variables(request: Request) -> SharedVariableCollection:
|
|
32
|
+
return request.app.state.shared_variables
|
|
33
|
+
|
|
34
|
+
SharedVariablesDependency = Annotated[SharedVariableCollection, Depends(get_shared_variables)]
|
|
35
|
+
|
|
36
|
+
interface_router = APIRouter()
|
|
37
|
+
adapter_router = APIRouter()
|
|
38
|
+
|
|
39
|
+
@adapter_router.get("/", response_model=List[AdapterPublic])
|
|
40
|
+
async def get_adapters(
|
|
41
|
+
adapters: AdapterControllerDependency,
|
|
42
|
+
adapter_type: Optional[str] = Query(
|
|
43
|
+
None, description="Filter by adapter type"
|
|
44
|
+
),
|
|
45
|
+
):
|
|
46
|
+
"""Get all adapters, optionally filtered by type."""
|
|
47
|
+
adapters_list = []
|
|
48
|
+
for adapter in adapters.get_all().values():
|
|
49
|
+
# Filter by type if specified
|
|
50
|
+
if adapter_type and adapter.adapter_type != adapter_type:
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
# Convert BaseAdapter to AdapterPublic
|
|
54
|
+
adapter_dict = {
|
|
55
|
+
"system_name": adapter.system_name,
|
|
56
|
+
"user_name": adapter.user_name,
|
|
57
|
+
"description": adapter.description,
|
|
58
|
+
"adapter_type": adapter.adapter_type,
|
|
59
|
+
"enabled": adapter.enabled,
|
|
60
|
+
"is_connected": adapter.is_connected,
|
|
61
|
+
}
|
|
62
|
+
adapters_list.append(AdapterPublic(**adapter_dict))
|
|
63
|
+
return adapters_list
|
|
64
|
+
|
|
65
|
+
@interface_router.get("/", response_model=List[InterfacePublic])
|
|
66
|
+
async def get_interfaces(
|
|
67
|
+
interfaces: InterfaceControllerDependency,
|
|
68
|
+
interface_type: Optional[str] = Query(
|
|
69
|
+
None, description="Filter by interface type"
|
|
70
|
+
),
|
|
71
|
+
):
|
|
72
|
+
"""Get all interfaces, optionally filtered by type."""
|
|
73
|
+
interfaces_list = []
|
|
74
|
+
for interface in interfaces.get_all().values():
|
|
75
|
+
# Filter by type if specified
|
|
76
|
+
if interface_type and interface.interface_type != interface_type:
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
interfaces_list.append(interface)
|
|
80
|
+
return interfaces_list
|
|
81
|
+
|
|
82
|
+
@adapter_router.put("/adapters/{system_name}/enable", response_model=AdapterPublic)
|
|
83
|
+
async def enable_adapter(system_name: str, adapters: AdapterControllerDependency):
|
|
84
|
+
"""Enable a specific adapter."""
|
|
85
|
+
adapter = adapters.get(system_name)
|
|
86
|
+
if not adapter:
|
|
87
|
+
raise HTTPException(status_code=404, detail="Adapter not found")
|
|
88
|
+
adapter.enabled = True
|
|
89
|
+
adapter_dict = {
|
|
90
|
+
"system_name": adapter.system_name,
|
|
91
|
+
"user_name": adapter.user_name,
|
|
92
|
+
"description": adapter.description,
|
|
93
|
+
"adapter_type": adapter.adapter_type,
|
|
94
|
+
"enabled": adapter.enabled,
|
|
95
|
+
"is_connected": adapter.is_connected,
|
|
96
|
+
}
|
|
97
|
+
return AdapterPublic(**adapter_dict)
|
|
98
|
+
|
|
99
|
+
@adapter_router.put(
|
|
100
|
+
"/adapters/{system_name}/disable", response_model=AdapterPublic
|
|
101
|
+
)
|
|
102
|
+
async def disable_adapter(system_name: str, adapters: AdapterControllerDependency):
|
|
103
|
+
"""Disable a specific adapter."""
|
|
104
|
+
adapter = adapters.get(system_name)
|
|
105
|
+
if not adapter:
|
|
106
|
+
raise HTTPException(status_code=404, detail="Adapter not found")
|
|
107
|
+
adapter.enabled = False
|
|
108
|
+
adapter_dict = {
|
|
109
|
+
"system_name": adapter.system_name,
|
|
110
|
+
"user_name": adapter.user_name,
|
|
111
|
+
"description": adapter.description,
|
|
112
|
+
"adapter_type": adapter.adapter_type,
|
|
113
|
+
"enabled": adapter.enabled,
|
|
114
|
+
"is_connected": adapter.is_connected,
|
|
115
|
+
}
|
|
116
|
+
return AdapterPublic(**adapter_dict)
|
|
117
|
+
|
|
118
|
+
@adapter_router.put(
|
|
119
|
+
"/adapters/{system_name}/connect", response_model=AdapterPublic
|
|
120
|
+
)
|
|
121
|
+
async def connect_adapter(system_name: str, adapters: AdapterControllerDependency):
|
|
122
|
+
"""Connect a specific adapter."""
|
|
123
|
+
adapter = adapters.get(system_name)
|
|
124
|
+
if not adapter:
|
|
125
|
+
raise HTTPException(status_code=404, detail="Adapter not found")
|
|
126
|
+
if adapter.connect():
|
|
127
|
+
return adapter
|
|
128
|
+
else:
|
|
129
|
+
raise HTTPException(status_code=500, detail="Failed to connect adapter")
|
|
130
|
+
|
|
131
|
+
@adapter_router.put(
|
|
132
|
+
"/adapters/{system_name}/disconnect", response_model=AdapterPublic
|
|
133
|
+
)
|
|
134
|
+
async def disconnect_adapter(system_name: str, adapters: AdapterControllerDependency):
|
|
135
|
+
"""Disconnect a specific adapter."""
|
|
136
|
+
adapter = adapters.get(system_name)
|
|
137
|
+
if not adapter:
|
|
138
|
+
raise HTTPException(status_code=404, detail="Adapter not found")
|
|
139
|
+
adapter.disconnect()
|
|
140
|
+
return adapter
|
|
141
|
+
|
|
142
|
+
@interface_router.put(
|
|
143
|
+
"/interfaces/{system_name}/disable", response_model=InterfacePublic
|
|
144
|
+
)
|
|
145
|
+
async def disable_interface(system_name: str, interfaces: InterfaceControllerDependency):
|
|
146
|
+
"""Disable a specific interface."""
|
|
147
|
+
interface = interfaces.get(system_name)
|
|
148
|
+
if not interface:
|
|
149
|
+
raise HTTPException(status_code=404, detail="Interface not found")
|
|
150
|
+
interface.enabled = False
|
|
151
|
+
return interface
|
|
152
|
+
|
|
153
|
+
@interface_router.put(
|
|
154
|
+
"/interfaces/{system_name}/enable", response_model=InterfacePublic
|
|
155
|
+
)
|
|
156
|
+
async def enable_interface(system_name: str, interfaces: InterfaceControllerDependency):
|
|
157
|
+
"""Enable a specific interface."""
|
|
158
|
+
interface = interfaces.get(system_name)
|
|
159
|
+
if not interface:
|
|
160
|
+
raise HTTPException(status_code=404, detail="Interface not found")
|
|
161
|
+
interface.enabled = True
|
|
162
|
+
return interface
|
|
163
|
+
|
|
164
|
+
@interface_router.put(
|
|
165
|
+
"/interfaces/{system_name}/connect", response_model=InterfacePublic
|
|
166
|
+
)
|
|
167
|
+
async def connect_interface(system_name: str, interfaces: InterfaceControllerDependency):
|
|
168
|
+
"""Connect a specific interface."""
|
|
169
|
+
interface = interfaces.get(system_name)
|
|
170
|
+
if not interface:
|
|
171
|
+
raise HTTPException(status_code=404, detail="Interface not found")
|
|
172
|
+
handler = interfaces.interface_handlers.get(interface.interface_type)
|
|
173
|
+
if handler and handler.connect(interface):
|
|
174
|
+
return interface
|
|
175
|
+
else:
|
|
176
|
+
raise HTTPException(
|
|
177
|
+
status_code=500, detail="Failed to connect interface"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
@interface_router.put(
|
|
181
|
+
"/interfaces/{system_name}/disconnect", response_model=InterfacePublic
|
|
182
|
+
)
|
|
183
|
+
async def disconnect_interface(system_name: str, interfaces: InterfaceControllerDependency):
|
|
184
|
+
"""Disconnect a specific interface."""
|
|
185
|
+
interface = interfaces.get(system_name)
|
|
186
|
+
if not interface:
|
|
187
|
+
raise HTTPException(status_code=404, detail="Interface not found")
|
|
188
|
+
handler = interfaces.interface_handlers.get(interface.interface_type)
|
|
189
|
+
if handler and handler.disconnect(interface):
|
|
190
|
+
return interface
|
|
191
|
+
else:
|
|
192
|
+
raise HTTPException(
|
|
193
|
+
status_code=500, detail="Failed to disconnect interface"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
@adapter_router.get("/types/adapters", response_model=List[AdapterTypeInfo])
|
|
197
|
+
async def get_adapter_types(adapters: AdapterControllerDependency):
|
|
198
|
+
"""Get all available adapter types with their metadata."""
|
|
199
|
+
return adapters.get_adapter_type_infos()
|
|
200
|
+
|
|
201
|
+
@interface_router.get("/types/interfaces", response_model=List[InterfaceTypeInfo])
|
|
202
|
+
async def get_interface_types(interfaces: InterfaceControllerDependency):
|
|
203
|
+
"""Get all available interface types with their metadata."""
|
|
204
|
+
return interfaces.get_interface_type_infos()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility functions for the opensignalbox-interface module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def swap_bytes(data: int) -> int:
|
|
7
|
+
"""
|
|
8
|
+
Swap the bytes in a 16-bit word.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
data: The 16-bit word to swap
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
The bytes-swapped word
|
|
15
|
+
"""
|
|
16
|
+
return ((data & 0xFF) << 8) | ((data >> 8) & 0xFF)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def swap_words(data: int) -> int:
|
|
20
|
+
"""
|
|
21
|
+
Swap the words in a 32-bit double word.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
data: The 32-bit double word to swap
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
The words-swapped double word
|
|
28
|
+
"""
|
|
29
|
+
return ((data & 0xFFFF) << 16) | ((data >> 16) & 0xFFFF)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
#dist
|
|
12
|
+
#dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
.vscode/*
|
|
17
|
+
!.vscode/extensions.json
|
|
18
|
+
.idea
|
|
19
|
+
.DS_Store
|
|
20
|
+
*.suo
|
|
21
|
+
*.ntvs*
|
|
22
|
+
*.njsproj
|
|
23
|
+
*.sln
|
|
24
|
+
*.sw?
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Vue 3 + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
4
|
+
|
|
5
|
+
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Web UI Architecture Refactoring
|
|
2
|
+
|
|
3
|
+
This document describes the refactored web UI structure for adapters and interfaces.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
├── components/
|
|
10
|
+
│ ├── ui/ # shadcn components (unchanged)
|
|
11
|
+
│ ├── adapters/ # Adapter-related components
|
|
12
|
+
│ │ ├── AdapterList.vue # Main adapter list component
|
|
13
|
+
│ │ ├── BaseAdapterEdit.vue # Reusable adapter edit component
|
|
14
|
+
│ │ ├── BaseAdapterView.vue # Reusable adapter view component
|
|
15
|
+
│ │ └── types.ts # Shared adapter types
|
|
16
|
+
│ ├── interfaces/ # Interface-related components
|
|
17
|
+
│ │ └── InterfaceList.vue # Main interface list component
|
|
18
|
+
│ └── SharedVariablePicker.vue
|
|
19
|
+
├── views/
|
|
20
|
+
│ ├── adapters/ # Adapter-specific views
|
|
21
|
+
│ │ ├── AdapterCreate.vue # Adapter type selection
|
|
22
|
+
│ │ ├── ModbusAdapterEdit.vue # Modbus-specific edit form
|
|
23
|
+
│ │ └── ModbusAdapterView.vue # Modbus-specific view
|
|
24
|
+
│ ├── interfaces/ # Interface-specific views
|
|
25
|
+
│ │ ├── InterfaceCreate.vue # Interface type selection
|
|
26
|
+
│ │ ├── SimpleInterfaceEdit.vue # Simple interface edit
|
|
27
|
+
│ │ ├── SimpleInterfaceView.vue # Simple interface view
|
|
28
|
+
│ │ ├── BellInterfaceEdit.vue # Bell interface edit
|
|
29
|
+
│ │ └── BellInterfaceView.vue # Bell interface view
|
|
30
|
+
│ ├── Overview.vue # Main dashboard
|
|
31
|
+
│ └── Settings.vue # Settings page
|
|
32
|
+
└── main.ts # Router configuration
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Key Improvements
|
|
36
|
+
|
|
37
|
+
### 1. Separation of Concerns
|
|
38
|
+
- **Components**: Reusable UI components organized by feature
|
|
39
|
+
- **Views**: Page-level components for specific routes
|
|
40
|
+
- **Types**: Shared TypeScript interfaces
|
|
41
|
+
|
|
42
|
+
### 2. Adapter Type System
|
|
43
|
+
- **Base Components**: `BaseAdapterEdit.vue` and `BaseAdapterView.vue` provide common functionality
|
|
44
|
+
- **Type-Specific Views**: Each adapter type (e.g., Modbus) has its own edit/view components
|
|
45
|
+
- **Extensible**: Easy to add new adapter types by extending base components
|
|
46
|
+
|
|
47
|
+
### 3. Routing Structure
|
|
48
|
+
```
|
|
49
|
+
/adapters/create # Select adapter type
|
|
50
|
+
/adapters/create/modbus # Create Modbus adapter
|
|
51
|
+
/adapters/edit/modbus/:name # Edit Modbus adapter
|
|
52
|
+
/adapters/view/modbus/:name # View Modbus adapter
|
|
53
|
+
|
|
54
|
+
/interfaces/create # Select interface type
|
|
55
|
+
/interfaces/create/simple # Create simple interface
|
|
56
|
+
/interfaces/edit/simple/:name # Edit simple interface
|
|
57
|
+
/interfaces/view/simple/:name # View simple interface
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Adding New Adapter Types
|
|
61
|
+
|
|
62
|
+
To add a new adapter type (e.g., "Serial"):
|
|
63
|
+
|
|
64
|
+
### 1. Create Type-Specific Components
|
|
65
|
+
|
|
66
|
+
**views/adapters/SerialAdapterEdit.vue**:
|
|
67
|
+
```vue
|
|
68
|
+
<script setup lang="ts">
|
|
69
|
+
import BaseAdapterEdit from '@/components/adapters/BaseAdapterEdit.vue'
|
|
70
|
+
// Import additional components as needed
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<BaseAdapterEdit
|
|
75
|
+
adapter-type="Serial"
|
|
76
|
+
adapter-type-name="Serial"
|
|
77
|
+
adapter-description="Configure your Serial adapter settings"
|
|
78
|
+
:show-network-config="false"
|
|
79
|
+
:show-baud-config="true"
|
|
80
|
+
>
|
|
81
|
+
<template #additional-cards="{ adapterIsNetworkState }">
|
|
82
|
+
<!-- Serial-specific configuration cards -->
|
|
83
|
+
</template>
|
|
84
|
+
</BaseAdapterEdit>
|
|
85
|
+
</template>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**views/adapters/SerialAdapterView.vue**:
|
|
89
|
+
```vue
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import BaseAdapterView from '@/components/adapters/BaseAdapterView.vue'
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<template>
|
|
95
|
+
<BaseAdapterView
|
|
96
|
+
adapter-type="Serial"
|
|
97
|
+
adapter-type-name="Serial"
|
|
98
|
+
edit-route="/adapters/edit/serial"
|
|
99
|
+
>
|
|
100
|
+
<template #adapter-specific="{ adapter }">
|
|
101
|
+
<!-- Serial-specific information cards -->
|
|
102
|
+
</template>
|
|
103
|
+
</BaseAdapterView>
|
|
104
|
+
</template>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 2. Update Router Configuration
|
|
108
|
+
|
|
109
|
+
Add routes to `main.ts`:
|
|
110
|
+
```typescript
|
|
111
|
+
// In the routes array
|
|
112
|
+
{ path: '/adapters/create/serial', name: 'Create Serial Adapter', component: SerialAdapterEdit },
|
|
113
|
+
{ path: '/adapters/edit/serial/:name', name: 'Edit Serial Adapter', component: SerialAdapterEdit },
|
|
114
|
+
{ path: '/adapters/view/serial/:name', name: 'View Serial Adapter', component: SerialAdapterView },
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 3. Backend Support
|
|
118
|
+
|
|
119
|
+
Ensure the backend API returns the new adapter type in:
|
|
120
|
+
- `/api/types/adapters` - Include the new adapter type metadata
|
|
121
|
+
- Adapter CRUD operations support the new type
|
|
122
|
+
|
|
123
|
+
## Benefits
|
|
124
|
+
|
|
125
|
+
1. **Maintainability**: Clear separation between reusable components and specific implementations
|
|
126
|
+
2. **Scalability**: Easy to add new adapter and interface types
|
|
127
|
+
3. **Consistency**: Base components ensure consistent UI/UX across all types
|
|
128
|
+
4. **Type Safety**: TypeScript interfaces provide compile-time checking
|
|
129
|
+
5. **Developer Experience**: Clear structure makes it easy for developers to understand and extend
|
|
130
|
+
|
|
131
|
+
## Migration Notes
|
|
132
|
+
|
|
133
|
+
- Old `AdapterEdit.vue` has been replaced with type-specific components
|
|
134
|
+
- `AdapterList.vue` now works similarly to `InterfaceList.vue` with dropdown navigation
|
|
135
|
+
- Routes have been restructured to include type information
|
|
136
|
+
- All existing functionality is preserved with improved organization
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://shadcn-vue.com/schema.json",
|
|
3
|
+
"style": "default",
|
|
4
|
+
"typescript": true,
|
|
5
|
+
"tsConfigPath": "./tsconfig.json",
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "tailwind.config.js",
|
|
8
|
+
"css": "src/assets/index.css",
|
|
9
|
+
"baseColor": "slate",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"framework": "vite",
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@/components",
|
|
15
|
+
"utils": "@/libs/utils"
|
|
16
|
+
}
|
|
17
|
+
}
|