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.
Files changed (209) hide show
  1. opensignalbox/interface/__init__.py +42 -0
  2. opensignalbox/interface/adapters/__init__.py +3 -0
  3. opensignalbox/interface/adapters/base.py +148 -0
  4. opensignalbox/interface/adapters/controller.py +286 -0
  5. opensignalbox/interface/adapters/modbus/__init__.py +3 -0
  6. opensignalbox/interface/adapters/modbus/adapter.py +485 -0
  7. opensignalbox/interface/assets/favicon.ico +0 -0
  8. opensignalbox/interface/interfaces/__init__.py +3 -0
  9. opensignalbox/interface/interfaces/base.py +170 -0
  10. opensignalbox/interface/interfaces/basicio/__init__.py +3 -0
  11. opensignalbox/interface/interfaces/basicio/connections.py +239 -0
  12. opensignalbox/interface/interfaces/basicio/handler.py +1096 -0
  13. opensignalbox/interface/interfaces/basicio/models.py +165 -0
  14. opensignalbox/interface/interfaces/bell/__init__.py +3 -0
  15. opensignalbox/interface/interfaces/bell/connections.py +279 -0
  16. opensignalbox/interface/interfaces/bell/handler.py +802 -0
  17. opensignalbox/interface/interfaces/bell/models.py +103 -0
  18. opensignalbox/interface/interfaces/controller.py +467 -0
  19. opensignalbox/interface/main.py +187 -0
  20. opensignalbox/interface/models.py +155 -0
  21. opensignalbox/interface/routes/__init__.py +4 -0
  22. opensignalbox/interface/routes/adapters.py +119 -0
  23. opensignalbox/interface/routes/interfaces.py +104 -0
  24. opensignalbox/interface/routes.py +204 -0
  25. opensignalbox/interface/utils.py +29 -0
  26. opensignalbox/interface/version.py +5 -0
  27. opensignalbox/interface/web_ui/.gitignore +24 -0
  28. opensignalbox/interface/web_ui/README.md +5 -0
  29. opensignalbox/interface/web_ui/WEB_UI_REFACTORING.md +136 -0
  30. opensignalbox/interface/web_ui/components.json +17 -0
  31. opensignalbox/interface/web_ui/dist/assets/index-DhsEc6uo.css +2020 -0
  32. opensignalbox/interface/web_ui/dist/assets/index-t__5JZjf.js +39056 -0
  33. opensignalbox/interface/web_ui/dist/assets/index-t__5JZjf.js.map +1 -0
  34. opensignalbox/interface/web_ui/dist/index.html +14 -0
  35. opensignalbox/interface/web_ui/index.html +13 -0
  36. opensignalbox/interface/web_ui/package-lock.json +3710 -0
  37. opensignalbox/interface/web_ui/package.json +39 -0
  38. opensignalbox/interface/web_ui/src/App.vue +32 -0
  39. opensignalbox/interface/web_ui/src/assets/favicon.ico +0 -0
  40. opensignalbox/interface/web_ui/src/assets/index.css +83 -0
  41. opensignalbox/interface/web_ui/src/components/SharedVariablePicker.vue +112 -0
  42. opensignalbox/interface/web_ui/src/components/adapters/AdapterList.vue +183 -0
  43. opensignalbox/interface/web_ui/src/components/adapters/types.ts +35 -0
  44. opensignalbox/interface/web_ui/src/components/interfaces/InterfaceList.vue +200 -0
  45. opensignalbox/interface/web_ui/src/components/ui/badge/Badge.vue +16 -0
  46. opensignalbox/interface/web_ui/src/components/ui/badge/index.ts +25 -0
  47. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/Breadcrumb.vue +13 -0
  48. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
  49. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbItem.vue +16 -0
  50. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbLink.vue +19 -0
  51. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbList.vue +16 -0
  52. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbPage.vue +19 -0
  53. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
  54. opensignalbox/interface/web_ui/src/components/ui/breadcrumb/index.ts +7 -0
  55. opensignalbox/interface/web_ui/src/components/ui/button/Button.vue +26 -0
  56. opensignalbox/interface/web_ui/src/components/ui/button/index.ts +35 -0
  57. opensignalbox/interface/web_ui/src/components/ui/card/Card.vue +21 -0
  58. opensignalbox/interface/web_ui/src/components/ui/card/CardContent.vue +14 -0
  59. opensignalbox/interface/web_ui/src/components/ui/card/CardDescription.vue +14 -0
  60. opensignalbox/interface/web_ui/src/components/ui/card/CardFooter.vue +14 -0
  61. opensignalbox/interface/web_ui/src/components/ui/card/CardHeader.vue +14 -0
  62. opensignalbox/interface/web_ui/src/components/ui/card/CardTitle.vue +18 -0
  63. opensignalbox/interface/web_ui/src/components/ui/card/index.ts +6 -0
  64. opensignalbox/interface/web_ui/src/components/ui/checkbox/Checkbox.vue +33 -0
  65. opensignalbox/interface/web_ui/src/components/ui/checkbox/index.ts +1 -0
  66. opensignalbox/interface/web_ui/src/components/ui/collapsible/Collapsible.vue +15 -0
  67. opensignalbox/interface/web_ui/src/components/ui/collapsible/CollapsibleContent.vue +11 -0
  68. opensignalbox/interface/web_ui/src/components/ui/collapsible/CollapsibleTrigger.vue +11 -0
  69. opensignalbox/interface/web_ui/src/components/ui/collapsible/index.ts +3 -0
  70. opensignalbox/interface/web_ui/src/components/ui/command/Command.vue +30 -0
  71. opensignalbox/interface/web_ui/src/components/ui/command/CommandDialog.vue +21 -0
  72. opensignalbox/interface/web_ui/src/components/ui/command/CommandEmpty.vue +20 -0
  73. opensignalbox/interface/web_ui/src/components/ui/command/CommandGroup.vue +29 -0
  74. opensignalbox/interface/web_ui/src/components/ui/command/CommandInput.vue +33 -0
  75. opensignalbox/interface/web_ui/src/components/ui/command/CommandItem.vue +26 -0
  76. opensignalbox/interface/web_ui/src/components/ui/command/CommandList.vue +27 -0
  77. opensignalbox/interface/web_ui/src/components/ui/command/CommandSeparator.vue +23 -0
  78. opensignalbox/interface/web_ui/src/components/ui/command/CommandShortcut.vue +14 -0
  79. opensignalbox/interface/web_ui/src/components/ui/command/index.ts +9 -0
  80. opensignalbox/interface/web_ui/src/components/ui/dialog/Dialog.vue +14 -0
  81. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogClose.vue +11 -0
  82. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogContent.vue +50 -0
  83. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogDescription.vue +24 -0
  84. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogFooter.vue +19 -0
  85. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogHeader.vue +16 -0
  86. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogScrollContent.vue +59 -0
  87. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogTitle.vue +29 -0
  88. opensignalbox/interface/web_ui/src/components/ui/dialog/DialogTrigger.vue +11 -0
  89. opensignalbox/interface/web_ui/src/components/ui/dialog/index.ts +9 -0
  90. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenu.vue +14 -0
  91. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +40 -0
  92. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuContent.vue +38 -0
  93. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
  94. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuItem.vue +28 -0
  95. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +24 -0
  96. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +19 -0
  97. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +41 -0
  98. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +22 -0
  99. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
  100. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  101. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
  102. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +33 -0
  103. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
  104. opensignalbox/interface/web_ui/src/components/ui/dropdown-menu/index.ts +16 -0
  105. opensignalbox/interface/web_ui/src/components/ui/form/FormControl.vue +16 -0
  106. opensignalbox/interface/web_ui/src/components/ui/form/FormDescription.vue +20 -0
  107. opensignalbox/interface/web_ui/src/components/ui/form/FormItem.vue +19 -0
  108. opensignalbox/interface/web_ui/src/components/ui/form/FormLabel.vue +23 -0
  109. opensignalbox/interface/web_ui/src/components/ui/form/FormMessage.vue +16 -0
  110. opensignalbox/interface/web_ui/src/components/ui/form/index.ts +7 -0
  111. opensignalbox/interface/web_ui/src/components/ui/form/injectionKeys.ts +4 -0
  112. opensignalbox/interface/web_ui/src/components/ui/form/useFormField.ts +30 -0
  113. opensignalbox/interface/web_ui/src/components/ui/input/Input.vue +24 -0
  114. opensignalbox/interface/web_ui/src/components/ui/input/index.ts +1 -0
  115. opensignalbox/interface/web_ui/src/components/ui/label/Label.vue +27 -0
  116. opensignalbox/interface/web_ui/src/components/ui/label/index.ts +1 -0
  117. opensignalbox/interface/web_ui/src/components/ui/number-field/NumberField.vue +23 -0
  118. opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldContent.vue +14 -0
  119. opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldDecrement.vue +25 -0
  120. opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldIncrement.vue +25 -0
  121. opensignalbox/interface/web_ui/src/components/ui/number-field/NumberFieldInput.vue +16 -0
  122. opensignalbox/interface/web_ui/src/components/ui/number-field/index.ts +5 -0
  123. opensignalbox/interface/web_ui/src/components/ui/popover/Popover.vue +15 -0
  124. opensignalbox/interface/web_ui/src/components/ui/popover/PopoverContent.vue +48 -0
  125. opensignalbox/interface/web_ui/src/components/ui/popover/PopoverTrigger.vue +11 -0
  126. opensignalbox/interface/web_ui/src/components/ui/popover/index.ts +3 -0
  127. opensignalbox/interface/web_ui/src/components/ui/radio-group/RadioGroup.vue +25 -0
  128. opensignalbox/interface/web_ui/src/components/ui/radio-group/RadioGroupItem.vue +39 -0
  129. opensignalbox/interface/web_ui/src/components/ui/radio-group/index.ts +2 -0
  130. opensignalbox/interface/web_ui/src/components/ui/scroll-area/ScrollArea.vue +29 -0
  131. opensignalbox/interface/web_ui/src/components/ui/scroll-area/ScrollBar.vue +30 -0
  132. opensignalbox/interface/web_ui/src/components/ui/scroll-area/index.ts +2 -0
  133. opensignalbox/interface/web_ui/src/components/ui/select/Select.vue +15 -0
  134. opensignalbox/interface/web_ui/src/components/ui/select/SelectContent.vue +53 -0
  135. opensignalbox/interface/web_ui/src/components/ui/select/SelectGroup.vue +19 -0
  136. opensignalbox/interface/web_ui/src/components/ui/select/SelectItem.vue +44 -0
  137. opensignalbox/interface/web_ui/src/components/ui/select/SelectItemText.vue +11 -0
  138. opensignalbox/interface/web_ui/src/components/ui/select/SelectLabel.vue +13 -0
  139. opensignalbox/interface/web_ui/src/components/ui/select/SelectScrollDownButton.vue +24 -0
  140. opensignalbox/interface/web_ui/src/components/ui/select/SelectScrollUpButton.vue +24 -0
  141. opensignalbox/interface/web_ui/src/components/ui/select/SelectSeparator.vue +17 -0
  142. opensignalbox/interface/web_ui/src/components/ui/select/SelectTrigger.vue +31 -0
  143. opensignalbox/interface/web_ui/src/components/ui/select/SelectValue.vue +11 -0
  144. opensignalbox/interface/web_ui/src/components/ui/select/index.ts +11 -0
  145. opensignalbox/interface/web_ui/src/components/ui/separator/Separator.vue +35 -0
  146. opensignalbox/interface/web_ui/src/components/ui/separator/index.ts +1 -0
  147. opensignalbox/interface/web_ui/src/components/ui/sheet/Sheet.vue +14 -0
  148. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetClose.vue +11 -0
  149. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetContent.vue +56 -0
  150. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetDescription.vue +22 -0
  151. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetFooter.vue +19 -0
  152. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetHeader.vue +16 -0
  153. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetTitle.vue +22 -0
  154. opensignalbox/interface/web_ui/src/components/ui/sheet/SheetTrigger.vue +11 -0
  155. opensignalbox/interface/web_ui/src/components/ui/sheet/index.ts +31 -0
  156. opensignalbox/interface/web_ui/src/components/ui/table/Table.vue +16 -0
  157. opensignalbox/interface/web_ui/src/components/ui/table/TableBody.vue +14 -0
  158. opensignalbox/interface/web_ui/src/components/ui/table/TableCaption.vue +14 -0
  159. opensignalbox/interface/web_ui/src/components/ui/table/TableCell.vue +21 -0
  160. opensignalbox/interface/web_ui/src/components/ui/table/TableEmpty.vue +37 -0
  161. opensignalbox/interface/web_ui/src/components/ui/table/TableFooter.vue +14 -0
  162. opensignalbox/interface/web_ui/src/components/ui/table/TableHead.vue +14 -0
  163. opensignalbox/interface/web_ui/src/components/ui/table/TableHeader.vue +14 -0
  164. opensignalbox/interface/web_ui/src/components/ui/table/TableRow.vue +14 -0
  165. opensignalbox/interface/web_ui/src/components/ui/table/index.ts +9 -0
  166. opensignalbox/interface/web_ui/src/components/ui/tabs/Tabs.vue +15 -0
  167. opensignalbox/interface/web_ui/src/components/ui/tabs/TabsContent.vue +22 -0
  168. opensignalbox/interface/web_ui/src/components/ui/tabs/TabsList.vue +25 -0
  169. opensignalbox/interface/web_ui/src/components/ui/tabs/TabsTrigger.vue +29 -0
  170. opensignalbox/interface/web_ui/src/components/ui/tabs/index.ts +4 -0
  171. opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInput.vue +22 -0
  172. opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputInput.vue +19 -0
  173. opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItem.vue +22 -0
  174. opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItemDelete.vue +24 -0
  175. opensignalbox/interface/web_ui/src/components/ui/tags-input/TagsInputItemText.vue +19 -0
  176. opensignalbox/interface/web_ui/src/components/ui/tags-input/index.ts +5 -0
  177. opensignalbox/interface/web_ui/src/components/ui/textarea/Textarea.vue +24 -0
  178. opensignalbox/interface/web_ui/src/components/ui/textarea/index.ts +1 -0
  179. opensignalbox/interface/web_ui/src/components/ui/tooltip/Tooltip.vue +14 -0
  180. opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipContent.vue +31 -0
  181. opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipProvider.vue +11 -0
  182. opensignalbox/interface/web_ui/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
  183. opensignalbox/interface/web_ui/src/components/ui/tooltip/index.ts +4 -0
  184. opensignalbox/interface/web_ui/src/libs/utils.ts +6 -0
  185. opensignalbox/interface/web_ui/src/main.ts +141 -0
  186. opensignalbox/interface/web_ui/src/views/Overview.vue +11 -0
  187. opensignalbox/interface/web_ui/src/views/Settings.vue +6 -0
  188. opensignalbox/interface/web_ui/src/views/SleafordEast.vue +205 -0
  189. opensignalbox/interface/web_ui/src/views/adapters/modbus/ModbusAdapterEdit.vue +343 -0
  190. opensignalbox/interface/web_ui/src/views/adapters/modbus/ModbusAdapterView.vue +270 -0
  191. opensignalbox/interface/web_ui/src/views/interfaces/InterfaceCreate.vue +0 -0
  192. opensignalbox/interface/web_ui/src/views/interfaces/basicio/BasicIOInterfaceEdit.vue +795 -0
  193. opensignalbox/interface/web_ui/src/views/interfaces/basicio/BasicIOInterfaceView.vue +648 -0
  194. opensignalbox/interface/web_ui/src/views/interfaces/bell/BellInterfaceEdit.vue +790 -0
  195. opensignalbox/interface/web_ui/src/views/interfaces/bell/BellInterfaceView.vue +437 -0
  196. opensignalbox/interface/web_ui/src/vite-env.d.ts +1 -0
  197. opensignalbox/interface/web_ui/tailwind.config.js +94 -0
  198. opensignalbox/interface/web_ui/tsconfig.app.json +27 -0
  199. opensignalbox/interface/web_ui/tsconfig.json +30 -0
  200. opensignalbox/interface/web_ui/tsconfig.node.json +12 -0
  201. opensignalbox/interface/web_ui/tsconfig.tsbuildinfo +1 -0
  202. opensignalbox/interface/web_ui/vite.config.d.ts +2 -0
  203. opensignalbox/interface/web_ui/vite.config.js +60 -0
  204. opensignalbox/interface/web_ui/vite.config.ts +62 -0
  205. opensignalbox_interface-0.1.0.dist-info/METADATA +49 -0
  206. opensignalbox_interface-0.1.0.dist-info/RECORD +209 -0
  207. opensignalbox_interface-0.1.0.dist-info/WHEEL +4 -0
  208. opensignalbox_interface-0.1.0.dist-info/entry_points.txt +2 -0
  209. 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,5 @@
1
+ """
2
+ Version information.
3
+ """
4
+
5
+ __version__ = "0.1.0"
@@ -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
+ }