@seedtactics/insight-client 16.4.0

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 (298) hide show
  1. package/README.md +37 -0
  2. package/dist/cell-status/buffers.d.ts +36 -0
  3. package/dist/cell-status/buffers.js +127 -0
  4. package/dist/cell-status/current-status.d.ts +30 -0
  5. package/dist/cell-status/current-status.js +200 -0
  6. package/dist/cell-status/estimated-cycle-times.d.ts +41 -0
  7. package/dist/cell-status/estimated-cycle-times.js +257 -0
  8. package/dist/cell-status/inspections.d.ts +55 -0
  9. package/dist/cell-status/inspections.js +213 -0
  10. package/dist/cell-status/loading.d.ts +26 -0
  11. package/dist/cell-status/loading.js +112 -0
  12. package/dist/cell-status/material-details.d.ts +116 -0
  13. package/dist/cell-status/material-details.js +422 -0
  14. package/dist/cell-status/material-summary.d.ts +52 -0
  15. package/dist/cell-status/material-summary.js +312 -0
  16. package/dist/cell-status/names.d.ts +19 -0
  17. package/dist/cell-status/names.js +134 -0
  18. package/dist/cell-status/pallet-cycles.d.ts +24 -0
  19. package/dist/cell-status/pallet-cycles.js +78 -0
  20. package/dist/cell-status/rebookings.d.ts +30 -0
  21. package/dist/cell-status/rebookings.js +139 -0
  22. package/dist/cell-status/scheduled-jobs.d.ts +18 -0
  23. package/dist/cell-status/scheduled-jobs.js +94 -0
  24. package/dist/cell-status/sim-day-usage.d.ts +14 -0
  25. package/dist/cell-status/sim-day-usage.js +54 -0
  26. package/dist/cell-status/sim-production.d.ts +22 -0
  27. package/dist/cell-status/sim-production.js +91 -0
  28. package/dist/cell-status/sim-station-use.d.ts +25 -0
  29. package/dist/cell-status/sim-station-use.js +71 -0
  30. package/dist/cell-status/station-cycles.d.ts +34 -0
  31. package/dist/cell-status/station-cycles.js +145 -0
  32. package/dist/cell-status/tool-replacements.d.ts +44 -0
  33. package/dist/cell-status/tool-replacements.js +155 -0
  34. package/dist/cell-status/tool-usage.d.ts +25 -0
  35. package/dist/cell-status/tool-usage.js +95 -0
  36. package/dist/components/App.d.ts +15 -0
  37. package/dist/components/App.js +549 -0
  38. package/dist/components/AxisAndGrid.d.ts +51 -0
  39. package/dist/components/AxisAndGrid.js +47 -0
  40. package/dist/components/BarcodeScanning.d.ts +6 -0
  41. package/dist/components/BarcodeScanning.js +150 -0
  42. package/dist/components/ChartTooltip.d.ts +28 -0
  43. package/dist/components/ChartTooltip.js +95 -0
  44. package/dist/components/ChooseMode.d.ts +18 -0
  45. package/dist/components/ChooseMode.js +136 -0
  46. package/dist/components/ChooseOperator.d.ts +1 -0
  47. package/dist/components/ChooseOperator.js +93 -0
  48. package/dist/components/ErrorsAndLoading.d.ts +9 -0
  49. package/dist/components/ErrorsAndLoading.js +55 -0
  50. package/dist/components/LoadingIcon.d.ts +1 -0
  51. package/dist/components/LoadingIcon.js +48 -0
  52. package/dist/components/LogEntry.d.ts +16 -0
  53. package/dist/components/LogEntry.js +365 -0
  54. package/dist/components/ManualSerialEntry.d.ts +5 -0
  55. package/dist/components/ManualSerialEntry.js +91 -0
  56. package/dist/components/MonthSelect.d.ts +6 -0
  57. package/dist/components/MonthSelect.js +67 -0
  58. package/dist/components/Navigation.d.ts +23 -0
  59. package/dist/components/Navigation.js +120 -0
  60. package/dist/components/VerboseLogging.d.ts +1 -0
  61. package/dist/components/VerboseLogging.js +47 -0
  62. package/dist/components/analysis/AnalysisSelectToolbar.d.ts +1 -0
  63. package/dist/components/analysis/AnalysisSelectToolbar.js +55 -0
  64. package/dist/components/analysis/BufferChart.d.ts +1 -0
  65. package/dist/components/analysis/BufferChart.js +139 -0
  66. package/dist/components/analysis/CostPerPiece.d.ts +2 -0
  67. package/dist/components/analysis/CostPerPiece.js +175 -0
  68. package/dist/components/analysis/CycleChart.d.ts +42 -0
  69. package/dist/components/analysis/CycleChart.js +281 -0
  70. package/dist/components/analysis/DataTable.d.ts +83 -0
  71. package/dist/components/analysis/DataTable.js +215 -0
  72. package/dist/components/analysis/EfficiencyPage.d.ts +2 -0
  73. package/dist/components/analysis/EfficiencyPage.js +138 -0
  74. package/dist/components/analysis/HeatChart.d.ts +22 -0
  75. package/dist/components/analysis/HeatChart.js +161 -0
  76. package/dist/components/analysis/InspectionDataTable.d.ts +10 -0
  77. package/dist/components/analysis/InspectionDataTable.js +148 -0
  78. package/dist/components/analysis/InspectionSankey.d.ts +12 -0
  79. package/dist/components/analysis/InspectionSankey.js +140 -0
  80. package/dist/components/analysis/PalletCycleCards.d.ts +1 -0
  81. package/dist/components/analysis/PalletCycleCards.js +137 -0
  82. package/dist/components/analysis/PartCycleCards.d.ts +2 -0
  83. package/dist/components/analysis/PartCycleCards.js +331 -0
  84. package/dist/components/analysis/QualityPage.d.ts +1 -0
  85. package/dist/components/analysis/QualityPage.js +49 -0
  86. package/dist/components/analysis/ScheduleHistory.d.ts +3 -0
  87. package/dist/components/analysis/ScheduleHistory.js +108 -0
  88. package/dist/components/analysis/StationDataTable.d.ts +25 -0
  89. package/dist/components/analysis/StationDataTable.js +246 -0
  90. package/dist/components/analysis/ToolReplacements.d.ts +1 -0
  91. package/dist/components/analysis/ToolReplacements.js +370 -0
  92. package/dist/components/operations/AllMaterial.d.ts +5 -0
  93. package/dist/components/operations/AllMaterial.js +267 -0
  94. package/dist/components/operations/ChartRangeEdit.d.ts +4 -0
  95. package/dist/components/operations/ChartRangeEdit.js +148 -0
  96. package/dist/components/operations/CloseoutReport.d.ts +2 -0
  97. package/dist/components/operations/CloseoutReport.js +172 -0
  98. package/dist/components/operations/CompletedParts.d.ts +2 -0
  99. package/dist/components/operations/CompletedParts.js +286 -0
  100. package/dist/components/operations/CurrentWorkorders.d.ts +3 -0
  101. package/dist/components/operations/CurrentWorkorders.js +368 -0
  102. package/dist/components/operations/Dashboard.d.ts +2 -0
  103. package/dist/components/operations/Dashboard.js +90 -0
  104. package/dist/components/operations/OEEChart.d.ts +10 -0
  105. package/dist/components/operations/OEEChart.js +173 -0
  106. package/dist/components/operations/Outliers.d.ts +4 -0
  107. package/dist/components/operations/Outliers.js +69 -0
  108. package/dist/components/operations/ProgramHighlight.d.ts +1 -0
  109. package/dist/components/operations/ProgramHighlight.js +9 -0
  110. package/dist/components/operations/Programs.d.ts +5 -0
  111. package/dist/components/operations/Programs.js +363 -0
  112. package/dist/components/operations/Rebookings.d.ts +1 -0
  113. package/dist/components/operations/Rebookings.js +213 -0
  114. package/dist/components/operations/RecentCycleChart.d.ts +4 -0
  115. package/dist/components/operations/RecentCycleChart.js +240 -0
  116. package/dist/components/operations/RecentProduction.d.ts +2 -0
  117. package/dist/components/operations/RecentProduction.js +213 -0
  118. package/dist/components/operations/RecentSchedules.d.ts +12 -0
  119. package/dist/components/operations/RecentSchedules.js +180 -0
  120. package/dist/components/operations/RecentStationCycles.d.ts +4 -0
  121. package/dist/components/operations/RecentStationCycles.js +159 -0
  122. package/dist/components/operations/ShiftSettings.d.ts +6 -0
  123. package/dist/components/operations/ShiftSettings.js +134 -0
  124. package/dist/components/operations/SimDayUsage.d.ts +1 -0
  125. package/dist/components/operations/SimDayUsage.js +133 -0
  126. package/dist/components/operations/ToolReport.d.ts +3 -0
  127. package/dist/components/operations/ToolReport.js +233 -0
  128. package/dist/components/operations/WorkorderGantt.d.ts +1 -0
  129. package/dist/components/operations/WorkorderGantt.js +124 -0
  130. package/dist/components/quality/QualityMaterial.d.ts +2 -0
  131. package/dist/components/quality/QualityMaterial.js +169 -0
  132. package/dist/components/quality/QualityPaths.d.ts +1 -0
  133. package/dist/components/quality/QualityPaths.js +53 -0
  134. package/dist/components/quality/RecentFailedInspections.d.ts +1 -0
  135. package/dist/components/quality/RecentFailedInspections.js +123 -0
  136. package/dist/components/routes.d.ts +170 -0
  137. package/dist/components/routes.js +301 -0
  138. package/dist/components/station-monitor/BulkRawMaterial.d.ts +11 -0
  139. package/dist/components/station-monitor/BulkRawMaterial.js +251 -0
  140. package/dist/components/station-monitor/Closeout.d.ts +5 -0
  141. package/dist/components/station-monitor/Closeout.js +162 -0
  142. package/dist/components/station-monitor/CustomStationMonitorDialog.d.ts +1 -0
  143. package/dist/components/station-monitor/CustomStationMonitorDialog.js +55 -0
  144. package/dist/components/station-monitor/Inspection.d.ts +8 -0
  145. package/dist/components/station-monitor/Inspection.js +164 -0
  146. package/dist/components/station-monitor/InvalidateCycle.d.ts +33 -0
  147. package/dist/components/station-monitor/InvalidateCycle.js +262 -0
  148. package/dist/components/station-monitor/JobDetails.d.ts +7 -0
  149. package/dist/components/station-monitor/JobDetails.js +108 -0
  150. package/dist/components/station-monitor/LoadStation.d.ts +10 -0
  151. package/dist/components/station-monitor/LoadStation.js +450 -0
  152. package/dist/components/station-monitor/Material.d.ts +77 -0
  153. package/dist/components/station-monitor/Material.js +489 -0
  154. package/dist/components/station-monitor/MoveMaterialArrows.d.ts +11 -0
  155. package/dist/components/station-monitor/MoveMaterialArrows.js +118 -0
  156. package/dist/components/station-monitor/PrintedLabel.d.ts +29 -0
  157. package/dist/components/station-monitor/PrintedLabel.js +166 -0
  158. package/dist/components/station-monitor/QuarantineButton.d.ts +4 -0
  159. package/dist/components/station-monitor/QuarantineButton.js +184 -0
  160. package/dist/components/station-monitor/Queues.d.ts +23 -0
  161. package/dist/components/station-monitor/Queues.js +312 -0
  162. package/dist/components/station-monitor/QueuesAddMaterial.d.ts +30 -0
  163. package/dist/components/station-monitor/QueuesAddMaterial.js +248 -0
  164. package/dist/components/station-monitor/SelectInspType.d.ts +2 -0
  165. package/dist/components/station-monitor/SelectInspType.js +99 -0
  166. package/dist/components/station-monitor/SelectWorkorder.d.ts +4 -0
  167. package/dist/components/station-monitor/SelectWorkorder.js +100 -0
  168. package/dist/components/station-monitor/StationToolbar.d.ts +3 -0
  169. package/dist/components/station-monitor/StationToolbar.js +168 -0
  170. package/dist/components/station-monitor/SystemOverview.d.ts +46 -0
  171. package/dist/components/station-monitor/SystemOverview.js +439 -0
  172. package/dist/components/station-monitor/Whiteboard.d.ts +10 -0
  173. package/dist/components/station-monitor/Whiteboard.js +67 -0
  174. package/dist/data/all-material-bins.d.ts +45 -0
  175. package/dist/data/all-material-bins.js +224 -0
  176. package/dist/data/chart-times.d.ts +20 -0
  177. package/dist/data/chart-times.js +99 -0
  178. package/dist/data/cost-per-piece.d.ts +32 -0
  179. package/dist/data/cost-per-piece.js +183 -0
  180. package/dist/data/current-cycles.d.ts +13 -0
  181. package/dist/data/current-cycles.js +144 -0
  182. package/dist/data/inspection-sankey.d.ts +15 -0
  183. package/dist/data/inspection-sankey.js +147 -0
  184. package/dist/data/move-arrows.d.ts +48 -0
  185. package/dist/data/move-arrows.js +217 -0
  186. package/dist/data/operators.d.ts +2 -0
  187. package/dist/data/operators.js +44 -0
  188. package/dist/data/part-summary.d.ts +17 -0
  189. package/dist/data/part-summary.js +107 -0
  190. package/dist/data/path-lookup.d.ts +13 -0
  191. package/dist/data/path-lookup.js +107 -0
  192. package/dist/data/queue-material.d.ts +46 -0
  193. package/dist/data/queue-material.js +256 -0
  194. package/dist/data/results.bufferchart.d.ts +10 -0
  195. package/dist/data/results.bufferchart.js +90 -0
  196. package/dist/data/results.completed-parts.d.ts +26 -0
  197. package/dist/data/results.completed-parts.js +181 -0
  198. package/dist/data/results.cycles.d.ts +86 -0
  199. package/dist/data/results.cycles.js +454 -0
  200. package/dist/data/results.inspection.d.ts +36 -0
  201. package/dist/data/results.inspection.js +188 -0
  202. package/dist/data/results.oee.d.ts +40 -0
  203. package/dist/data/results.oee.js +330 -0
  204. package/dist/data/results.schedules.d.ts +23 -0
  205. package/dist/data/results.schedules.js +157 -0
  206. package/dist/data/tools-programs.d.ts +78 -0
  207. package/dist/data/tools-programs.js +376 -0
  208. package/dist/index.d.ts +1 -0
  209. package/dist/index.js +60 -0
  210. package/dist/network/api.d.ts +1390 -0
  211. package/dist/network/api.js +4971 -0
  212. package/dist/network/backend-mock.d.ts +11 -0
  213. package/dist/network/backend-mock.js +512 -0
  214. package/dist/network/backend.d.ts +57 -0
  215. package/dist/network/backend.js +77 -0
  216. package/dist/network/load-specific-month.d.ts +13 -0
  217. package/dist/network/load-specific-month.js +77 -0
  218. package/dist/network/server-settings.d.ts +12 -0
  219. package/dist/network/server-settings.js +92 -0
  220. package/dist/network/websocket.d.ts +4 -0
  221. package/dist/network/websocket.js +165 -0
  222. package/dist/renderer.d.ts +8 -0
  223. package/dist/renderer.js +55 -0
  224. package/dist/seedtactics-logo.d.ts +2 -0
  225. package/dist/seedtactics-logo.js +4 -0
  226. package/dist/util/chart-colors.d.ts +1 -0
  227. package/dist/util/chart-colors.js +116 -0
  228. package/dist/util/chart-helpers.d.ts +3 -0
  229. package/dist/util/chart-helpers.js +51 -0
  230. package/dist/util/parseISODuration.d.ts +4 -0
  231. package/dist/util/parseISODuration.js +40 -0
  232. package/docs/client-efficiency.md +355 -0
  233. package/docs/client-engineering.md +54 -0
  234. package/docs/client-launch.md +55 -0
  235. package/docs/client-operations.md +88 -0
  236. package/docs/client-quality.md +74 -0
  237. package/docs/client-sales.md +61 -0
  238. package/docs/client-scanners.md +41 -0
  239. package/docs/client-station-monitor.md +149 -0
  240. package/docs/client-tools-programs.md +74 -0
  241. package/docs/improve-fms.md +141 -0
  242. package/docs/makino.md +40 -0
  243. package/docs/material-quarantine.md +82 -0
  244. package/docs/material-tracking.md +236 -0
  245. package/docs/mazak.md +115 -0
  246. package/docs/niigata.md +228 -0
  247. package/docs/operator-procedures.md +106 -0
  248. package/docs/part-instructions.md +63 -0
  249. package/docs/screenshots/insight-all-material.png +0 -0
  250. package/docs/screenshots/insight-analysis-pallets.png +0 -0
  251. package/docs/screenshots/insight-analysis-part-completed.png +0 -0
  252. package/docs/screenshots/insight-analysis-sankey.png +0 -0
  253. package/docs/screenshots/insight-analysis-station-oee.png +0 -0
  254. package/docs/screenshots/insight-buffer-occupancy.png +0 -0
  255. package/docs/screenshots/insight-choose-analysis-month.png +0 -0
  256. package/docs/screenshots/insight-closeout.png +0 -0
  257. package/docs/screenshots/insight-cost-percentages.png +0 -0
  258. package/docs/screenshots/insight-dashboard.png +0 -0
  259. package/docs/screenshots/insight-event-custom-view.jpg +0 -0
  260. package/docs/screenshots/insight-event-viewer.jpg +0 -0
  261. package/docs/screenshots/insight-inspection.png +0 -0
  262. package/docs/screenshots/insight-load-station-details.png +0 -0
  263. package/docs/screenshots/insight-load-station.png +0 -0
  264. package/docs/screenshots/insight-loadcycle-graph.png +0 -0
  265. package/docs/screenshots/insight-loadstation-small.jpg +0 -0
  266. package/docs/screenshots/insight-machinecycle-graph.png +0 -0
  267. package/docs/screenshots/insight-machinecycle-table.png +0 -0
  268. package/docs/screenshots/insight-machinecycles.png +0 -0
  269. package/docs/screenshots/insight-machinehours.png +0 -0
  270. package/docs/screenshots/insight-machineoutliers.png +0 -0
  271. package/docs/screenshots/insight-monthly-schedules.png +0 -0
  272. package/docs/screenshots/insight-operations-material.png +0 -0
  273. package/docs/screenshots/insight-operations-overview.png +0 -0
  274. package/docs/screenshots/insight-operations-reports.png +0 -0
  275. package/docs/screenshots/insight-part-cost.png +0 -0
  276. package/docs/screenshots/insight-program-report.png +0 -0
  277. package/docs/screenshots/insight-quality-material-details.png +0 -0
  278. package/docs/screenshots/insight-quality-material.png +0 -0
  279. package/docs/screenshots/insight-quality-quarantine.png +0 -0
  280. package/docs/screenshots/insight-quality-sankey.png +0 -0
  281. package/docs/screenshots/insight-quality-similar-paths.png +0 -0
  282. package/docs/screenshots/insight-queue-details.png +0 -0
  283. package/docs/screenshots/insight-queues-jobs-table.png +0 -0
  284. package/docs/screenshots/insight-queues.png +0 -0
  285. package/docs/screenshots/insight-sim-day-usage.png +0 -0
  286. package/docs/screenshots/insight-station-system-overview-buttons.png +0 -0
  287. package/docs/screenshots/insight-station-system-overview.png +0 -0
  288. package/docs/screenshots/insight-system-overview.png +0 -0
  289. package/docs/screenshots/insight-tool-replacements.png +0 -0
  290. package/docs/screenshots/insight-tool-report.png +0 -0
  291. package/docs/screenshots/insight-toolbar-btns.png +0 -0
  292. package/docs/screenshots/insight-workorder-gantt.png +0 -0
  293. package/docs/screenshots/insight-workorders.png +0 -0
  294. package/docs/security.md +131 -0
  295. package/docs/server-config.md +56 -0
  296. package/docs/server-errors.md +44 -0
  297. package/package.json +90 -0
  298. package/src/index.ts +65 -0
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # FMS Insight Client
2
+
3
+ This is the client half of [FMS
4
+ Insight](https://github.com/SeedTactics/fms-insight). FMS Insight is a program
5
+ for a flexible machining system (FMS) cell controller which tracks material,
6
+ records a log of events, helps with inspections and serial marking, presents
7
+ details about the cell via webpages, and more. These web pages help operators
8
+ on the shop floor manage material, supervisors monitor the day to day
9
+ activities, and engineers evaluate the long-term efficiency of tools and the
10
+ cell.
11
+
12
+ The server is written in C# and available on nuget in the
13
+ [BlackMaple.MachineFramework](https://www.nuget.org/packages/BlackMaple.MachineFramework)
14
+ package. The client in this npm package is a React SPA which communicates with
15
+ the server with HTTP JSON requests. The client is built using vite and served
16
+ as static files, typically by the C# server. Because of that, the nuget package
17
+ for the server contain a built version of the client. If you are just using
18
+ FMS Insight and don't intend any changes to the client, you can just use the
19
+ BlackMaple.MachineFramework nuget. This npm package is needed only if you wish
20
+ to modify the client or import portions of the client into your own pages.
21
+
22
+ ## Code Overview
23
+
24
+ The client stores data in [jotai](https://jotai.org/) stores. We use a
25
+ thick-client approach: each client loads a large amout of events at startup and
26
+ then uses a websocket connection to keep the stores updated as new events occur.
27
+ Most of the reports and pages are then generated on the client, typically using
28
+ jotai atoms. The atoms storing the information about the cell are in the
29
+ `src/cell-status` directory. The code in the `src/network` directory handles
30
+ the initial data load and the websocket connection to keep the jotai stores updated.
31
+
32
+ The `src/data` directory contains a large amout of the client-side business logic
33
+ and report generating typescript code. It takes the raw event data from the cell
34
+ status and turns it into a format suitable for display. Finally, the `src/components`
35
+ directory contains the React components which display the various reports and pages.
36
+ To customize, you should look at `src/components/App.tsx` for inspiration: it imports
37
+ the various pages and handles the routing.
@@ -0,0 +1,36 @@
1
+ import type { ServerEventAndTime } from "./loading.js";
2
+ import { ILogEntry } from "../network/api.js";
3
+ import { HashMap } from "@seedtactics/immutable-collections";
4
+ import { Atom } from "jotai";
5
+ export type BufferType = {
6
+ readonly type: "Rotary";
7
+ readonly machineGroup: string;
8
+ readonly machineNum: number;
9
+ } | {
10
+ readonly type: "StockerWaitForMC";
11
+ readonly stockerNum: number;
12
+ } | {
13
+ readonly type: "StockerWaitForUnload";
14
+ readonly stockerNum: number;
15
+ } | {
16
+ readonly type: "Queue";
17
+ readonly queue: string;
18
+ };
19
+ export interface BufferEntry {
20
+ readonly buffer: BufferType;
21
+ readonly endTime: Date;
22
+ readonly elapsedSeconds: number;
23
+ readonly numMaterial: number;
24
+ }
25
+ export type BufferEntryByCntr = HashMap<number, BufferEntry>;
26
+ export declare const last30BufferEntries: Atom<BufferEntryByCntr>;
27
+ export declare const specificMonthBufferEntries: Atom<BufferEntryByCntr>;
28
+ export declare const setLast30Buffer: import("jotai").WritableAtom<null, [log: readonly Readonly<ILogEntry>[]], void> & {
29
+ init: null;
30
+ };
31
+ export declare const updateLast30Buffer: import("jotai").WritableAtom<null, [ServerEventAndTime], void> & {
32
+ init: null;
33
+ };
34
+ export declare const setSpecificMonthBuffer: import("jotai").WritableAtom<null, [log: readonly Readonly<ILogEntry>[]], void> & {
35
+ init: null;
36
+ };
@@ -0,0 +1,127 @@
1
+ /* Copyright (c) 2021, John Lenz
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+
16
+ * Neither the name of John Lenz, Black Maple Software, SeedTactics,
17
+ nor the names of other contributors may be used to endorse or
18
+ promote products derived from this software without specific
19
+ prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+ import { addDays } from "date-fns";
34
+ import { LogType } from "../network/api.js";
35
+ import { durationToSeconds } from "../util/parseISODuration.js";
36
+ import { LazySeq, HashMap } from "@seedtactics/immutable-collections";
37
+ import { atom } from "jotai";
38
+ const last30BufferEntriesRW = atom(HashMap.empty());
39
+ export const last30BufferEntries = last30BufferEntriesRW;
40
+ const specificMonthBufferEntriesRW = atom(HashMap.empty());
41
+ export const specificMonthBufferEntries = specificMonthBufferEntriesRW;
42
+ function convertEntry(e) {
43
+ if (e.elapsed === "")
44
+ return null;
45
+ const elapsedSeconds = durationToSeconds(e.elapsed);
46
+ if (elapsedSeconds <= 0)
47
+ return null;
48
+ switch (e.type) {
49
+ case LogType.RemoveFromQueue:
50
+ return [
51
+ e.counter,
52
+ {
53
+ buffer: { type: "Queue", queue: e.loc },
54
+ endTime: e.endUTC,
55
+ elapsedSeconds,
56
+ numMaterial: e.material.length,
57
+ },
58
+ ];
59
+ case LogType.PalletInStocker:
60
+ if (!e.startofcycle && e.result === "WaitForMachine") {
61
+ return [
62
+ e.counter,
63
+ {
64
+ buffer: { type: "StockerWaitForMC", stockerNum: e.locnum },
65
+ endTime: e.endUTC,
66
+ elapsedSeconds,
67
+ numMaterial: e.material.length,
68
+ },
69
+ ];
70
+ }
71
+ else if (!e.startofcycle) {
72
+ return [
73
+ e.counter,
74
+ {
75
+ buffer: { type: "StockerWaitForUnload", stockerNum: e.locnum },
76
+ endTime: e.endUTC,
77
+ elapsedSeconds,
78
+ numMaterial: e.material.length,
79
+ },
80
+ ];
81
+ }
82
+ else {
83
+ return null;
84
+ }
85
+ case LogType.PalletOnRotaryInbound:
86
+ if (!e.startofcycle) {
87
+ return [
88
+ e.counter,
89
+ {
90
+ buffer: { type: "Rotary", machineGroup: e.loc, machineNum: e.locnum },
91
+ endTime: e.endUTC,
92
+ elapsedSeconds,
93
+ numMaterial: e.material.length,
94
+ },
95
+ ];
96
+ }
97
+ else {
98
+ return null;
99
+ }
100
+ default:
101
+ return null;
102
+ }
103
+ }
104
+ export const setLast30Buffer = atom(null, (_, set, log) => {
105
+ set(last30BufferEntriesRW, (oldEntries) => oldEntries.union(LazySeq.of(log)
106
+ .collect(convertEntry)
107
+ .toHashMap((x) => x)));
108
+ });
109
+ export const updateLast30Buffer = atom(null, (_, set, { evt, now, expire }) => {
110
+ if (!evt.logEntry)
111
+ return;
112
+ const log = convertEntry(evt.logEntry);
113
+ if (!log)
114
+ return;
115
+ set(last30BufferEntriesRW, (entries) => {
116
+ if (expire) {
117
+ const expireD = addDays(now, -30);
118
+ entries = entries.filter((e) => e.endTime >= expireD);
119
+ }
120
+ return entries.set(log[0], log[1]);
121
+ });
122
+ });
123
+ export const setSpecificMonthBuffer = atom(null, (_, set, log) => {
124
+ set(specificMonthBufferEntriesRW, LazySeq.of(log)
125
+ .collect(convertEntry)
126
+ .toHashMap((x) => x));
127
+ });
@@ -0,0 +1,30 @@
1
+ import { ICurrentStatus } from "../network/api.js";
2
+ import type { ServerEventAndTime } from "./loading.js";
3
+ import { Atom } from "jotai";
4
+ export declare const currentStatus: Atom<ICurrentStatus>;
5
+ export declare const secondsSinceEpochAtom: import("jotai").PrimitiveAtom<number> & {
6
+ init: number;
7
+ };
8
+ export declare const setJobComment: import("jotai").WritableAtom<null, [uniq: string, newVal: string | null], void> & {
9
+ init: null;
10
+ };
11
+ export declare const addWorkorderComment: import("jotai").WritableAtom<null, [{
12
+ workorder: string;
13
+ comment: string;
14
+ }], void> & {
15
+ init: null;
16
+ };
17
+ export declare const setCurrentStatus: import("jotai").WritableAtom<null, [st: Readonly<ICurrentStatus>], void> & {
18
+ init: null;
19
+ };
20
+ export declare const updateCurrentStatus: import("jotai").WritableAtom<null, [ServerEventAndTime], void> & {
21
+ init: null;
22
+ };
23
+ export interface QueueReordering {
24
+ readonly queue: string;
25
+ readonly matId: number;
26
+ readonly newIdx: number;
27
+ }
28
+ export declare const reorderQueuedMatInCurrentStatus: import("jotai").WritableAtom<null, [QueueReordering], void> & {
29
+ init: null;
30
+ };
@@ -0,0 +1,200 @@
1
+ /* Copyright (c) 2021, John Lenz
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+
16
+ * Neither the name of John Lenz, Black Maple Software, SeedTactics,
17
+ nor the names of other contributors may be used to endorse or
18
+ promote products derived from this software without specific
19
+ prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+ import { JobsBackend, LogBackend } from "../network/backend.js";
34
+ import { InProcessMaterial, LogType, LocType, ActiveJob, WorkorderComment, ActiveWorkorder, } from "../network/api.js";
35
+ import { last30JobComment } from "./scheduled-jobs.js";
36
+ import { atom } from "jotai";
37
+ import { currentOperator } from "../data/operators.js";
38
+ const currentStatusRW = atom({
39
+ timeOfCurrentStatusUTC: new Date(),
40
+ jobs: {},
41
+ pallets: {},
42
+ material: [],
43
+ alarms: [],
44
+ queues: {},
45
+ });
46
+ export const currentStatus = currentStatusRW;
47
+ export const secondsSinceEpochAtom = atom(Math.floor(Date.now() / 1000));
48
+ secondsSinceEpochAtom.onMount = (setSelf) => {
49
+ const interval = setInterval(() => {
50
+ setSelf(Math.floor(Date.now() / 1000));
51
+ }, 1000);
52
+ return () => clearInterval(interval);
53
+ };
54
+ export const setJobComment = atom(null, (_, set, uniq, newVal) => {
55
+ const newComment = newVal === null ? "" : newVal;
56
+ set(currentStatusRW, (st) => {
57
+ const oldJob = st.jobs[uniq];
58
+ if (oldJob) {
59
+ const newJob = new ActiveJob(oldJob);
60
+ newJob.comment = newComment;
61
+ return { ...st, jobs: { ...st.jobs, [uniq]: newJob } };
62
+ }
63
+ else {
64
+ return st;
65
+ }
66
+ });
67
+ set(last30JobComment(uniq), newComment);
68
+ void JobsBackend.setJobComment(uniq, newComment);
69
+ });
70
+ export const addWorkorderComment = atom(null, (get, set, { workorder, comment }) => {
71
+ const operator = get(currentOperator);
72
+ set(currentStatusRW, (st) => {
73
+ if (!st.workorders)
74
+ return st;
75
+ return {
76
+ ...st,
77
+ workorders: st.workorders.map((w) => w.workorderId === workorder
78
+ ? new ActiveWorkorder({
79
+ ...w,
80
+ comments: [...(w.comments ?? []), new WorkorderComment({ comment, timeUTC: new Date() })],
81
+ })
82
+ : w),
83
+ };
84
+ });
85
+ void LogBackend.recordWorkorderComment(workorder, operator, comment);
86
+ });
87
+ export const setCurrentStatus = atom(null, (_, set, st) => set(currentStatusRW, st));
88
+ export const updateCurrentStatus = atom(null, (_, set, { evt }) => {
89
+ if (evt.logEntry) {
90
+ set(currentStatusRW, processEventsIntoCurrentStatus(evt.logEntry));
91
+ }
92
+ else if (evt.newCurrentStatus) {
93
+ set(currentStatusRW, evt.newCurrentStatus);
94
+ }
95
+ });
96
+ function processEventsIntoCurrentStatus(entry) {
97
+ return (curSt) => {
98
+ const mats = new Map();
99
+ function adjustMat(id, f) {
100
+ if (mats.size === 0) {
101
+ for (const m of curSt.material) {
102
+ mats.set(m.materialID, m);
103
+ }
104
+ }
105
+ const oldMat = mats.get(id);
106
+ if (oldMat !== undefined) {
107
+ mats.set(id, new InProcessMaterial(f(oldMat)));
108
+ }
109
+ }
110
+ switch (entry.type) {
111
+ case LogType.PartMark:
112
+ for (const m of entry.material) {
113
+ adjustMat(m.id, (inmat) => ({ ...inmat, serial: entry.result }));
114
+ }
115
+ break;
116
+ case LogType.OrderAssignment:
117
+ for (const m of entry.material) {
118
+ adjustMat(m.id, (inmat) => ({ ...inmat, workorderId: entry.result }));
119
+ }
120
+ break;
121
+ case LogType.Inspection:
122
+ case LogType.InspectionForce:
123
+ if (entry.result.toLowerCase() === "true" || entry.result === "1") {
124
+ let inspType;
125
+ if (entry.type === LogType.InspectionForce) {
126
+ inspType = entry.program;
127
+ }
128
+ else {
129
+ inspType = (entry.details || {}).InspectionType;
130
+ }
131
+ if (inspType) {
132
+ for (const m of entry.material) {
133
+ adjustMat(m.id, (inmat) => ({
134
+ ...inmat,
135
+ signaledInspections: [...inmat.signaledInspections, inspType],
136
+ }));
137
+ }
138
+ }
139
+ }
140
+ break;
141
+ }
142
+ if (mats.size === 0) {
143
+ return curSt;
144
+ }
145
+ else {
146
+ return {
147
+ ...curSt,
148
+ material: Array.from(mats.values()),
149
+ };
150
+ }
151
+ };
152
+ }
153
+ export const reorderQueuedMatInCurrentStatus = atom(null, (_, set, { queue, matId, newIdx }) => {
154
+ set(currentStatusRW, (curSt) => {
155
+ const oldMat = curSt.material.find((i) => i.materialID === matId);
156
+ if (!oldMat || oldMat.location.type !== LocType.InQueue) {
157
+ return curSt;
158
+ }
159
+ if (oldMat.location.currentQueue === queue && oldMat.location.queuePosition === newIdx) {
160
+ return curSt;
161
+ }
162
+ const oldQueue = oldMat.location.currentQueue;
163
+ const oldIdx = oldMat.location.queuePosition;
164
+ if (oldIdx === undefined || oldQueue === undefined) {
165
+ return curSt;
166
+ }
167
+ const newMats = curSt.material.map((m) => {
168
+ if (m.location.type !== LocType.InQueue ||
169
+ m.location.queuePosition === undefined ||
170
+ m.location.currentQueue === undefined) {
171
+ return m;
172
+ }
173
+ if (m.materialID === matId) {
174
+ return new InProcessMaterial({
175
+ ...m,
176
+ location: { type: LocType.InQueue, currentQueue: queue, queuePosition: newIdx },
177
+ });
178
+ }
179
+ let idx = m.location.queuePosition;
180
+ // old queue material is moved down
181
+ if (m.location.currentQueue === oldQueue && m.location.queuePosition > oldIdx) {
182
+ idx -= 1;
183
+ }
184
+ // new queue material is moved up to make room
185
+ if (m.location.currentQueue === queue && idx >= newIdx) {
186
+ idx += 1;
187
+ }
188
+ if (idx !== m.location.queuePosition) {
189
+ return new InProcessMaterial({
190
+ ...m,
191
+ location: { ...m.location, queuePosition: idx },
192
+ });
193
+ }
194
+ else {
195
+ return m;
196
+ }
197
+ });
198
+ return { ...curSt, material: newMats };
199
+ });
200
+ });
@@ -0,0 +1,41 @@
1
+ import { ILogEntry } from "../network/api.js";
2
+ import { LazySeq, HashMap, OrderedMapKey } from "@seedtactics/immutable-collections";
3
+ import type { PartCycleData } from "./station-cycles.js";
4
+ import { Atom } from "jotai";
5
+ export interface StatisticalCycleTime {
6
+ readonly medianMinutesForSingleMat: number;
7
+ readonly MAD_belowMinutes: number;
8
+ readonly MAD_aboveMinutes: number;
9
+ readonly expectedCycleMinutesForSingleMat: number;
10
+ }
11
+ export declare class PartAndStationOperation {
12
+ readonly part: string;
13
+ readonly statGroup: string;
14
+ readonly operation: string;
15
+ constructor(part: string, statGroup: string, operation: string);
16
+ static ofLogCycle(c: Readonly<ILogEntry>): PartAndStationOperation;
17
+ static ofPartCycle(c: Readonly<PartCycleData>): PartAndStationOperation;
18
+ compare(other: PartAndStationOperation): number;
19
+ hash(): number;
20
+ toString(): string;
21
+ }
22
+ export type EstimatedCycleTimes = HashMap<PartAndStationOperation, StatisticalCycleTime>;
23
+ export declare const last30EstimatedCycleTimes: Atom<EstimatedCycleTimes>;
24
+ export declare const specificMonthEstimatedCycleTimes: Atom<EstimatedCycleTimes>;
25
+ export declare function isOutlier(s: StatisticalCycleTime, mins: number): boolean;
26
+ export declare function isOutlierAbove(s: StatisticalCycleTime, mins: number): boolean;
27
+ export declare function chunkCyclesWithSimilarEndTime<T, K>(allCycles: LazySeq<T>, getKey: (t: T) => K & OrderedMapKey, getTime: (c: T) => Date): LazySeq<[K, ReadonlyArray<ReadonlyArray<T>>]>;
28
+ export interface LogEntryWithSplitElapsed<T> {
29
+ readonly cycle: T;
30
+ readonly elapsedForSingleMaterialMinutes: number;
31
+ }
32
+ export declare function splitElapsedTimeAmongChunk<T extends {
33
+ material: ReadonlyArray<unknown>;
34
+ }>(chunk: ReadonlyArray<T>, getElapsedMins: (c: T) => number, getActiveMins: (c: T) => number): ReadonlyArray<LogEntryWithSplitElapsed<T>>;
35
+ export declare function calcElapsedForCycles(eventLog: ReadonlyArray<Readonly<ILogEntry>>): LazySeq<LogEntryWithSplitElapsed<Readonly<ILogEntry>>>;
36
+ export declare const setLast30EstimatedCycleTimes: import("jotai").WritableAtom<null, [log: readonly Readonly<ILogEntry>[]], void> & {
37
+ init: null;
38
+ };
39
+ export declare const setSpecificMonthEstimatedCycleTimes: import("jotai").WritableAtom<null, [log: readonly Readonly<ILogEntry>[]], void> & {
40
+ init: null;
41
+ };