Compare commits

...

535 Commits
1.6.7 ... main

Author SHA1 Message Date
Matt McWilliams f17d137d25 Work on neopixel light. 2025-05-14 21:00:25 -04:00
Matt McWilliams 1fbde2d366 Caught a critical error with the filmout feature. Due to work on the server feature, all filmout functionality was being routed through the server, instead of just making it an optional display source if a client is connected. The use of the server.useServer() method was implemented and the filmout display method was updated to not return early. Special thanks to Sandy McLennan for catching this one. 2025-05-14 20:59:59 -04:00
Matt McWilliams e8da086707 Add missing package declarations 2025-05-08 19:04:50 -04:00
Matt McWilliams 56310b6969 Move work from contact printer design philosphy section to mcopy, which is to be the more in-depth paper 2025-02-21 11:53:59 -05:00
Matt McWilliams f95c033165 All work on whitepaper, philosophy and motivations are the current focus 2025-02-21 00:21:34 -05:00
Matt McWilliams 93cc0d4151 Create a placeholder for the mcopy whitepaper 2025-02-20 14:37:16 -05:00
Matt McWilliams 920c257bf1 Reference common/common.scad, not the removed local one. Update takeup 2025-02-13 22:59:14 -05:00
Matt McWilliams 0021bd7512 All work on takeup. First pass, printing feed side to test. 2025-02-13 22:58:03 -05:00
Matt McWilliams 19c5ee3540 Takeup WIP 2025-02-12 23:07:10 -05:00
Matt McWilliams ae02e3de44 Move takeup script (now its own module) to build a better version of what is in the examples of that module. 2025-02-12 23:01:44 -05:00
Matt McWilliams eb78341275 Remove extra common.scad now that the shared script is in use 2025-02-12 22:52:17 -05:00
Matt McWilliams b43e97bad4 Update all references to common.scad to use the shared module 2025-02-12 22:51:43 -05:00
Matt McWilliams 344e367cd9 Final fix of .gitmodules by fixing my local scripts 2025-02-12 22:49:34 -05:00
Matt McWilliams 93b33f09e2 Remove mcad 2025-02-12 22:46:53 -05:00
Matt McWilliams 72e91a41fb Remove mcad 2025-02-12 22:46:44 -05:00
Matt McWilliams 02e697822b Overhaul of scad submodules and scripts. Use the scad.sh script in the common module 2025-02-12 22:36:18 -05:00
Matt McWilliams 71e541afb5 Add ignore = dirty to all submodules 2025-02-12 13:37:16 -05:00
Matt McWilliams 25ba26b063 Update the sprocketed_roller module used in this project 2025-02-12 13:35:36 -05:00
Matt McWilliams f775c330a6 All work on the gate 2025-01-12 14:04:05 -05:00
Matt McWilliams 25f0cce1ff Resolved a bug that was preventing callback from working. Previously only worked because of a race condition introduced by a setTimeout 2025-01-12 14:03:58 -05:00
Matt McWilliams 6d99122a33 BOM script produces links to parts 2024-11-28 14:43:06 -05:00
Matt McWilliams 1d2a65867b All work on 16mm gate. Frame seems centered. 2024-11-26 13:28:03 -05:00
Matt McWilliams 498b585b67 Add support for controlling the printer with an NES retro-style USB controller. As long as it has 10 buttons. 2024-11-26 13:27:31 -05:00
Matt McWilliams 93ac73f69e Improvements to the mcopy JK99 board: now the JK100.2 2024-11-19 15:30:21 -05:00
Matt McWilliams d40957063c All work on mcopy hardware. Improvements to gate peg bars, film path, front block and gate mask slides. Improvement to rails mounts for Bolex and Arri. Improvements to projector controller electronics mount. 2024-11-19 01:24:27 -05:00
Matt McWilliams 34dfb25f57 Work on mcopy gate. Adjustments to plate sizes (made front_plate thicker to print better without cracking) 2024-11-13 14:45:11 -05:00
Matt McWilliams e771056313 Work on adding reinforcement to the electronics mount. 2024-11-09 17:09:45 -05:00
Matt McWilliams 9a526eac71 More work on gate and updated BOM 2024-11-07 12:47:31 -05:00
Matt McWilliams 2866eaa2ef All work on gate. Add peg bar and use the BOM script when compiling all parts. 2024-11-06 12:32:54 -05:00
Matt McWilliams e6c65650de BOM script calculates total costs of rows of parts and entire BOM 2024-11-05 20:50:42 -05:00
Matt McWilliams bc71d86ee6 Generate the BOM. Need to work on the priceing stage, but works for current purposes. 2024-11-05 20:13:36 -05:00
Matt McWilliams e9b89bd10b Add adjustments for new filmless library 2024-11-05 15:15:31 -05:00
Matt McWilliams ff927564b6 Work on mcopy_gate front_block(). Countersink the m2.5 nuts in the slide and gate masks 2024-11-04 22:52:02 -05:00
Matt McWilliams 4b0cc2e766 Mcopy gate work before demo changes. 2024-11-04 22:25:57 -05:00
Matt McWilliams bf5b927cb3 add neopixel sketch. still working on hardware. 2024-10-30 16:00:05 -04:00
Matt McWilliams c4b175866d Work on gate, need to add catch to slide to prevent from coming out too far with spring-loaded action 2024-10-24 22:15:06 -04:00
Matt McWilliams 8de80ab44d Replace all bolts in m3 with m2.5 bolts. 2024-10-23 11:25:58 -04:00
Matt McWilliams 31adb77f90 Commit changes to endstop camera shield without debug log lines 2024-10-22 17:33:18 -04:00
Matt McWilliams 9515232d12 All work on gate before m3 -> m2.5 changes and other updates based on physical assembling and testing. 2024-10-17 20:59:51 -04:00
Matt McWilliams 2b2fc66581 Start work on LED lamp tests 2024-10-17 20:28:36 -04:00
Matt McWilliams 78aa627c5d Updated Fritzing project for JK99 (now JK100.1) shield. 2024-10-15 16:49:25 -04:00
Matt McWilliams 0eaefb2b48 When mscript compilation fails, throw error in console. 2024-10-14 12:12:39 -04:00
Matt McWilliams b51b7e8481 Update scripts to reflect capability of the mscript interpreter right now. No set within loops. Resolves #10 2024-10-14 09:49:37 -04:00
Matt McWilliams c365eff6a7 Fixed single issue related to #11. If state of secondary projector or camera are set, include in output. 2024-10-13 15:49:44 -04:00
Matt McWilliams 4149d77d70 Render all mcopy_gate parts and add them to the scad render script. 2024-10-08 23:15:15 -04:00
Matt McWilliams 28a323f4f8 Detail work on mcopy gate 2024-10-08 08:16:32 -04:00
Matt McWilliams 09d7274bce Adjustments to gate sprocketed rollers 2024-09-22 11:29:50 -04:00
Matt McWilliams af97f5da1e Update sprocketed roller design to use a nut to lock in place 2024-09-18 23:10:40 -04:00
Matt McWilliams 16b7a7def2 Bevel the sides where the film enters the gate. 2024-09-14 18:49:32 -04:00
Matt McWilliams 320e38bfd8 Fix text labels on gates 2024-09-14 11:18:33 -04:00
Matt McWilliams 1f18b59f9d Round the filmpath bevels. Safer areas touching film. 2024-09-14 11:17:31 -04:00
Matt McWilliams 750cd3e67c Label the gate masks 2024-09-13 19:01:20 -04:00
Matt McWilliams b4271c3c86 Save work on lens assembly 2024-09-12 23:10:34 -04:00
Matt McWilliams 73418031ae Save gate work (broken). 2024-09-12 23:10:08 -04:00
Matt McWilliams 95f8674d72 Work on JK lens assembly 2024-08-25 09:29:31 -04:00
Matt McWilliams 689447611a Update the lens assembly debug mode to match current prints. 2024-08-15 10:28:00 -04:00
Matt McWilliams 8de61abd7b Render parts of the lens assembly 2024-08-09 17:14:23 -04:00
Matt McWilliams 0b59f4906f Implement the button and switch logic for physical interfaces to the camera. In the case that the open/close switch is changed, move to that state, otherwise allow for digital control. 2024-08-05 06:47:12 -04:00
Matt McWilliams 7cecef3de5 Add getDirection() to EndstopCameraShield and fix sloppy bugs in code that were not disabling emitters after actions. Could have caused false positives in behavior so check on the machine 2024-08-03 08:46:46 -04:00
Matt McWilliams 35d832f965 Prefill exposureAvg with 250ms because it is closest to an average from tests 2024-07-31 13:40:10 -04:00
Matt McWilliams c3d2943dcc All updates to EndstopCameraShield library for Oxberry and Mitchell cameras (now working and tested). 2024-07-30 20:00:09 -04:00
Matt McWilliams abc72087b2 Update data in all places 2024-07-08 22:59:54 -04:00
Matt McWilliams f594472fd2 Created the basics of the mitchell and oxberry firmwares. Mitchell still needs button logic but oxberry will be controlled entirely digitally. 2024-07-07 22:17:48 -04:00
Matt McWilliams 29cd83eecf There does not need to be separate open_forward/open_backward and closed_forward/closed_backward commands. Direction should be set with separate commands and can be controlled at a higher level. 2024-07-07 21:32:02 -04:00
Matt McWilliams c0e7422920 Work on oxberry camera firmware. Basics are there. Will add button features to mitchell. 2024-07-05 23:56:45 -04:00
Matt McWilliams 84fe1b71be Accidentally modified an autogenerated part of McopySerial. Fixed 2024-06-30 12:10:30 -04:00
Matt McWilliams 966f67882a Fix ino.sh script. Add pin declarations to EndstopCameraShield 2024-06-30 11:50:02 -04:00
Matt McWilliams b858c9fba0 Create placeholder scripts for Mitchell and Oxberry cameras 2024-06-23 21:38:36 -04:00
Matt McWilliams d1028a7e02 Work on endstopcamerashield.h 2024-06-22 22:57:20 -04:00
Matt McWilliams 603d5b0219 Merge branch 'main' of ssh://git.sixteenmillimeter.com/16mm/mcopy 2024-06-22 14:11:34 -04:00
Matt McWilliams df66ff1c7d Hardware updates 2024-06-22 14:11:19 -04:00
Matt McWilliams e6ef1ff395 Actually add new commands to cfg and all libs 2024-06-13 13:42:05 -04:00
Matt McWilliams 8e9a57bcd3 Add new command flags for camera open camera closed. Re-organized and separated identifiers and cmd flags 2024-06-13 13:35:25 -04:00
Matt McWilliams 4dc988c5bb Resolves #83; Adds the -hwaccel auto flag to all ffmpeg output commands. May not be used unless the source video is an accelerated format. 2024-05-24 15:43:52 -04:00
Matt McWilliams bc081cfe63 Correct lib jsdocs in modules. Update tests to catch new error in mscript. 2024-05-24 15:23:58 -04:00
Matt McWilliams 6c8d2d712d Remove callback from mscript (never used) and make all non-public methods private. 2024-05-24 00:26:12 -04:00
Matt McWilliams b4a974a33e Updated tests to add cases catching mscript failing on multi-device scripts 2024-05-24 00:09:28 -04:00
Matt McWilliams b21b899303 Re-enabled tests. Re-enabled docs build (jsdocs are very out of date). Removed several any types and created types for Config 2024-05-23 23:36:51 -04:00
Matt McWilliams 5597aea828 Do not display broken layout before devices are ready 2024-05-23 20:56:32 -04:00
Matt McWilliams 5d31bf0020 Ported main.js to TypeScript. Rewrote all imports and replaced with class constructors, not require()(). 2024-05-23 20:51:35 -04:00
Matt McWilliams 91ad944c46 Removed several uses of any and added types to System module. 2024-05-23 19:54:42 -04:00
Matt McWilliams cb63194fc6 All known classes have types exported and imported into dependent modules. This has already caught a class of bugs. Removing references to any will catch another. 2024-05-23 18:49:18 -04:00
Matt McWilliams 7f8a9d4289 Add Settings and Devices classes TypeScript source. 2024-05-22 23:37:21 -04:00
Matt McWilliams 8e8fac92d1 Update Settings class to export properly. Replace use of any in Device. 2024-05-22 23:36:40 -04:00
Matt McWilliams 7e24c70454 Re-write of log module to use export properly (in Typescript) and include the winston types for Logger. Will repeat this step with all of the remaining modules that are declared 'any' type and miss out on the benefits of using Typescript in the first place. 2024-05-19 18:14:33 -04:00
Matt McWilliams a9f20ebf36 Remove extraneous log lines from arduino. Device is printed by send() and also sendAsync is called by send and logs the same information. Removed. 2024-05-19 17:11:31 -04:00
Matt McWilliams 4b8c8ee842 Improve logging in JKMM100 sketches. 2024-05-19 17:10:50 -04:00
Matt McWilliams 5bad15a79a In a two device simultaneous action, the cmd module was attemptint to await both actions in an array. This was not working and caused await to not occur. Instead, all actions have been replaced by a Promise.all, which awaits both actions simultaneously until both are complete. After that, function is correct. 2024-05-19 11:05:16 -04:00
Matt McWilliams 9b7d1a3e5c Add a second projector version of the JKM100 script. In the script, move the 16ms delay to BEFORE the confirmation character and increase it to 100ms to make sure all shake is out of the system before shooting a frame. 2024-05-19 09:38:48 -04:00
Matt McWilliams 5f7fa6287f Add changes from diverged repo 2024-05-15 21:49:45 -04:00
Matt McWilliams 2af8b4b209 Merge remote-tracking branch 'origin/main' 2024-04-28 21:38:32 -04:00
Matt McWilliams 66096fa2ea Add the designs and sketches for the ACME Trebes. 2024-04-19 18:09:44 -06:00
Matt McWilliams 18875a01c6 Correctly reference common.scad and add file for camera mount. 2024-04-15 14:05:38 -06:00
Matt McWilliams 7d2c2b9d09 Use common.scad, change all cylinder entries 2024-04-15 09:42:25 -06:00
Matt McWilliams 67a290a02a Add a bellows adapter for Canon RF cameras and an ACME bellows 2024-04-14 13:34:41 -06:00
Matt McWilliams 63f4278b2b Resolve startup order issues and explanation for all the delays that were meager attempts to solve a race condition. By moving more IPC connectionts to handles, which can be awaited, there are no more attempts to send message to light object that fails because it has not yet been instantiated. 2024-04-06 23:37:30 -04:00
Matt McWilliams 6778f871db Devices, serial and type terms were updated everywhere in code except in the settings object. 2024-04-06 20:29:56 -04:00
Matt McWilliams edc72a5486 Do not overwrite data with an empty object. Overwrite values if there are keys in the object. 2024-04-06 20:15:19 -04:00
Matt McWilliams 2779258111 List of devices looks strange on laptop. Attempt at fix here 2024-04-06 20:10:14 -04:00
Matt McWilliams da735779b4 Add more trycatches add more logs. Not sure where failure is. 2024-04-06 20:00:54 -04:00
Matt McWilliams b7e2e912f4 Figure out why devices.ready() is not reaching end of method on Mono laptop 2024-04-06 19:53:04 -04:00
Matt McWilliams d34172d8e9 Use device.profile() method, seemingly not implemented properly 2024-04-06 19:37:29 -04:00
Matt McWilliams f30ce78f9d Suppress warnings from Intval and execRaw during compilation. Add logging to ready to test on Mono laptop 2024-04-06 19:18:15 -04:00
Matt McWilliams ed767aedb5 Recompile with newer modules. 2024-04-06 19:09:50 -04:00
Matt McWilliams ab35895cb3 update rails 2024-04-06 19:02:39 -04:00
Matt McWilliams 1e2b65644d Update package lock files to work with node16 and electron19 2024-04-06 18:55:46 -04:00
Matt McWilliams 3f58bbc617 Merged changes from work script into JKMM100, works on device in both work script and deployment one 2024-04-06 15:48:02 -04:00
Matt McWilliams c1da7b53a2 Fix for the canonical URL caught by Tom Murphy
Thanks Tom!
2024-01-24 05:19:07 +00:00
Matt McWilliams 4181c22995 Cleanup whitespace/semicolons and add concept for passing an exposure length to the image in millis. 2024-01-19 06:49:03 -05:00
Matt McWilliams d31ac53bd1 Back is ready to print 2024-01-09 13:54:01 -05:00
Matt McWilliams 9b954852aa Add the first draft for the CPC plug back 2024-01-08 15:49:08 -05:00
Matt McWilliams 3758916fb5 Adjust plug insert 2024-01-06 17:56:55 -05:00
Matt McWilliams 25c1395655 make insert thicker for betther overall strength of the plug 2024-01-06 14:30:00 -05:00
Matt McWilliams 440edd7b18 Add 5mm marks to bolex plate 2023-12-27 23:56:10 -05:00
Matt McWilliams a2f045841f Fix bolt countersink in bolex mounting block. Add center line to top 2023-12-27 20:04:43 -05:00
Matt McWilliams c890107e1e Experimental refactor, move commonly-used pattern of cylinder() module with 4 names arguments to cy() with 3 positional arguments, D = diameter, H = height, and FN = $fn. Might improve readability and reduce repetative use of center = true. 2023-12-26 17:37:39 -05:00
Matt McWilliams a5df1650b9 Move nuts to bottom of camera sled and bolts can drop in from the top (easier assembly, bolts can be glued in place or held in more easily). Create camera sled bolex plate and modify the bolex standoff to accomodate it. WIP. 2023-12-23 23:08:59 -05:00
Matt McWilliams 173ce499bc CPC connector work 2023-12-15 19:40:18 -05:00
Matt McWilliams 33412b0588 Merge branch 'main' of ssh://git.sixteenmillimeter.com/16mm/mcopy 2023-12-10 22:51:38 -05:00
Matt McWilliams 3c5e31a961 Work on CPC Connector plug 2023-12-10 22:48:12 -05:00
Matt McWilliams 39676f9a06 fastcsg is non-deterministic 2023-12-02 09:40:54 -05:00
Matt McWilliams 0f893d94c4 Fix the dual projector script and add notes 2023-11-30 22:32:48 -05:00
Matt McWilliams b08f5094d5 Make a solid bearing roller 2023-11-30 22:32:33 -05:00
Matt McWilliams 70e046eeb7 Fix plug diameter 2023-11-30 22:32:18 -05:00
Matt McWilliams 58d0742187 Add takeup signal terminals to the mcopy projector board. 2023-11-28 23:09:09 -05:00
Matt McWilliams f84e8b741a Developed a seemingly working fix with the "correction loop" strategy. Might be putting the motor through hell but it is consistent. 2023-11-25 20:22:44 -05:00
Matt McWilliams fcf24b5539 Add the OFFSET command to the McopySerial library 2023-11-25 20:06:16 -05:00
Matt McWilliams 128a4d2ded Update mcopy_JKMM100_work to have McopySerial library 2023-11-25 20:05:52 -05:00
Matt McWilliams b14d24e650 Prototype for Arduino Mega shield for projector. 2023-11-25 18:08:10 -05:00
Matt McWilliams 7995665c6b Add camera sled 2023-11-24 10:58:20 -05:00
Matt McWilliams a22906d3c2 Add mcopy projector board. 2023-11-22 17:33:23 -05:00
Matt McWilliams 042533dc85 Add plugs for linear bearings in rail ends. 2023-11-19 16:08:37 -05:00
Matt McWilliams 5fbefeecbf Update to the orbital brace 2023-11-13 20:43:13 -05:00
Matt McWilliams a9772ff081 Changes to the brace to allow the projector to fit. Made Y of panel larger. 2023-11-13 20:41:26 -05:00
Matt McWilliams cdf983c7c6 Render STLs for mcopy_projector and mcopy_rails. Make tweaks to orbital mount to fit bolts. 2023-11-12 15:22:23 -05:00
Matt McWilliams 03f886580f Created orbital brace corner and rendered additional stls 2023-11-09 15:54:56 -05:00
Matt McWilliams a06e2869b9 Adjust bolt voids on corner_bracket 2023-11-08 18:15:31 -05:00
Matt McWilliams 6bafb263de Projector rails added and printed 2023-11-04 09:38:20 -04:00
Matt McWilliams 493ff5fbf6 Update raisl and render all files 2023-11-01 00:27:46 -04:00
Matt McWilliams c29e0880ac Work on rails and lens gantry. First prototype is made. Rendering all. 2023-10-30 22:02:30 -04:00
Matt McWilliams 986c7a915b Tweaks to lens sled gantry 2023-10-26 18:11:35 -04:00
Matt McWilliams 68b1b8b819 Double bearings in lens sled 2023-10-24 22:20:47 -04:00
Matt McWilliams 382ba56fa7 Create a prospective "inaccurate" analogReadAverage method. 2023-10-10 22:29:02 -04:00
Matt McWilliams 24d6685047 Use I to trigger projector.home() 2023-10-10 22:12:31 -04:00
Matt McWilliams 565d2ecceb Add second dataset for testing findPeak method 2023-10-10 21:20:51 -04:00
Matt McWilliams c4456e458f Add "home" as command character "I". 2023-10-10 21:16:49 -04:00
Matt McWilliams f707dedc91 New homing behavior. Ready to port back to original. 2023-10-09 22:59:05 -04:00
Matt McWilliams 702fc4680d Had accidentally switched motors, explaining odd homing behavior. New homing behavior whips ass. 2023-10-09 22:58:48 -04:00
Matt McWilliams 99b63150ac Add more smoothing during homing step. Is running consistently but is ending with motor in wrong position each time. Very strange. 2023-10-09 20:52:58 -04:00
Matt McWilliams 6e7c226c57 Make a sample script for analyzing the array during homing step. 2023-10-09 20:52:18 -04:00
Matt McWilliams c8e5f7b742 Caught one bug after separating out code 2023-10-09 19:15:30 -04:00
Matt McWilliams 0cf147d185 Piece off homing code into its own script. 2023-10-09 19:09:50 -04:00
Matt McWilliams cf1514f53e Print lens slded at full width (140mm for now) 2023-10-09 19:07:16 -04:00
Matt McWilliams af3843a8ef Add servo functionality for rack and pinion motion. Need to fix home feature. 2023-10-09 09:59:19 -04:00
Matt McWilliams 91ce2dd450 Add BOM log lines and move rail ends into its own module 2023-10-09 09:58:55 -04:00
Matt McWilliams 71c9efae42 Tweak to the rack and pinion mechanism to allow it to fit. 2023-10-09 09:58:35 -04:00
Matt McWilliams 08ce0d792b Fix for case where this.confirmExec is not a function 2023-10-08 18:15:31 -04:00
Matt McWilliams 754ef17b74 Update servo gear to fit reinforced servo connectors. 2023-10-08 11:41:35 -04:00
Matt McWilliams 5d4fec8c81 Start adding BOM log lines to build. 2023-10-07 15:26:10 -04:00
Matt McWilliams 1e0338a77f Update rack and pinion library to one that produces valid geometry. Make first pass at rack and pinion gear 2023-10-06 13:47:15 -04:00
Matt McWilliams e6b9628746 All projector work from today 2023-10-05 17:28:01 -04:00
Matt McWilliams 6f68081dc5 Restore the home method. Now it compiles. 2023-10-03 13:44:04 -04:00
Matt McWilliams 66b18dd351 Work on LED enclosure 2023-10-03 09:16:34 -04:00
Matt McWilliams b5f5b6461a Work on LED housings 2023-09-28 22:51:55 -04:00
Matt McWilliams 6dd29d9596 Disable home feature for now. Fixed impossibly stupid bug with reverse mode. Used uint16_t rather than int16_t causing an overflow. 2023-09-28 20:46:45 -04:00
Matt McWilliams 29ba125534 Work on LED housing. 2023-09-27 21:31:35 -04:00
Matt McWilliams 144af1414c Merge remote-tracking branch 'origin/main' 2023-09-27 19:10:24 -04:00
Matt McWilliams 06906eca42 Start progress on rack and pinion nub mover 2023-09-27 19:10:13 -04:00
Matt McWilliams 0d47748d6a Saved work in progress 2023-09-27 10:07:50 -04:00
Matt McWilliams b1c8192625 Projector firmware progress: currently the homing function will not compile due to errors with reference and so the sketch method needs to be broken into workable smaller methods 2023-09-25 21:54:31 -04:00
Matt McWilliams d2c7781d79 Servo notch puller progress 2023-09-25 21:53:10 -04:00
Matt McWilliams 37d4f50ef4 Add OpenSCAD/MCAD to the project to prevent double work. Including as a submodule appears to satisfy the requirement of the LGPL and allows mcopy to remain MIT licensed. 2023-09-25 12:25:56 -04:00
Matt McWilliams 082ac85c5c Add deeper notches for 90 degree points 2023-09-25 12:14:59 -04:00
Matt McWilliams cfca56ba48 Migrate stepper block into its own module 2023-09-24 22:58:14 -04:00
Matt McWilliams c7cb4ddbc5 Create the first design of the orbital mount and make slight adjustment to panel (screws were not attaching fully). 2023-09-24 22:46:38 -04:00
Matt McWilliams 7f98d6028b Commit all work in progress 2023-09-21 21:06:31 -04:00
Matt McWilliams 401822a7bb Merge branch 'main' of ssh://git.sixteenmillimeter.com/16mm/mcopy 2023-09-15 19:18:09 -04:00
Matt McWilliams 173ba06590 Work on projector (wrong) 2023-09-14 23:30:29 -04:00
Matt McWilliams 2677118bad fix 2023-09-12 22:36:18 -04:00
Matt McWilliams 8e90456d87 LED gate should be larger 2023-09-12 21:53:38 -04:00
Matt McWilliams 0b880a5e79 Add accurateRead functions and Readme 2023-09-06 15:41:36 -04:00
Matt McWilliams 082dbc0826 Add void for motor, threaded rod (optional) and linear rod. 2023-09-06 00:01:00 -04:00
Matt McWilliams 5eccbbf6df Remove part of the 2020 ends so that it can print without supports 2023-09-05 23:29:48 -04:00
Matt McWilliams 513deb7a0a Render part of the projector. 2023-09-05 23:15:53 -04:00
Matt McWilliams 2b24dc647c Update lens assembly to start using a 2020 frame 2023-09-05 23:15:32 -04:00
Matt McWilliams f8e5968f30 Rename JK lens assembly to reflect it is a new design 2023-09-05 21:31:31 -04:00
Matt McWilliams 18b8c84fff Add additional bearings to lens sled and voids for m5 bolts to hold in side bearings. 2023-09-04 13:10:23 -04:00
Matt McWilliams 1d6ccb7838 Enlarge void for m5 bolt. Add void for m5 nut. 2023-09-04 11:43:01 -04:00
Matt McWilliams a7a63a3be7 Render all projector and rails in current state 2023-09-04 10:49:20 -04:00
Matt McWilliams 153ef9eceb Use fast-csg and parallel with 8 jobs hardcoded 2023-09-04 10:48:54 -04:00
Matt McWilliams eec7765e73 Restore settings logic 2023-08-30 01:18:10 -04:00
Matt McWilliams 03f2b55762 Fucked up the merge 2023-08-29 23:33:42 -04:00
Matt McWilliams 6714374639 restore work from tonight 2023-08-29 23:11:24 -04:00
Matt McWilliams b6b1f5d5ba Parts work 2023-08-29 22:34:55 -04:00
Matt McWilliams d7a10f9737 Enable different modes of stepping by using the settings pins. Previously was causing odd behavior because they were being used for LEDs. 2023-08-29 19:48:49 -04:00
Matt McWilliams d778adc7d0 Add LED holder concept to projector panel design 2023-08-29 17:05:53 -04:00
Matt McWilliams dcbb57f732 Rewrite mcopy_projector_firmware with AccelStepper, replacing the custom Itead firmware (not working) 2023-08-29 15:33:51 -04:00
Matt McWilliams 24452794a9 Merge remote-tracking branch 'origin/main' 2023-08-25 16:44:35 -04:00
Matt McWilliams 24fe1e8773 Work on projector: Still having issues with IteadDualStepperShield (addresses wrong motor, wrong number of steps). 2023-08-25 16:44:28 -04:00
Matt McWilliams b30c637c10 Add structures to insert 2020 Tslot into to make rails fit more snug 2023-08-23 23:35:00 -04:00
Matt McWilliams f16795b11c Render the mcopy rails parts in current form 2023-08-23 22:27:06 -04:00
Matt McWilliams 141d27599f McopyProjector lib for mcopy_projector_firmware rewrite in progress. 2023-08-23 15:21:50 -04:00
Matt McWilliams 86c88c4ac2 Printing a prototype for the lens sled 2023-08-23 00:14:47 -04:00
Matt McWilliams fbab0c043a Give up on SCAD makefile 2023-08-21 22:47:29 -04:00
Matt McWilliams 1a01a4f05e Update sprocketed_roller 2023-08-21 22:47:05 -04:00
Matt McWilliams b0305ae6da Run on all but 1 core. Update JK rails to use actual measurement 2023-08-21 22:46:42 -04:00
Matt McWilliams dd4834de04 Render rails parts (still WIP) 2023-08-21 19:39:08 -04:00
Matt McWilliams 2d90c127a3 Render existing projector panel parts 2023-08-21 19:38:55 -04:00
Matt McWilliams 51d440fccc Render all working CPC connector parts 2023-08-21 19:38:16 -04:00
Matt McWilliams 2e3ed56bb3 Update part names of bellows.scad. Render missing magnetic board. 2023-08-21 19:34:21 -04:00
Matt McWilliams 4be57f3128 Update part names for CPC connectors 2023-08-21 19:31:20 -04:00
Matt McWilliams de6f0d0495 Compile all parts in project, optionally using GNU parallel if available. 2023-08-21 19:04:39 -04:00
Matt McWilliams 98e1e73163 Update to a dynamic bash file that can render all parts in a .scad file 2023-08-21 18:23:41 -04:00
Matt McWilliams 1ae524ff31 Start making a parts list in rails end file 2023-08-21 18:23:16 -04:00
Matt McWilliams 010927c5ca Rename rails_2020 to mcopy_rails 2023-08-20 23:55:27 -04:00
Matt McWilliams 3346bf01af Work on rails having a bearing 2023-08-20 23:54:21 -04:00
Matt McWilliams 788cac7d50 All work towards creating a sled rail for the lens carriage assembly 2023-08-20 18:35:48 -04:00
Matt McWilliams 4c0fa2ba41 rails end prototype 2023-08-20 13:57:00 -04:00
Matt McWilliams 83209f466f Update all submodules 2023-08-20 12:46:36 -04:00
Matt McWilliams 10c452c1b3 Work on rails 2023-08-20 12:37:50 -04:00
Matt McWilliams a8a33a823a Update to 1.8.0 to reflect new breaking changes in app 2023-08-06 15:22:38 -04:00
Matt McWilliams e7e7f86ab3 Manual merge from capper branch: all changes to devices library. 2023-08-06 15:04:33 -04:00
Matt McWilliams 386285d48c Definition file that prevents compiler warnings on some platforms. Still unexplained because tsc is installed local to the project. 2023-08-06 14:58:26 -04:00
Matt McWilliams c4119ab7cc Manual merge from capper branch: all changes to arduino library with some improvements. 2023-08-06 14:56:42 -04:00
Matt McWilliams 176643f148 Manual merge from capper branch: all changes to display library. 2023-08-06 14:36:31 -04:00
Matt McWilliams 8b235bb6b0 mitchell work 2023-08-05 14:42:03 -04:00
Matt McWilliams 8a170f65ca Merge pull request 'canon_ble' (#82) from canon_ble into main
Reviewed-on: #82
2023-08-01 03:38:51 +00:00
Matt McWilliams 2f56dd4b8a Update the timing after delaying for 5000ms (hack) 2023-07-30 23:03:06 -04:00
Matt McWilliams 699c2dbec8 UI cleanup 1: confirm setting the exposure 2023-07-30 22:26:05 -04:00
Matt McWilliams dac720863d Resolves #80 and #81. UI will need a little cleanup. There is some string concatenation happening where it shouldn't. 2023-07-30 22:13:50 -04:00
Matt McWilliams 3b03eb70fb Add placeholder for original stepper motor 2023-07-24 21:20:06 -04:00
Matt McWilliams a173cf0d7c WIP 2023-07-23 20:00:42 -04:00
Matt McWilliams 55b39e7db3 Tweak to USB protector 2023-07-18 23:13:20 -04:00
Matt McWilliams 505a2a71e7 Add magnetic bellows models 2023-07-14 21:40:03 -04:00
Matt McWilliams fb51716e3a All work 2023-07-14 21:13:04 -04:00
Matt McWilliams bdd74fa90a Save css changes 2023-07-14 21:12:48 -04:00
Matt McWilliams 8631250b9e Ignore all apple hidden files 2023-07-13 13:00:10 -04:00
Matt McWilliams c9f35ffe90 Merge branch 'canon_ble' of ssh://git.sixteenmillimeter.com/16mm/mcopy into canon_ble 2023-07-12 22:25:17 -04:00
Matt McWilliams 18d6e2c7cd WIP on state problem 2023-07-12 22:22:46 -04:00
Matt McWilliams f47ea2d382 Work on rails ends 2023-07-10 23:07:32 -04:00
Matt McWilliams 0cc167b3a6 Incredibly close to #80 and #81. Can get state confirmation at startup. Can send exposure string and get confirmation after. Cannot get state outside of initial confirmation. Something is either locked or failing to wait? 2023-07-10 22:33:16 -04:00
Matthew McWilliams 5133295f38 Save JKMM100 work 2023-07-08 19:44:57 -04:00
Matt McWilliams 621948fbac Work on mcopy_rails concepts 2023-07-05 15:17:56 -04:00
Matt McWilliams 4539c6d897 Methods in place for setting exposure 2023-07-05 15:17:45 -04:00
Matt McWilliams a7db072dc6 Accept exposure targets as string arguments to be parsed 2023-07-05 14:46:43 -04:00
Matt McWilliams 58ce079330 Both components are working properly. 2023-07-04 22:46:37 -04:00
Matt McWilliams dd03583a27 Proof of concept works. Nano can proxy requests to ESP32 via soft serial and then receives confirmation after event. Nano has a cleaner serial interface and will not throw junk into mcopy app serial listener. 2023-07-04 18:45:51 -04:00
Matt McWilliams 3feaea74bf Do not need to declare Serial2. 2023-07-04 18:18:51 -04:00
Matt McWilliams 1d6cbe5c53 Update the serial tests 2023-07-04 17:15:26 -04:00
Matt McWilliams 318f931dbf ESP32 HardSerial note 2023-07-03 22:44:43 -04:00
Matt McWilliams 5400518ea6 Merge remote-tracking branch 'origin/canon_ble' into canon_ble 2023-07-03 22:35:37 -04:00
Matt McWilliams f73a1e3931 nano softserial note 2023-07-03 22:35:29 -04:00
Matthew McWilliams 60d7ab4b5e Add missing lines to debug sketch 2023-07-03 20:34:47 -04:00
Matthew McWilliams 95cde2907a Run the debug script 2023-07-03 20:33:32 -04:00
Matthew McWilliams 35b67f1815 Use the correct identifier on projectors 2023-07-03 20:33:18 -04:00
Matt McWilliams f958789b20 Merge remote-tracking branch 'origin/canon_ble' into canon_ble 2023-07-02 13:56:11 -04:00
Matt McWilliams 4beef04a3f Projector debug idea. 2023-07-02 13:56:03 -04:00
Matthew McWilliams 6d379d284b on site work at MONO 2023-07-01 16:34:07 -04:00
Matt McWilliams 2c21110b97 fix reference to cmdChar 2023-06-28 20:01:53 -04:00
Matt McWilliams 777db577d7 Structure of both sketches is complete, need to test on hardware 2023-06-28 15:06:11 -04:00
Matt McWilliams bf320216cf REmove remaining components from ble 2023-06-28 12:43:24 -04:00
Matt McWilliams b48c498574 Remove unneeded components from both ble sketches 2023-06-28 12:41:54 -04:00
Matt McWilliams 0b71da8e7b Canon BLE two-Arduino rewrite WIP 2023-06-27 23:16:16 -04:00
Matt McWilliams c0d6cbccec Can now detect if state is available on a device 2023-06-17 17:57:30 -04:00
Matt McWilliams 95ede98623 State string should start and end with the character 2023-06-17 13:08:00 -04:00
Matt McWilliams 3881dd4891 Update McopySerial to have a sendStr method, which is distinct from print, which should be used for debug logging. 2023-06-17 11:40:56 -04:00
Matt McWilliams 71e4bea384 Preliminary state support in arduino library. Currently confirms the negative state. Might want to push it until after verify, out of enumerate. 2023-06-16 23:04:16 -04:00
Matt McWilliams 83aa3099c4 Update the settings page with time for projector and camera actions 2023-06-16 22:07:53 -04:00
Matt McWilliams 672db32917 Put in place changes needed to receive a string from an arduino 2023-06-12 22:45:25 -04:00
Matt McWilliams 80a9c23f4d Speed down the motors 2023-05-26 07:09:00 -04:00
Matt McWilliams 49ad3c28a8 Only print projector time to state 2023-05-25 10:45:44 -04:00
Matt McWilliams a29c85628c Add bones of the dual stepper motor, JK compatible projector firmware. 2023-05-25 10:43:45 -04:00
Matt McWilliams 3ec93ab3b1 work 2023-05-16 23:05:13 -04:00
Matt McWilliams 10c29d3af1 Add a set screw to the gate_key 2023-05-15 21:48:09 -04:00
Matt McWilliams 41840b90c8 Update gitsub 2023-05-15 12:36:03 -04:00
Matt McWilliams c89e865d3d Bearing needs slight gap to allow the inner bearing wheel to rotate freely 2023-05-14 21:17:20 -04:00
Matt McWilliams c6ec54bd06 Flip projector panel to print 2023-05-14 21:01:46 -04:00
Matt McWilliams af3b1b8cbb Create first draft of projector panel redesign 2023-05-14 21:00:52 -04:00
Matt McWilliams 86273a9f09 Merge remote-tracking branch 'origin/canon_ble' into canon_ble 2023-05-02 23:58:39 -04:00
Matt McWilliams ba0241a811 Update ESP32 case 2023-05-02 23:58:31 -04:00
Matt McWilliams 1bd73876b4 Add sprocketed roller module 2023-04-28 15:35:54 -04:00
Matt McWilliams cc806cbe52 Initialize and connect only after mcopyserial connects. 2023-04-20 22:50:48 -04:00
Matt McWilliams 8f7a40075a Add connected and identified member booleans to determine when fully connected to mcopy. 2023-04-20 22:37:37 -04:00
Matt McWilliams 64faaa9427 Slight change to outer diameter. 2023-04-19 13:32:06 -04:00
Matt McWilliams d44c67ce80 Update the lens board design 2023-04-19 13:31:47 -04:00
Matt McWilliams 144b408092 Print state in the arri-s firmware 2023-04-17 16:44:04 -04:00
Matt McWilliams d2390dca30 Add a bellows board -- to be attached to bellows and then to boards with magnets. Render all STLs 2023-04-16 23:33:11 -04:00
Matt McWilliams 503a8ec92f Add magnets to bellows board design 2023-04-16 22:53:16 -04:00
Matt McWilliams ca22a3ba4b Rewrite arri_s_firmware to use McopySerial 2023-04-16 16:42:00 -04:00
Matt McWilliams ef54e61494 Use McopySerial in mcopy_arri_s_firmware 2023-04-15 22:44:33 -04:00
Matt McWilliams b1745c786b Invert logic for use with solid state relays rather than standard 2023-04-14 19:48:20 -04:00
Matt McWilliams 83efbc18c7 Fix mcopy_cam_canon_ble 2023-04-13 20:39:24 -04:00
Matthew McWilliams f47396e48c Need confirmation after mcopy_cam_relay 2023-04-12 15:25:41 -04:00
Matt McWilliams 03c27a9226 Relay logic was reversed 2023-04-12 15:15:41 -04:00
Matt McWilliams 08655898d4 Merge remote-tracking branch 'origin/canon_ble' into canon_ble 2023-04-12 14:52:40 -04:00
Matt McWilliams 5d347d23e4 Correctly reference backward LED 2023-04-12 14:52:35 -04:00
Matthew McWilliams a25d93ec55 Correctly delay between frames. 2023-04-12 14:52:05 -04:00
Matthew McWilliams bbf0cbd1c6 Add the button to the relay sketch 2023-04-11 23:43:35 -04:00
Matthew McWilliams 4aceeac1c2 Remove libraries required by TickTwo. This sketch will not use blink in this fashion ATM. 2023-04-11 23:26:12 -04:00
Matt McWilliams 1f5bb85304 Correctly reference LEDs 2023-04-11 22:39:44 -04:00
Matthew McWilliams 087fd3f763 Complete the mcopy relay sketch without variable exposure. 2023-04-11 01:13:44 -04:00
Matthew McWilliams daece3b45a Add the new mcopy_cam_relay script. 2023-04-11 00:38:06 -04:00
Matthew McWilliams 9705505285 Refactor ino.sh to loop through array of scripts to copy McopySerial library to. 2023-04-11 00:37:14 -04:00
Matthew McWilliams 9016062f70 Rename mcopy_cam_canon to mcopy_cam_canon_ble to differentiate 2023-04-11 00:28:27 -04:00
Matthew McWilliams a6de66eb66 Blink LED on startup 2023-04-11 00:24:39 -04:00
Matt McWilliams 6ada6b08ed Add LED features to projector firmware. 2023-04-10 23:28:02 -04:00
Matt McWilliams 710e178ba2 Merge branch 'canon_ble' of ssh://git.sixteenmillimeter.com/16mm/mcopy into canon_ble 2023-04-10 21:12:08 -04:00
Matt McWilliams 9e7990851e Case design work 2023-04-10 21:04:01 -04:00
Matt McWilliams ae34558f18 Add project home and mirrors to Readme 2023-04-07 09:44:51 -04:00
Matt McWilliams c1a51f1ce8 Canon EF bellows adapter 2023-04-01 19:24:29 -04:00
Matt McWilliams 13702a3d5b Add a canon_EF_body_cap script 2023-03-30 20:15:43 -04:00
Matt McWilliams 6b66cfe03f Add bolt voids to canon mount 2023-03-29 22:47:49 -04:00
Matt McWilliams cbc876c57c Case ready for production 2023-03-29 21:58:03 -04:00
Matt McWilliams 7813a8c904 First draft of Rebel case 2023-03-28 19:41:35 -04:00
Matt McWilliams 5f941e91b5 Add conecpt for arduino nano case 2023-03-26 20:19:15 -04:00
Matt McWilliams d262ed418d Add base to socket connector. 2023-03-26 20:19:00 -04:00
Matt McWilliams 2e9db4d667 Connector size is working 2023-03-26 18:53:01 -04:00
Matt McWilliams bd9317dd8f Adjust angles. Make $fn configurable (crashing the GUI on my desktop). 2023-03-26 17:53:26 -04:00
Matt McWilliams 461add1cda Start adding LEDs 2023-03-26 16:06:08 -04:00
Matt McWilliams 1528dec668 Rename bellows adapter 2023-03-24 13:51:29 -04:00
Matt McWilliams fff9d5d410 Export mcopy serial to it's own repo 2023-03-24 13:50:38 -04:00
Matt McWilliams 231c354cb1 Update McopySerial usage in both scripts that use it. 2023-03-21 20:38:45 -04:00
Matt McWilliams 4e0149e752 Fixed issue with baud being stored as const overflowed. Silly mistake.
Also storing command chars as public const variables to shorten code and allow for mc.COMMAND rather than McopySerial::COMMAND. Cleans up example code a lot.
2023-03-21 20:35:00 -04:00
Matt McWilliams 5c6b9191e5 Work in progress: Serial does not work from external library 2023-03-20 19:45:32 -04:00
Matt McWilliams 77a0f7d8a0 Use the correct pins for the projector 2023-03-18 17:36:24 -04:00
Matt McWilliams 9faae6fc36 Create the first state sender. 2023-03-18 17:25:58 -04:00
Matt McWilliams 3689eb7528 Rewrite mcopy_light to use McopySerial 2023-03-18 17:13:41 -04:00
Matt McWilliams 210dc85558 Add getString and print methods 2023-03-18 17:04:06 -04:00
Matt McWilliams 174b900cd8 Update commands 2023-03-18 17:00:13 -04:00
Matt McWilliams fbe954280f Socket connector work 2023-03-18 17:00:02 -04:00
Matt McWilliams 142c990a0e Refactored GUI into TypeScript and class-based format 2023-03-18 16:59:26 -04:00
Matt McWilliams 790ea3d551 Add guides for collar flanges 2023-03-15 22:11:48 -04:00
Matt McWilliams c6b8592490 Enlarge case and add bolt 2023-03-15 21:35:35 -04:00
Matt McWilliams f67e011d5e Canon EOS M50 mount design 2023-03-15 21:35:23 -04:00
Matt McWilliams a4bc54482d Work on canon mount 2023-03-15 19:22:18 -04:00
Matt McWilliams be50eb6fcf Work on ESP32 case and CPC socket 2023-03-14 21:45:18 -04:00
Matt McWilliams a7d784583a Case for an ESP32 dev board (Inland, Microcenter) 2023-03-13 17:46:38 -04:00
Matt McWilliams 7af1f739e4 Canon EF M bellows mount 2023-03-13 17:46:21 -04:00
Matt McWilliams 3e247703a8 More CPC connector work 2023-03-13 17:45:50 -04:00
Matt McWilliams c7e338ebff projector electronics improvements, move arduino mount, increase size, adjust resistor mount 2023-03-12 21:28:29 -04:00
Matt McWilliams cc2af435d5 First pass at esp32 case 2023-03-12 17:55:09 -04:00
Matt McWilliams 87695b173d First pass at projector controller design and refactor of sequencer case. 2023-03-12 16:36:16 -04:00
Matt McWilliams 722ff9c05e Remove unneeded comments 2023-03-10 21:19:30 -05:00
Matt McWilliams 51114df576 First draft of the JKMM100 firmware using McopySerial. Boy does this make my life easier.
Need to find a better way than copying it into all of these different projects.
Oh well.
2023-03-09 21:54:54 -05:00
Matt McWilliams 9126bc82c0 Confirm the camera command (this should happen after it expects frame is taken). 2023-03-09 21:51:49 -05:00
Matt McWilliams e09fe7d42f McopySerial now has a confirm() method which marks the end of a command. This is a wrapper around Serial.println() 2023-03-09 21:51:29 -05:00
Matt McWilliams 234e69c7a2 Canon BLE firmware now uses the McopySerial script for it's USB communication. 2023-03-09 21:30:59 -05:00
Matt McWilliams d7017af245 Move connect and identify methods to internal ones. 2023-03-09 21:26:31 -05:00
Matt McWilliams f49c70ead6 Define all command chars as static constants. Provide an identity when initializing and allow for setting with another method. 2023-03-09 21:18:10 -05:00
Matt McWilliams 9a89dbe6a5 Automatically toggle debug state internally 2023-03-09 21:08:36 -05:00
Matt McWilliams 844bb286a5 Build the skeleton of McopySerial. Contains all command chars as flags. Is now re-built with latest command flags automatically when syncing to all projects. Compiles. Will implement more in canon firmware. 2023-03-09 21:01:20 -05:00
Matt McWilliams 4eceecf139 Add ino script 2023-03-08 22:37:40 -05:00
Matt McWilliams 95e2e997e5 Move mcopy serial script. Add work (isn't working). 2023-03-08 21:28:09 -05:00
Matt McWilliams 346c303edb First pass at connector plug 2023-03-08 16:01:02 -05:00
Matt McWilliams 908fe52ad8 Simplify projector_controller.scad 2023-03-05 17:14:01 -05:00
Matt McWilliams 3fd1e47b7b Rename sleeve to collar 2023-03-05 17:13:42 -05:00
Matt McWilliams d41f082839 Update light sketch, add Pixie lib 2023-03-05 17:13:29 -05:00
Matt McWilliams 2047ce4f76 cpc connector work 2023-03-05 00:28:39 -05:00
Matt McWilliams 3ef56cab21 Compile all Arri-S parts 2023-03-04 20:20:16 -05:00
Matt McWilliams 6b77b98aad Add more files to scad.sh 2023-03-04 20:00:01 -05:00
Matt McWilliams 211101cd6b Add common SCAD lib. Add a script that compiles all scad files to stl (make is getting excessive). Canonicalize STL files after they're compiled. 2023-03-04 19:44:20 -05:00
Matt McWilliams e27cae353f Work on McopySerial library. Still having trouble with compiling. 2023-03-04 19:25:50 -05:00
Matt McWilliams b12a08e47a Rename lib to match style of others 2023-03-04 19:04:55 -05:00
Matt McWilliams 9b298ac676 Sync actual files 2023-03-04 19:01:35 -05:00
Matt McWilliams 52acb97e08 Try without symlinks 2023-03-04 18:59:47 -05:00
Matt McWilliams 78450e9e6a Add mcopy_serial library 2023-03-04 18:52:51 -05:00
Matt McWilliams dc746fe6f4 canon work 2023-03-03 10:13:40 -05:00
Matt McWilliams 0e3bc563a7 Update blink functionality. Probably will not work during start? 2023-03-01 13:51:54 -05:00
Matt McWilliams d0ef5d410d Ignore all .svd files 2023-03-01 13:38:48 -05:00
Matt McWilliams d9aa7dc698 Ignore build artifacts 2023-03-01 13:38:27 -05:00
Matt McWilliams 70ab8cb527 Improve timing. Sequence takes into account serialDelay within each command and sequenceDelay has no bearing. Was adding 120ms of error to every step 2023-03-01 13:37:22 -05:00
Matt McWilliams 512f6c86ad Resolves #73. Delay is exported in .ts file so it is non-ambient 2023-03-01 13:35:45 -05:00
Matt McWilliams d23eb290d9 Merge branch 'main' into canon_ble 2023-02-28 15:59:11 -05:00
Matt McWilliams 648bca5b2e Merge pull request 'Merge the estimates branch' (#79) from estimates into main
Reviewed-on: #79
2023-02-28 15:58:26 -05:00
Matt McWilliams 5db5d477e4 Timing is now updated via rolling average on all projector and camera actions. This data is reset when profile is changed. This data is stored in the settings.json and loaded on start so estimates will improve the more it is used. 2023-02-28 15:55:02 -05:00
Matt McWilliams 7741134917 Create the Timing class 2023-02-28 14:30:17 -05:00
Matt McWilliams 3c19cd35cf Resolves #4 (4 years ago!). Adds delay (stops scripts for X seconds), alert (displays an alert that stops script execution) and pause (displays a pre-populated alert). 2023-02-28 12:49:11 -05:00
Matt McWilliams 85832d18f6 Placeholder for notes 2023-02-27 23:16:44 -05:00
Matt McWilliams 5f0da91659 Canon BLE work 2023-02-26 22:19:07 -05:00
Matt McWilliams e1bf69e622 Add work on mcopy_cam_canon. This includes teh CanonBLERemote library, ArduinoNvs (dependency of CanonBLERemote) and TickTwo, potentially to manage a blinking UI component. Not working. Finish the firmware feature in this branch. 2023-02-25 22:24:29 -05:00
Matt McWilliams d9290f7262 Add branch_name.sh to print out only the branch name 2023-02-25 22:22:42 -05:00
Matt McWilliams 81b6846261 Only update patch on main 2023-02-25 22:22:18 -05:00
Matt McWilliams a57519adce Merge pull request 'Merge all work on server with filmout features' (#77) from server into main
Reviewed-on: #77
2023-02-25 21:16:28 -05:00
Matt McWilliams 02639466ee By doing a check for active clients during the sequencer start and stop actions, the local display is no longer used. Resolves first part of #20. 2023-02-25 17:00:11 -05:00
Matt McWilliams 6e2795d380 Remove ACK messages for ping, rely on 2023-02-25 16:33:55 -05:00
Matt McWilliams 8e35596088 Fixed the iOS issue. Also allow for fullscreen on all browsers (with no sleep). Can preview properly but normal mode does not work 2023-02-25 16:32:08 -05:00
Matt McWilliams 0162d012c5 Server can now display images and will completely preempt local display when done 2023-02-25 13:22:20 -05:00
Matt McWilliams 47fb673b78 Combined script and html into single request (problems with iOS safari).
Can get script loaded but still cannot connect to websocket server without SSL.

ALSO: Now can pre-empt opening new display if an active client is connected to server.
Otherwise will open a local link.
2023-02-25 13:11:40 -05:00
Matt McWilliams f296488bc2 Further progress on #20. TODO: Image display logic on the server side. Need to add image to proxy list and give it a properly-extensioned name and cmdAll.
ALSO: Server is not working on iOS.
2023-02-25 12:40:35 -05:00
Matt McWilliams f5392aea9f Resolves #74 2023-02-25 12:33:18 -05:00
Matt McWilliams 24b1301f9f Adding contextIsolation: false to the display module fixes the initial issue in #74, cannot use "require" but the escape button does not work due to "Cannot read properties of undefined (reading 'getCurrentWindow')" 2023-02-25 12:16:47 -05:00
Matt McWilliams 1290a8f324 Major progress on #20. Promised-based websocket command structure is completed. All functionality needs to be placed into individual classes and any new functions get added to the server.
Will create entire thin client using this method.
2023-02-25 11:59:56 -05:00
Matt McWilliams e64277e438 More work on #20. Fix typos in display code. Should re-work script into transpiled ts file. 2023-02-25 02:08:56 -05:00
Matt McWilliams c9bcb74a9f Progress on #20. Can start up a server and serve client.js 2023-02-25 02:08:05 -05:00
Matt McWilliams 42db1f81b8 Server work 2023-02-25 00:24:07 -05:00
Matt McWilliams 7222952eba Update version nubmers 2023-02-19 19:43:12 -05:00
Matt McWilliams 744f10c948 Display version in app 2023-02-19 11:36:06 -05:00
Matt McWilliams b50704a6a8 Fix minor layout issue on sequence page (on mac at least). 2023-02-19 01:28:18 -05:00
Matt McWilliams c152806511 Now it works. 2023-02-19 01:27:19 -05:00
Matt McWilliams 4d9454daf2 Patch script now working 2023-02-19 01:22:44 -05:00
Matt McWilliams e754c65602 Increment patch without npm install 2023-02-19 01:20:51 -05:00
Matt McWilliams b672921c84 Increment patch number on commit 2023-02-19 01:18:03 -05:00
Matt McWilliams 6116ada2fd Getting a new error when compiling delay library. Attempt to stop autogenerating d.ts files.
src/delay/index.ts:11:10 - error TS2384: Overload signatures must all be ambient or non-ambient.
2023-02-19 00:55:17 -05:00
Matt McWilliams d7baa4d17b Merge branch 'capper'
:w
ls
2023-02-19 00:29:40 -05:00
Matt McWilliams ebc5504998 Add commands for takeup 2023-02-19 00:29:07 -05:00
Matt McWilliams c5e66a6f40 Merge pull request 'Merge in 9 months of work on capper branch' (#71) from capper into main
Reviewed-on: #71
2023-02-19 00:28:45 -05:00
Matt McWilliams cff558ef9a Add 15mm to mount void for camera bolt 2023-02-12 14:14:03 -05:00
Matt McWilliams 325837d93e Adjustment to allow space on the right side 2023-02-12 14:10:44 -05:00
Matt McWilliams 135540b261 Remove some material for the rails 2023-02-03 20:08:18 -05:00
Matt McWilliams 49464cd25a Finished the design of the lens assembly base z attachment 2023-02-02 19:48:30 -05:00
Matt McWilliams d0fe54b429 Add m5 nut to the common lib 2023-02-02 19:48:08 -05:00
Matt McWilliams 2dce6f4b08 Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2023-01-31 11:52:13 -05:00
Matt McWilliams 99794d04c2 jk assembly and arri-s wip 2023-01-31 11:52:10 -05:00
Matt McWilliams cc06655cd6 Update debug 2023-01-23 00:28:26 -05:00
Matt McWilliams ab6f517d27 Rails work 2023-01-17 12:04:03 -05:00
Matt McWilliams 682167db48 Add new commands for takeup forward and takeup backward 2023-01-15 10:09:55 -05:00
Matt McWilliams f127dc1128 Merge remote-tracking branch 'origin/capper' into capper 2023-01-14 15:26:07 -05:00
Matt McWilliams 0b816ae8e1 Adjust the position of the Z axis, move the linear bearing up and down to prevent binding on motion 2023-01-14 15:25:53 -05:00
Matt McWilliams c600fea4e1 Start rails concept 2023-01-12 19:26:05 -05:00
Matt McWilliams 92067bdbef Add top part to assembly 2023-01-11 19:17:15 -05:00
Matt McWilliams c181e003a3 First draft of base 2023-01-07 18:43:59 -05:00
Matt McWilliams 597137670d Merge base work with knob changes 2023-01-06 10:31:25 -05:00
Matt McWilliams 3036aebbc4 Knob and collar work 2023-01-06 09:18:03 -05:00
Matt McWilliams cbe6477af2 Improvements to bearing and Tnut size 2023-01-05 17:35:25 -05:00
Matthew McWilliams c2546d2bc5 Add m3 nuts and bolts to threaded z movement 2023-01-05 14:40:25 -05:00
Matt McWilliams 46be1bfd3b Assembly work. Adjusted design to simplify placement of 2 linear bearings 2023-01-04 23:11:48 -05:00
Matt McWilliams 1029885047 Update threaded Z, still needs m3 bolts 2023-01-04 18:26:22 -05:00
Matt McWilliams 164bde8cce All arri s mount and jk lens assembly work. need to do some branch cleanup on this project and tackle capper issues for merge of this branch. 2023-01-03 21:16:19 -05:00
Matt McWilliams 41504caac9 Increase the bolt size on the bellows board 2023-01-02 17:11:44 -05:00
Matt McWilliams 9b34b4e026 Adjust the height of the mount (-14.5mm) and make bolt voids larger 2023-01-02 14:33:16 -05:00
Matt McWilliams 95612c1d18 Add m3 nuts 2023-01-02 14:30:54 -05:00
Matt McWilliams 0829ec9081 Use a variable 2023-01-02 13:53:41 -05:00
Matt McWilliams ef0d246901 Increase the inner diameter of the bellows board to allow the threads to pass through cleanly and be held in place by the screw 2023-01-02 13:53:30 -05:00
Matt McWilliams 622a8a7c42 Add first concept bellows board 2023-01-01 11:43:30 -05:00
Matt McWilliams 925659ba4b Create an Arri S mount for the JK rails 2023-01-01 11:43:21 -05:00
Matt McWilliams 20c9287ac2 Work on concept JK lens assembly 2022-12-24 17:36:25 -05:00
Matt McWilliams 8aaa2b8940 Add a concept JK lens assembly 2022-12-24 01:55:11 -05:00
Matt McWilliams 30bd35e21d Add an M4 nut to the common OpenSCAD lib 2022-12-24 01:54:57 -05:00
Matthew McWilliams 0c2e39f0b2 Arri bellows work 2022-12-23 23:01:37 -05:00
Matt McWilliams cbd7001228 Save work on the JK99 shield. 2022-11-13 17:35:18 -05:00
Matt McWilliams dec96ec9be Use variable in stepper declaration 2022-11-11 15:47:58 -05:00
Matt McWilliams 3942cd05be Declare stepsPerRevolution so change is explicit when that happens 2022-11-11 15:47:43 -05:00
Matt McWilliams ee1e9c9feb Stepper firmware is working. Needed extra tape around coupling connector to add friction to connection and now it keeps. 2022-11-04 19:37:11 -04:00
Matt McWilliams fcb77232ec Create the driveCoupling module for the stepper motor design 2022-10-30 12:14:25 -04:00
Matt McWilliams 1fcbec7466 Work on stepper motor design and software. Motor still moves more slowly than it should but will investigate multiple factors leading to this result 2022-10-28 19:46:02 -04:00
Matt McWilliams 98f2c7a24a Pausing work on arri_s_DC firmware because hardware is less than ideal. Too much play in the motor position to trust right now. Steppers better approach. 2022-10-28 11:28:30 -04:00
Matt McWilliams 787e6ed06e Add a concept arri_s camera controller firmware. Using class-based approach as an experiment in Arduino code structure. 2022-10-28 07:50:30 -04:00
Matt McWilliams bb5b7c7897 Add divot to the drive coupling 2022-10-28 07:44:19 -04:00
Matt McWilliams 42b3aa767d Allow for even more space for microswritch 2022-10-28 01:32:58 -04:00
Matt McWilliams b20a6084e6 Allow for more space for the microswitch 2022-10-27 18:10:13 -04:00
Matthew McWilliams d9a8576701 Adjust size of drive coupling for the DC connector 2022-10-21 16:05:56 -04:00
Matthew McWilliams 69273d2a1c Increase scale of motor shaft void by 5% 2022-10-21 15:26:17 -04:00
Matthew McWilliams 755ea757f7 Add set screw for bearing and counter sink bolt caps for other cap m3s 2022-10-21 15:24:21 -04:00
Matt McWilliams 81fc54af8d DC motor design has all components designed, need to print, test and adjust. 2022-10-19 06:38:56 -04:00
Matt McWilliams 4281ca4390 Work on Arri-S DC motor 2022-10-16 19:03:02 -04:00
Matt McWilliams 3419172535 Arri-S work 2022-10-15 00:13:05 -04:00
Matt McWilliams 206c266b08 Added Arri-S motor and cap measurements as taken 10/8/2022 2022-10-09 11:22:12 -04:00
Matthew McWilliams 5026cf869f Arri-S work 2022-10-07 19:47:56 -04:00
Matthew McWilliams d5ecd9e057 Improve capper documentation 2022-09-16 09:45:19 -04:00
Matthew McWilliams 72b5077356 Restructure includes and type definition files so that mscript runs 2022-08-07 22:18:58 -04:00
Matthew McWilliams 6601c030f7 Refactor mscript GUI code into Typescript 2022-08-07 22:10:53 -04:00
Matthew McWilliams 3ec1373f08 Caught a possible ancient bug in the loop logic for calculating state of camera and projector backwards movements. 2022-08-07 17:23:06 -04:00
Matt McWilliams b29478cb58 Increment build patch version 2022-08-04 10:57:36 -04:00
Matt McWilliams fe61e63e76 Add secondary projector and camera commands to the mscript module 2022-08-04 10:52:00 -04:00
Matt McWilliams ee0ab663d7 Complete the alert feature. Have not created pause, but this could be done using the same alert object to prevent code duplication. 2022-08-03 09:02:47 -04:00
Matt McWilliams 1964d6002d Add mono logo as png, but might use svg instead. Render crashed PC. 2022-07-22 21:56:43 -04:00
Matt McWilliams f55b72044c Mcopy firmware with optional capper feature 2022-07-17 11:05:20 -04:00
Matt McWilliams 3f759f5678 Add the ability to detect a single capper device 2022-07-17 09:57:52 -04:00
Matt McWilliams 6582154ec6 Fix debug script and component 2022-07-17 09:56:03 -04:00
Matt McWilliams 9d0545aa4f All capper features in app, can shoot blank frames, can turn on capper independently and can schedule blank frames in the sequencer. Some cleanup may be needed but there are no noticeable regressions in the app. TODO: Finish all arduino scripts. 2022-07-15 18:11:26 -04:00
Matt McWilliams ea055d6e56 Capper case candidate 2022-07-13 23:04:00 -04:00
Matthew McWilliams bc48765b35 Start work on base 2022-07-13 18:16:43 -04:00
Matthew McWilliams 70c2c695f0 All capper work. Need to wrap all actions in the 'b' command and push functionality to a lower level to prevent unneeded complexity. 2022-07-13 15:21:26 -04:00
Matthew McWilliams 8ec5816364 Adjust settings page to support Processing input 2022-07-13 10:15:47 -04:00
Matthew McWilliams c33c6e24f6 Work on motor rod 2022-07-13 09:01:25 -04:00
Matt McWilliams b0ca15bd8d Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-07-13 08:28:58 -04:00
Matt McWilliams 76799bd66d Capper work 2022-07-13 08:28:18 -04:00
Matthew McWilliams 18dbb72a54 Minor updates to comments 2022-07-06 14:42:53 -04:00
Matthew McWilliams c0ec81c0f9 Add Servo debug script 2022-07-06 14:42:16 -04:00
Matt McWilliams c3661d6ff1 Remove opto endstop logic, ready for hardware testing. 2022-06-28 08:58:31 -04:00
Matt McWilliams c0f056cd8d Re-render all STLs for capper, removing the opto endstop component (for now) 2022-06-28 08:38:11 -04:00
Matt McWilliams 2924efe39f Reduce the size of the void for the screw in the cap. 2022-06-28 08:34:29 -04:00
Matt McWilliams e275539fb0 Remove endstop completely and start rounding surfaces. 2022-06-22 07:45:01 -04:00
Matt McWilliams 4c13c54815 Updates to endstop mount design. Had incorrectly positioned voids for SMD chips on the endstop 2022-06-20 13:00:40 -04:00
Matt McWilliams 62a66f5f6d More mount work and start of endstop logic. Rebuilding the B&H projector unity. 2022-06-17 23:39:19 -04:00
Matt McWilliams 3a435933e3 Work on the opto endstop mount. This needs to be re-oriented before next print. 2022-06-16 00:29:31 -04:00
Matt McWilliams 78f7ac0e68 Mount work 2022-06-13 22:46:23 -04:00
Matt McWilliams 28dc19fc32 Work on endstop functionality 2022-06-13 22:46:13 -04:00
Matt McWilliams 585c47d6c7 Allow capper identifier in list of acceptable responses. 2022-06-13 08:08:42 -04:00
Matt McWilliams 04a0330327 All work on first draft of capper hardware 2022-06-12 22:26:03 -04:00
Matt McWilliams dae4e65aee Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-06-12 13:37:52 -04:00
Matt McWilliams 129647b863 App work 2022-06-12 13:37:00 -04:00
Matt McWilliams 2f9201716a All capper work. Debug firmware for testing. STL of cap as printed. 2022-06-12 13:14:43 -04:00
Matt McWilliams f9d716552b Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-06-11 16:06:25 -04:00
Matt McWilliams 818c8453ee Capper OpenSCAD work 2022-06-11 16:03:08 -04:00
Matthew McWilliams f7a3c52260 Silly typo: did not invoke Servo_init() and so servo was not initalizing 2022-06-10 13:19:38 -04:00
Matt McWilliams 9d3bf24627 Hardware ideas for capper mount and flag. Need to model servo and add places for endstops 2022-06-07 07:55:47 -04:00
Matt McWilliams c77201ef4e Add new commands and identifiers for the capper, start moving into capital characters 2022-06-07 07:55:26 -04:00
Matt McWilliams f585aa2a5a Upgrade electron 11 -> 19 (huge jump). Install new remote module to preserve legacy communication protocol. 2022-06-04 11:11:23 -04:00
Matt McWilliams 96e0ce6050 Merge branch 'capper' of git.sixteenmillimeter.com:16mm/mcopy into capper 2022-05-31 17:44:56 -04:00
Matt McWilliams 17d4ff459f Notes about 4pin_connectors 2022-05-31 17:43:03 -04:00
Matt McWilliams c15c376a2f Start work on capper branch 2022-05-30 18:50:18 -04:00
Matt McWilliams 22bed4632b Update the notarization process for installing mcopy 2022-04-30 18:51:33 -04:00
Matt McWilliams 8b5faaa1a4 Update global package.lock 2022-04-30 16:03:33 -04:00
Matt McWilliams 81d94fd727 update package lock 2022-04-30 16:03:03 -04:00
Matt McWilliams bbfe6fc657 Add option to use Processing with a server as a capture method triggered by the camera.
Enter a url into the Settings panel in the Processing URL input box and select the radio button.
2022-04-30 15:58:17 -04:00
Matt McWilliams 467a5c06d6 Update the projector knob design 2022-04-30 15:52:04 -04:00
Matt McWilliams 9dce9fb1f2 Add an alternate script for notarizing builds 2021-05-01 12:20:19 -04:00
Matt McWilliams e1c8ba1320 Build_linux.sh already tags the installer with the correct version number 2021-04-13 18:39:22 -04:00
mmcwilliams 4ef318c55e Rename installer after build process. 2021-04-13 14:45:15 -04:00
mmcwilliams 7f7513809a Established an app signing process for macs using electron-packager. The process takes an enormous amount of time but has so far been running without throwing an exception and the signature is confirmed by codesign. 2021-04-13 14:17:12 -04:00
Matt McWilliams b3bb07454f Add a lamp housing knob 2021-04-05 10:40:50 -04:00
Matt McWilliams faad084b2b Hide "blank" buttons because they do not have a use case in the current app. 2021-04-01 22:21:27 -04:00
Matt McWilliams 3e528c23a5 Give the filmout position input element a fixed width value 2021-04-01 19:45:08 -04:00
Matt McWilliams 6fed941441 Filmout UI was breaking on linux (all of a sudden) 2021-04-01 19:40:29 -04:00
Matt McWilliams 6fee5a803c connector case box 2021-03-19 21:32:53 -04:00
Matt McWilliams 2861bc52fd intval2 connector firmware 2021-03-19 14:09:46 -04:00
Matt McWilliams 8c14a06b96 Removed naked console.log statements that were used to debug a serial issue. If needed they can be re-added to the actual log library. 2021-03-19 12:10:07 -04:00
Matt McWilliams 3e0ac3f0d0 Added return types to Filmout library and added return types to comments where needed. 2021-03-19 12:09:03 -04:00
Matt McWilliams 394fbe2323 Update cfg.json. Not sure why this lags?? 2021-03-18 11:55:18 -04:00
Matt McWilliams 11267796ba Update links to latest release 2021-03-18 11:35:55 -04:00
Matt McWilliams aac5e5d488 Increment patch to 1.6.9 2021-03-18 11:28:46 -04:00
Matt McWilliams 8a6bc0b4f5 Fixed video export, still sequence selection 2021-03-18 11:27:53 -04:00
Matt McWilliams a2af605d37 Filmout needs to receive the whole state, not just the frame. Still broken. 2021-03-18 10:00:49 -04:00
Matt McWilliams 32f70be614 Fixes #50 - Support image sequences in filmout feature 2021-02-24 11:58:19 -05:00
Matt McWilliams 31c701734a Corrected a UI issue with selecting directories of non-supported images. Works on macOS now with videos, images and image sequences. Testing on linux again before resolving. 2021-02-24 11:50:15 -05:00
Matt McWilliams fb7b1e2fb6 Added an edge-case helper for choosing files/directories in linux. This finishes the requirement for issue #50 on linux, but will test changes on macOS before marking the issue resolved. 2021-02-24 10:05:45 -05:00
Matt McWilliams 5061a511ab Corrected an issue with the monitor selection UI where the text is cut off. 2021-02-24 00:38:11 -05:00
Matt McWilliams c0121bcfe7 Have seemingly added the ability to use image sequences with the filmout feature with a few caveats. File selection is working on mac but was not on Linux. Also using this method only jpeg and png sequences can be used. This is not unacceptable, but the UI will have to be made more explicit about this limitation. I would like to support TIFF files but even now with single images they are rendered to PNG using ffmpeg. 2021-02-24 00:22:08 -05:00
Matt McWilliams 66639e951b Allow for the selection of a video file, image or directory containing images to be selected in the filmout UI. 2021-02-23 19:54:03 -05:00
Matt McWilliams 53d147b9bc Add lstat and "directory" property onto the filmout.state object. 2021-02-23 19:53:22 -05:00
Matt McWilliams ad1ac51fc8 Need to enableRemote in the electron browser window that gets created by filmout. 2021-02-23 16:16:17 -05:00
Matt McWilliams 88a6e9f563 Update links to older builds 2021-02-22 13:48:19 -05:00
Matt McWilliams 7dc4d153be Merge remote-tracking branch 'origin/master' 2021-02-22 13:47:05 -05:00
Matt McWilliams dcc91501ee Update readme with links to latest release (1.6.7) 2021-02-22 13:46:58 -05:00
450 changed files with 3397398 additions and 14922 deletions

12
.gitignore vendored
View File

@ -3,4 +3,14 @@
*.Parent
node_modules
dist
dist
*.svd
*debug_custom.json
*debug.cfg
notes/mphd
./lib
./debug

17
.gitmodules vendored Normal file
View File

@ -0,0 +1,17 @@
[submodule "scad/common"]
path = scad/common
url = https://git.sixteenmillimeter.com/modules/common.git
ignore = dirty
[submodule "scad/takeup"]
path = scad/takeup
url = https://git.sixteenmillimeter.com/modules/takeup.git
ignore = dirty
[submodule "scad/sprocketed_roller"]
path = scad/sprocketed_roller
url = https://git.sixteenmillimeter.com/modules/sprocketed_roller.git
ignore = dirty
[submodule "scad/MCAD"]
path = scad/MCAD
url = https://github.com/openscad/MCAD.git
branch = master
ignore = dirty

178
Readme.md
View File

@ -1,85 +1,93 @@
# mcopy
An open platform for controlling small-gauge film optical printers (16mm, Super8, 8mm).
-------
1. <a href="#intro">Introduction</a>
2. <a href="#downloads">Downloads</a>
1. <a href="#usage">Usage</a>
2. <a href="#software">Software</a>
3. <a href="#firmware">Firmware</a>
3. <a href="#hardware">Hardware</a>
4. <a href="#why">Why?</a>
-------
## Introduction <a name="intro"></a>
The `mcopy` project is comprised of software and hardware for optical printers, built with re-purposed broken projectors.
#### Components
* Sequencer desktop app
* Scripting language, called `mscript`, for orchestrating complex sequences
* Arduino firmware for projectors, cameras, lights and existing printers
* 3D models of parts used for modifying projectors and printers
* Schematics for simple Arduino-based electronics
* Filmout feature for digitally transferring video and images to analog film
* Interoperability with the [intval3](https://github.com/sixteenmillimeter/intval3) intervalometer
## Downloads <a name="downloads"></a>
### Latest Installers
* [1.6.2](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.2) for macOS, Linux (.deb) and Windows (.msi)
### Older Versions
* [1.6.1](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.1) for macOS
* [1.5.2](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.5.2) for macOS
* [1.4.9](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.4.9) for macOS and Linux (.deb)
* [1.2.0](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.2.0) for macOS and Linux (.deb)
* [1.0.3](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.0.3) for macOS and Linux (.deb)
For Windows, you can [install from source](https://github.com/sixteenmillimeter/mcopy/tree/master/app#mcopy-desktop-app) for now.
## Usage <a name="usage"></a>
The software requires your hardware to be in place before the mcopy control app is useful.
![mcopy app](docs/mcopy.png?raw=true "mcopy app")
## Software <a name="software"></a>
The mcopy desktop app is an Electron-based project which can be built for Linux, Windows and macOS.
Pre-built packages will be made available for macOS, initially, with the other two target platforms to follow.
To build the desktop app from source, see the [installation and running instructions](https://github.com/sixteenmillimeter/mcopy/tree/master/app#mcopy-desktop-app).
The desktop software also interoperates with two related projects; the Bluetooth + Wifi capable, Raspberry Pi-based [INTVAL3](https://github.com/sixteenmillimeter/intval3) and the Arduino-based [intval2](https://github.com/sixteenmillimeter/intval2).
## Firmware <a name="firmware"></a>
This project contains Arduino formware for controlling:
* a projector
* a camera (see [intval2](https://github.com/sixteenmillimeter/intval2) for more info)
* a light
* a projector + a camera
* a projector + a light
* a camera + a light
* a camera + a projector + a light
Using a simple serial interface, this modular platform can be used to control DIY components, modified existing optical printers or a mixture of components.
The desktop app can connect to multiple serial devices, so your mcopy optical printer can be built from various designs that suit your hardware tastes/needs/available parts.
## Hardware <a name="hardware"></a>
All non-electronic hardware for this project is available as plaintext OpenSCAD files and 3D print-able .STL files.
The hardware component of this project is aimed at modifying broken Bell & Howell projectors into USB serial-controlled projectors to be used in optical printing.
As a secondary capability, this desktop software and firmware package can be used to replace the sequencers for early-model JK optical printers, with some modification.
## Why? <a name="why"></a>
I'm interested in expanding the viability and access of the 16mm film format and to repurpose thre rising tide of discarded film technology.
# mcopy
An open platform for controlling small-gauge film optical printers (16mm, Super8, 8mm).
## [Project Home - git.sixteenmillimeter.com/16mm/mcopy](https://git.sixteenmillimeter.com/16mm/mcopy)
* Github Mirror - [github.com/sixteenmillimeter/mcopy](https://github.com/sixteenmillimeter/mcopy)
* Gitlab Mirror - [gitlab.com/16mm/mcopy](https://gitlab.com/16mm/mcopy)
-------
1. <a href="#intro">Introduction</a>
2. <a href="#downloads">Downloads</a>
1. <a href="#usage">Usage</a>
2. <a href="#software">Software</a>
3. <a href="#firmware">Firmware</a>
3. <a href="#hardware">Hardware</a>
4. <a href="#why">Why?</a>
-------
## Introduction <a name="intro"></a>
The `mcopy` project is comprised of software and hardware for optical printers, built with re-purposed broken projectors.
#### Components
* Sequencer desktop app
* Scripting language, called `mscript`, for orchestrating complex sequences
* Arduino firmware for projectors, cameras, lights and existing printers
* 3D models of parts used for modifying projectors and printers
* Schematics for simple Arduino-based electronics
* Filmout feature for digitally transferring video and images to analog film
* Interoperability with the [intval3](https://github.com/sixteenmillimeter/intval3) intervalometer
## Downloads <a name="downloads"></a>
### Latest Installers
* [1.6.9](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.9) for macOS, Linux (.deb) and Windows (.msi)
### Older Versions
* [1.6.7](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.7) for macOS and Linux (.deb)
* [1.6.4](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.4) for macOS, Linux (.deb) and Windows (.msi)
* [1.6.2](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.2) for macOS
* [1.6.1](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.6.1) for macOS
* [1.5.2](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.5.2) for macOS
* [1.4.9](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.4.9) for macOS and Linux (.deb)
* [1.2.0](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.2.0) for macOS and Linux (.deb)
* [1.0.3](https://github.com/sixteenmillimeter/mcopy/releases/tag/1.0.3) for macOS and Linux (.deb)
For Windows, you can [install from source](https://github.com/sixteenmillimeter/mcopy/tree/master/app#mcopy-desktop-app) for now.
## Usage <a name="usage"></a>
The software requires your hardware to be in place before the mcopy control app is useful.
![mcopy app](docs/mcopy.png?raw=true "mcopy app")
## Software <a name="software"></a>
The mcopy desktop app is an Electron-based project which can be built for Linux, Windows and macOS.
Pre-built packages will be made available for macOS, initially, with the other two target platforms to follow.
To build the desktop app from source, see the [installation and running instructions](https://github.com/sixteenmillimeter/mcopy/tree/master/app#mcopy-desktop-app).
The desktop software also interoperates with two related projects; the Bluetooth + Wifi capable, Raspberry Pi-based [INTVAL3](https://github.com/sixteenmillimeter/intval3) and the Arduino-based [intval2](https://github.com/sixteenmillimeter/intval2).
## Firmware <a name="firmware"></a>
This project contains Arduino formware for controlling:
* a projector
* a camera (see [intval2](https://github.com/sixteenmillimeter/intval2) for more info)
* a light
* a projector + a camera
* a projector + a light
* a camera + a light
* a camera + a projector + a light
Using a simple serial interface, this modular platform can be used to control DIY components, modified existing optical printers or a mixture of components.
The desktop app can connect to multiple serial devices, so your mcopy optical printer can be built from various designs that suit your hardware tastes/needs/available parts.
## Hardware <a name="hardware"></a>
All non-electronic hardware for this project is available as plaintext OpenSCAD files and 3D print-able .STL files.
The hardware component of this project is aimed at modifying broken Bell & Howell projectors into USB serial-controlled projectors to be used in optical printing.
As a secondary capability, this desktop software and firmware package can be used to replace the sequencers for early-model JK optical printers, with some modification.
## Why? <a name="why"></a>
I'm interested in expanding the viability and access of the 16mm film format and to repurpose thre rising tide of discarded film technology.

5
app/.gitignore vendored
View File

@ -1,3 +1,6 @@
node_modules/*
logs/*
data/transfer*.json
data/transfer*.json
.appleId*
.applePwd*
.appleIdentity*

View File

@ -194,8 +194,8 @@ button:focus {
width: 66px;
height: 66px;
position: absolute;
top: 7px;
left: 7px;
top: 14px / 2;
left: 14px / 2;
}
.dial-wrapper input {
margin-top: 94px;
@ -210,10 +210,10 @@ button:focus {
top: 0;
bottom: 0;
overflow: hidden;
width: 40px;
width: 80px / 2;
}
.dial-container.dial-container1 {
left: 40px;
left: 80px / 2;
}
.dial-container.dial-container1 .dial-wedge {
transform: rotateZ(0deg);
@ -227,16 +227,16 @@ button:focus {
.dial-container.dial-container2 .dial-wedge {
transform: rotateZ(0deg);
border-radius: 80px 0 0 80px;
transform-origin: 40px 40px;
transform-origin: 80px/2 80px/2;
}
.dial-wedge {
height: 80px;
width: 40px;
width: 80px / 2;
}
.dial-marker {
border-radius: 50%;
height: 7px;
width: 7px;
height: 14px / 2;
width: 14px / 2;
position: absolute;
top: 0;
left: calc(50% - (14px * 2));
@ -367,6 +367,7 @@ button:focus {
float: right;
width: 90px;
margin-right: 60px;
height: 32px;
}
#seq_stats {
width: 40%;
@ -484,6 +485,9 @@ button:focus {
#sequence #projector_second_backward > div {
color: #bf2e39;
}
#sequence #black input[type=checkbox]:checked {
background: white;
}
#sequence input[type=checkbox] {
-webkit-appearance: none;
-moz-appearance: none;
@ -500,6 +504,10 @@ button:focus {
box-sizing: border-box;
cursor: pointer;
}
#sequence input[type=checkbox].disabled {
cursor: not-allowed;
border-color: #646464;
}
#sequence .L {
display: inline-block;
width: 35px;
@ -627,6 +635,11 @@ button:focus {
background: #AB1A25;
border-color: #AB1A25;
}
.cmd:active.capper,
.cmd.active.capper {
background: white;
color: #272b30;
}
.cmd:active i,
.cmd.active i {
color: #272b30;
@ -650,14 +663,44 @@ button:focus {
::-webkit-scrollbar-thumb:window-inactive {
background: rgba(0, 0, 0, 0.05);
}
#settings h4 {
margin-bottom: 1px;
}
#settings > div {
width: 300px;
margin: 0 auto;
}
#settings > div.left {
float: left;
padding-left: 30px;
}
#settings > div.right {
float: right;
padding-right: 30px;
}
#settings > div.right input[type=number] {
min-width: 200px;
width: 200px;
}
#settings > div.right input[readonly] {
cursor: not-allowed;
}
#settings > div.right .spacer {
height: 62px;
}
#settings > div.right .proj_time {
height: 111px;
}
#settings > div.right .cam_time {
height: 111px;
}
#settings > div.right > div {
width: 270px;
}
#settings > div > div {
width: 360px;
}
#settings input[type=text],
#settings input[type=number],
#settings select {
display: block;
border-radius: 5px;
@ -672,33 +715,43 @@ button:focus {
padding: 6px 12px;
font-size: 21px;
min-width: 300px;
max-width: 300px;
}
#settings input[type=text] span,
#settings input[type=number] span,
#settings select span {
display: block;
font-size: 16px;
font-weight: 200;
}
#settings input[type=text]:active,
#settings input[type=number]:active,
#settings select:active,
#settings input[type=text] .active,
#settings input[type=number] .active,
#settings select .active {
background: #fff;
color: #272b30;
outline: none;
}
#settings input[type=text]:focus,
#settings input[type=number]:focus,
#settings select:focus {
outline: none;
}
#settings input[type=text].active,
#settings input[type=number].active,
#settings select.active {
border-color: #DAE035;
color: #DAE035;
}
#settings input[type=text] {
width: 200px;
}
#settings button {
margin-top: -1px;
margin-top: 0px;
float: right;
padding: 8px 16px 9px;
}
#settings input[type=radio] {
float: right;
@ -707,6 +760,17 @@ button:focus {
#settings .spacer {
margin-top: 10px;
}
#settings #version {
position: absolute;
right: 20px;
bottom: 10px;
z-index: 1000;
height: 14px;
width: auto;
font-size: 14px;
line-height: 14px;
color: #999;
}
.cm-s-monokai.CodeMirror {
background: #272b30 !important;
}
@ -795,9 +859,11 @@ button:focus {
}
#path_bar select {
line-height: 41px;
height: 41px;
height: 37px;
margin-right: 5px;
float: right;
box-sizing: content-box;
padding: 0 0 0 8px;
}
#filmout_monitor {
display: none;
@ -837,20 +903,22 @@ button:focus {
#filmout_position_wrap input {
margin-right: 5px;
margin-left: 5px;
width: 308px !important;
box-sizing: border-box;
}
#filmout_position_wrap button,
#filmout_position_wrap input {
float: left;
}
#filmout_position_wrap > div {
width: 410px;
width: 425px;
margin: 0 auto;
}
#filmout_functions {
padding-top: 5px;
}
#filmout_functions > div {
width: 410px;
width: 425px;
margin: 0 auto;
}
#filmout_stats_video,
@ -872,6 +940,12 @@ button:focus {
#filmout_stats_monitor {
right: 5px;
}
.hide {
display: none;
}
.show {
display: block;
}
#screens {
overflow-x: hidden;
}
@ -1124,19 +1198,23 @@ button:focus {
float: right;
}
.cam2,
.proj2 {
.proj2,
.black {
display: none;
}
.cam2 > *,
.proj2 > * {
.proj2 > *,
.black > * {
visibility: hidden;
}
.cam2.on,
.proj2.on {
.proj2.on,
.black.on {
display: block;
}
.cam2.on > *,
.proj2.on > * {
.proj2.on > *,
.black.on > * {
visibility: visible;
}
#overlay {

View File

@ -1,5 +1,5 @@
{
"version": "1.6.7",
"version": "1.8.164",
"ext_port": 1111,
"profiles": {
"mcopy": {
@ -15,8 +15,8 @@
"momentary": 0
},
"black": {
"before": 0,
"after": 0
"before": 100,
"after": 100
},
"light": false
},
@ -178,7 +178,22 @@
"cameras": "4",
"camera_projectors_identifier": "5",
"cameras_projector_identifier": "6",
"cameras_projectors_identifier": "7"
"cameras_projectors_identifier": "7",
"capper_identifier": "C",
"camera_capper_identifier": "8",
"camera_capper_projector_identifier": "9",
"camera_capper_projectors_identifier": "0",
"capper_on": "A",
"capper_off": "B",
"camera_open": "J",
"camera_close": "K",
"takeup_forward": "D",
"takeup_backward": "F",
"error": "E",
"camera_exposure": "G",
"state": "H",
"home": "I",
"offset": "O"
}
}
}

View File

@ -13,6 +13,16 @@
body.meter {
background: rgb(117, 117, 117);
}
body.meter #img,
body.meter #can {
display: none;
}
body.image #can{
display: none;
}
body.image #img {
display: block;
}
#img {
position: absolute;
/*background-image: url(".../img/background.jpg");*/
@ -46,35 +56,48 @@
</canvas>
<script>
'use strict';
const { remote, ipcRenderer } = require('electron')
const { ipcRenderer } = require('electron')
const remote = require('@electron/remote')
let imgTmp;
function delay (ms) {
return new Promise((resolve) => {
return setTimeout(resolve, ms)
})
}
async function setImage (src) {
return new Promise(async (resolve, reject) => {
imgTmp = new Image()
let img = document.getElementById('img')
let body = document.querySelector('body')
if (body.classList.contains('meter')) {
body.classList.remove('meter')
}
body.className = ''
body.classList.add('image')
imgTmp.onload = function () {
img.style.backgroundImage = `url('${src}')`;
return resolve(src);
};
imgTmp.src = src;
});
img.style.backgroundImage = `url('${src}')`
return resolve(src)
}
imgTmp.src = src
})
}
function setBlank () {
let img = document.getElementById('img')
img.style.background = ''
img.style.backgroundUrl = ''
img.style.backgroundColor = 'black'
}
async function onMeter () {
console.log('meter')
const body = document.querySelector('body')
if (!body.classList.contains('meter')) {
body.classList.add('meter')
}
body.className = ''
body.classList.add('meter')
}
async function onFocus () {
console.log('focus')
const can = document.getElementById('can')
const dpr = window.devicePixelRatio || 1
const body = document.querySelector('body')
let ctx;
body.className = ''
if (!can.classList.contains('show')) {
can.classList.add('show')
}
@ -122,7 +145,9 @@
const can = document.getElementById('can')
const dpr = window.devicePixelRatio || 1
const screen = window.outerWidth / window.outerHeight
let ctx;
const body = document.querySelector('body')
let ctx
body.className = ''
if (!can.classList.contains('show')) {
can.classList.add('show')
}
@ -131,7 +156,7 @@
can.width = (window.innerHeight * arg.ratio) * dpr
can.height = window.innerHeight * dpr
} else {
can.width =window.innerWidth * dpr
can.width = window.innerWidth * dpr
can.height = (window.innerWidth / arg.ratio) * dpr
}
} else {
@ -145,7 +170,7 @@
can.style.width = `${window.innerHeight * arg.ratio}px`
can.style.height = `${window.innerHeight}px`
} else {
can.style.width = `${window.inneWidth}px`
can.style.width = `${window.innerWidth}px`
can.style.height = `${window.innerWidth / arg.ratio}px`
}
} else {
@ -208,18 +233,28 @@
}
async function onDigital (event, arg) {
if (arg.src) {
if (arg.exposure) {
setBlank()
await delay(10)
}
try {
await setImage(arg.src)
await setImage(arg.src)
} catch (err) {
console.error(err)
}
ipcRenderer.send('display_load', { src : arg.src });
if (arg.exposure) {
await delay(arg.exposure)
setBlank()
}
ipcRenderer.send('display_load', { src : arg.src })
}
return event.returnValue = true
}
async function onEscape (evt) {
let isEscape = false
let win
evt = evt || window.event
if ('key' in evt) {
@ -227,6 +262,7 @@
} else {
isEscape = (evt.keyCode == 27)
}
if (isEscape) {
win = remote.getCurrentWindow()
win.close()

12
app/entitlements.plist Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

View File

@ -13,7 +13,7 @@
</head>
<body onload="init();" style="background:#272b30;">
<nav id="toolbar"></nav>
<div id="screens">
<div id="screens" class="hide">
<div id="sequencer" class="screen" style="display: block;">
<div id="counters">
<div class="cam">
@ -45,6 +45,8 @@
<div id="camera_second_backward" class="row cam2" y="2"></div>
<div id="projector_backward" class="row" y="1"></div>
<div id="projector_second_backward" class="row proj2" y="3"></div>
<div id="black" class="row black"></div>
<div id="light_set" class="row spacer"></div>
<div id="numbers" class="row"></div>
@ -60,6 +62,8 @@
<div><span>PROJ </span><i class="fa fa-minus"></i></div>
<div class="proj2"><span>PROJ2 </span><i class="fa fa-minus"></i></div>
<div class="black"><span>BLANK </span><i class="fa fa-times"></i></div>
<div class="spacer"><span>LIGHT</span></div>
</div>
</div>
@ -144,20 +148,34 @@
<i class="fa fa-step-backward"></i>
</button>
</div>
<div>
<div class="hide">
<button id="cmd_black_forward" onclick="cmd.black_forward();" class="cmd fwd">
<i class="fa fa-times-circle"></i>
BLANK +1
<i class="fa fa-step-forward"></i>
</button>
</div>
<div>
<div class="hide">
<button id="cmd_black_backward" onclick="cmd.black_backward();" class="cmd bwd">
<i class="fa fa-times-circle"></i>
BLANK -1
<i class="fa fa-step-backward"></i>
</button>
</div>
<div class="hide">
<button id="cmd_capper_on" onclick="cmd.capper_on();" class="cmd capper">
<i class="fa fa-times-circle"></i>
CAPPER ON
<i class="fa fa-eye"></i>
</button>
</div>
<div class="hide">
<button id="cmd_capper_off" onclick="cmd.capper_off();" class="cmd capper active">
<i class="fa fa-eye"></i>
CAPPER OFF
<i class="fa fa-eye"></i>
</button>
</div>
</div>
<div>
<div>
@ -389,7 +407,7 @@
</div>
</div>
<div id="settings" class="screen">
<div>
<div class="left">
<div>
<h4>Devices</h4>
<select id="devices">
@ -419,6 +437,13 @@
<input type="text" id="intval" name="intval" placeholder="INTVAL3 URL"/>
<input type="radio" id="camera_type_intval" name="camera_type" value="intval" onclick="devices.intval();" />
</div>
<div class="spacer">
<input type="text" id="processing" name="processing" placeholder="PROCESSING URL" />
<input type="radio" id="camera_type_processing" name="camera_type" value="processing" onclick="devices.processing();" />
</div>
<div>
<div id="version"></div>
</div>
<div>
<h4>Light</h4>
<select id="light_device">
@ -432,6 +457,19 @@
</select>
</div>
</div>
<div class="right">
<div class="spacer"></div>
<div class="proj_time">
<h4>Projector Time (ms)</h4>
<input type="number" readonly id="proj_time" value="0" />
<button id="submit_proj_time" class="hide">✓</button>
</div>
<div class="cam_time">
<h4>Camera Time (ms)</h4>
<input type="number" readonly id="cam_time" value="0" />
<button id="submit_cam_time" class="hide" onclick="cam.exposure($('#cam_time').val());">✓</button>
</div>
</div>
</div>
</div>
<div id="overlay" onclick="gui.overlay(false);gui.spinner(false);"></div>

View File

@ -2474,8 +2474,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d<k.length;d++)if(c=k[d]+b,void 0!==e[c])return c;return void 0!==e[b]?b:void 0}function e(a,b){for(var c in b)a.style[d(a,c)||c]=b[c];return a}function f(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)void 0===a[d]&&(a[d]=c[d])}return a}function g(a,b){return"string"==typeof a?a:a[b%a.length]}function h(a){this.opts=f(a||{},h.defaults,n)}function i(){function c(b,c){return a("<"+b+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}}var j,k=["webkit","Moz","ms","O"],l={},m=function(){var c=a("style",{type:"text/css"});return b(document.getElementsByTagName("head")[0],c),c.sheet||c.styleSheet}(),n={lines:12,length:7,width:5,radius:10,rotate:0,corners:1,color:"#000",direction:1,speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"50%",left:"50%",position:"absolute"};h.defaults={},f(h.prototype,{spin:function(b){this.stop();{var c=this,d=c.opts,f=c.el=e(a(0,{className:d.className}),{position:d.position,width:0,zIndex:d.zIndex});d.radius+d.length+d.width}if(e(f,{left:d.left,top:d.top}),b&&b.insertBefore(f,b.firstChild||null),f.setAttribute("role","progressbar"),c.lines(f,c.opts),!j){var g,h=0,i=(d.lines-1)*(1-d.direction)/2,k=d.fps,l=k/d.speed,m=(1-d.opacity)/(l*d.trail/100),n=l/d.lines;!function o(){h++;for(var a=0;a<d.lines;a++)g=Math.max(1-(h+(d.lines-a)*n)%l*m,d.opacity),c.opacity(f,a*d.direction+i,g,d);c.timeout=c.el&&setTimeout(o,~~(1e3/k))}()}return c},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=void 0),this},lines:function(d,f){function h(b,c){return e(a(),{position:"absolute",width:f.length+f.width+"px",height:f.width+"px",background:b,boxShadow:c,transformOrigin:"left",transform:"rotate("+~~(360/f.lines*k+f.rotate)+"deg) translate("+f.radius+"px,0)",borderRadius:(f.corners*f.width>>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k<f.lines;k++)i=e(a(),{position:"absolute",top:1+~(f.width/2)+"px",transform:f.hwaccel?"translate3d(0,0,0)":"",opacity:f.opacity,animation:j&&c(f.opacity,f.trail,l+k*f.direction,f.lines)+" "+1/f.speed+"s linear infinite"}),f.shadow&&b(i,e(h("#000","0 0 4px #000"),{top:"2px"})),b(d,b(i,h(g(f.color,k),"0 0 1px rgba(0,0,0,.1)")));return d},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}});var o=e(a("group"),{behavior:"url(#default#VML)"});return!d(o,"transform")&&o.adj?i():j=d(o,"animation"),h});
const mcopy = {};
const { remote, ipcRenderer } = require('electron');
const dialog = require('electron').remote.dialog;
const remote = require('@electron/remote');
const { ipcRenderer } = require('electron');
const { dialog } = remote;
const notifier = require('node-notifier');
const fs = require('fs');
const uuid = require('uuid').v4;
@ -2495,8 +2496,14 @@ const cmd = require('./lib/ui/cmd.js');
const devices = require('./lib/ui/devices.js');
const filmout = require('./lib/ui/filmout.js');
const mse = require('./lib/ui/mscript.js');
const capper = require('./lib/ui/capper.js');
const timing = require('./lib/ui/timing.js');
const Mscript = require('./lib/mscript');
const { delay } = require('./lib/delay');
const alertObj = require('./lib/ui/alert.js');
const gamecontroller = require('./lib/ui/gamecontroller.js');
const { Log } = require('./lib/log');
let log;
/******
@ -2510,9 +2517,10 @@ mcopy.state = {
async function init () {
'use strict';
log = await require('log')({})
log = await Log({ label : 'ui' })
nav.init();
gui.init();
grid.init();
mse.mscript.init();
mse.console.init();
@ -2523,4 +2531,8 @@ async function init () {
proj.init();
cam.init();
seq.init();
capper.init();
alertObj.init();
timing.init();
gamecontroller.init(seq, cmd, cam, proj);
};

View File

@ -10,6 +10,13 @@
@import "./mscript.less";
@import "./filmout.less";
.hide {
display: none;
}
.show {
display: block;
}
#screens{
overflow-x: hidden;
}
@ -168,7 +175,8 @@
}
.cam2,
.proj2{
.proj2,
.black{
display : none;
> * {
visibility: hidden;

View File

@ -42,6 +42,10 @@
background: @BACKWARD;
border-color: @BACKWARD;
}
&.capper{
background: white;
color: @BG;
}
i{
color: @BG;
}

View File

@ -27,9 +27,11 @@
}
select{
line-height: 41px;
height: 41px;
height: 37px;
margin-right: 5px;
float: right;
box-sizing: content-box;
padding: 0 0 0 8px;
}
}
#filmout_file {
@ -73,12 +75,14 @@
input{
margin-right: 5px;
margin-left: 5px;
width: 308px !important;
box-sizing: border-box;
}
button, input{
float: left;
}
> div{
width: 410px;
width: 425px;
margin: 0 auto;
}
}
@ -86,7 +90,7 @@
#filmout_functions{
padding-top: 5px;
> div{
width: 410px;
width: 425px;
margin: 0 auto;
}
}

View File

@ -28,6 +28,7 @@
float: right;
width: 90px;
margin-right: 60px;
height: 32px;
}
}
#seq_stats{
@ -126,6 +127,13 @@
color: @BACKWARD + @SECOND;
}
}
#black{
input[type=checkbox]{
&:checked{
background: white;
}
}
}
input[type=checkbox]{
-webkit-appearance: none;
-moz-appearance: none;
@ -141,6 +149,10 @@
display: inline-block;
box-sizing: border-box;
cursor: pointer;
&.disabled{
cursor: not-allowed;
border-color: rgb(100, 100, 100);
}
}
.L{
display: inline-block;

View File

@ -1,25 +1,61 @@
#settings{
h4{
margin-bottom: 1px;
}
> div{
width: 300px;
margin: 0 auto;
&.left{
float: left;
padding-left: 30px;
}
&.right{
float: right;
padding-right: 30px;
input[type=number] {
min-width: 200px;
width: 200px;
}
input[readonly]{
cursor: not-allowed;
}
.spacer{
height: 62px;
}
.proj_time{
height: 111px;
}
.cam_time{
height: 111px;
}
& > div {
width: 270px;
}
}
}
> div > div{
width: 360px;
}
input[type=text], select{
input[type=text],
input[type=number],
select{
.button();
display: inline-block;
padding: 6px 12px;
font-size: 21px;
min-width: 300px;
max-width: 300px;
&.active{
border-color: @SELECTED;
color: @SELECTED;
}
}
input[type=text]{
width: 200px;
}
button{
margin-top: -1px;
float: right;
margin-top: 0px;
float: right;
padding: 8px 16px 9px;
}
input[type=radio]{
float: right;
@ -28,4 +64,15 @@
.spacer{
margin-top: 10px;
}
#version{
position: absolute;
right: 20px;
bottom: 10px;
z-index: 1000;
height: 14px;
width: auto;
font-size: 14px;
line-height: 14px;
color: #999;
}
}

40
app/lib/alert/Readme.md Normal file
View File

@ -0,0 +1,40 @@
<a name="module_lib/alert"></a>
## lib/alert
* [lib/alert](#module_lib/alert)
* [~Alert](#module_lib/alert..Alert)
* [.init()](#module_lib/alert..Alert+init)
* [.listen()](#module_lib/alert..Alert+listen)
* [.listener()](#module_lib/alert..Alert+listener)
* [.start()](#module_lib/alert..Alert+start)
<a name="module_lib/alert..Alert"></a>
### lib/alert~Alert
Class for pushing an alert to the UI from the backend.
**Kind**: inner class of [<code>lib/alert</code>](#module_lib/alert)
* [~Alert](#module_lib/alert..Alert)
* [.init()](#module_lib/alert..Alert+init)
* [.listen()](#module_lib/alert..Alert+listen)
* [.listener()](#module_lib/alert..Alert+listener)
* [.start()](#module_lib/alert..Alert+start)
<a name="module_lib/alert..Alert+init"></a>
#### alert.init()
**Kind**: instance method of [<code>Alert</code>](#module_lib/alert..Alert)
<a name="module_lib/alert..Alert+listen"></a>
#### alert.listen()
**Kind**: instance method of [<code>Alert</code>](#module_lib/alert..Alert)
<a name="module_lib/alert..Alert+listener"></a>
#### alert.listener()
**Kind**: instance method of [<code>Alert</code>](#module_lib/alert..Alert)
<a name="module_lib/alert..Alert+start"></a>
#### alert.start()
**Kind**: instance method of [<code>Alert</code>](#module_lib/alert..Alert)

29
app/lib/alert/index.d.ts vendored Normal file
View File

@ -0,0 +1,29 @@
import type { WebContents } from 'electron';
/** @module lib/alert */
/**
* Class for pushing an alert to the UI from the backend.
*/
export declare class Alert {
private ipc;
private log;
private id;
private cb;
private ui;
constructor(ui: WebContents);
/**
*
**/
private init;
/**
*
**/
private listen;
/**
*
**/
private listener;
/**
*
**/
start(cmd: string): Promise<number>;
}

62
app/lib/alert/index.js Normal file
View File

@ -0,0 +1,62 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Alert = void 0;
const electron_1 = require("electron");
const log_1 = require("log");
/** @module lib/alert */
/**
* Class for pushing an alert to the UI from the backend.
*/
class Alert {
constructor(ui) {
this.ipc = electron_1.ipcMain;
this.id = 'alert';
this.cb = null;
this.ui = ui;
this.init();
}
/**
*
**/
async init() {
this.log = await (0, log_1.Log)({ label: this.id });
this.listen();
}
/**
*
**/
listen() {
this.ipc.on(this.id, this.listener.bind(this));
}
/**
*
**/
async listener(event, arg) {
if (this.cb !== null) {
try {
await this.cb(arg.state, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
*
**/
async start(cmd) {
const start = +new Date();
const msg = (cmd + '').replace('ALERT', '').replace('Alert', '').replace('alert', '').trim();
this.ui.send(this.id, { msg });
return new Promise(function (resolve, reject) {
this.cb = function () {
const ms = (+new Date()) - start;
return resolve(ms);
};
}.bind(this));
}
}
exports.Alert = Alert;
module.exports = { Alert };
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/alert/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,uCAAmC;AAEnC,6BAA0B;AAI1B,wBAAwB;AAExB;;GAEG;AAEH,MAAa,KAAK;IAOjB,YAAc,EAAgB;QANtB,QAAG,GAAoB,kBAAO,CAAA;QAE9B,OAAE,GAAY,OAAO,CAAA;QACrB,OAAE,GAAc,IAAI,CAAA;QAI3B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,GAAG,GAAG,MAAM,IAAA,SAAG,EAAC,EAAE,KAAK,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QACzC,IAAI,CAAC,MAAM,EAAE,CAAA;IACd,CAAC;IAED;;QAEI;IACI,MAAM;QACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,QAAQ,CAAE,KAAoB,EAAE,GAAS;QACtD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE;YACrB,IAAI;gBACH,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;aAChC;YAAC,OAAO,GAAG,EAAE;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;aACnB;SACD;QACD,KAAK,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IAED;;QAEI;IACG,KAAK,CAAC,KAAK,CAAE,GAAY;QAC/B,MAAM,KAAK,GAAY,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,MAAM,GAAG,GAAY,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACrG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAC9B,OAAO,IAAI,OAAO,CAAC,UAAU,OAAkB,EAAE,MAAiB;YACjE,IAAI,CAAC,EAAE,GAAG;gBACT,MAAM,EAAE,GAAY,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;gBAC1C,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC,CAAA;QACF,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACf,CAAC;CACD;AAvDD,sBAuDC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAA"}

View File

@ -1,43 +1,146 @@
<a name="Arduino"></a>
## Modules
## Arduino
Class representing the arduino communication features
<dl>
<dt><a href="#module_lib/arduino">lib/arduino</a></dt>
<dd></dd>
</dl>
**Kind**: global class
## Constants
* [Arduino](#Arduino)
* [.enumerate()](#Arduino+enumerate) ⇒ <code>Promise</code>
* [.sendAsync(device, cmd)](#Arduino+sendAsync) ⇒ <code>Promise</code>
* [.writeAsync(device, str)](#Arduino+writeAsync) ⇒ <code>Promise</code>
* [.openArduino(device)](#Arduino+openArduino) ⇒ <code>Promise</code>
* [.closeArduino(device)](#Arduino+closeArduino) ⇒ <code>Promise</code>
<dl>
<dt><a href="#delay_1">delay_1</a></dt>
<dd><p>2023-07-16 Clarification</p>
<p>Previous versions of this script intermingled and even
swapped the usage of the terms &#39;serial&#39; and &#39;device&#39;.
From here on out, the terms will be used as such:</p>
<p>serial - a hardware address of a serial port
device - common name of a type of mcopy device (eg. camera,
projector, light) that is aliased to a serial port</p>
</dd>
</dl>
<a name="Arduino+enumerate"></a>
<a name="module_lib/arduino"></a>
### arduino.enumerate() ⇒ <code>Promise</code>
## lib/arduino
* [lib/arduino](#module_lib/arduino)
* [~Arduino](#module_lib/arduino..Arduino)
* [.enumerate()](#module_lib/arduino..Arduino+enumerate) ⇒ <code>Promise</code>
* [.sendAsync(device, cmd)](#module_lib/arduino..Arduino+sendAsync) ⇒ <code>Promise</code>
* [.send(device, cmd)](#module_lib/arduino..Arduino+send) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
* [.sendString(device, str)](#module_lib/arduino..Arduino+sendString) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
* [.stateAsync()](#module_lib/arduino..Arduino+stateAsync)
* [.state()](#module_lib/arduino..Arduino+state)
* [.writeAsync(device, str)](#module_lib/arduino..Arduino+writeAsync) ⇒ <code>Promise</code>
* [.end(serial, data)](#module_lib/arduino..Arduino+end) ⇒ <code>any</code>
* [.aliasSerial(device, serial)](#module_lib/arduino..Arduino+aliasSerial)
* [.connect(device, serial, confirm)](#module_lib/arduino..Arduino+connect) ⇒ <code>Promise.&lt;string&gt;</code>
* [.confirmEnd(data)](#module_lib/arduino..Arduino+confirmEnd)
* [.verify()](#module_lib/arduino..Arduino+verify) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.distinguish()](#module_lib/arduino..Arduino+distinguish) ⇒ <code>Promise.&lt;string&gt;</code>
* [.close()](#module_lib/arduino..Arduino+close) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.fakeConnect(serial)](#module_lib/arduino..Arduino+fakeConnect) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.openArduino(device)](#module_lib/arduino..Arduino+openArduino) ⇒ <code>Promise</code>
* [.closeArduino(device)](#module_lib/arduino..Arduino+closeArduino) ⇒ <code>Promise</code>
<a name="module_lib/arduino..Arduino"></a>
### lib/arduino~Arduino
Class representing the arduino communication features.
**Kind**: inner class of [<code>lib/arduino</code>](#module_lib/arduino)
* [~Arduino](#module_lib/arduino..Arduino)
* [.enumerate()](#module_lib/arduino..Arduino+enumerate) ⇒ <code>Promise</code>
* [.sendAsync(device, cmd)](#module_lib/arduino..Arduino+sendAsync) ⇒ <code>Promise</code>
* [.send(device, cmd)](#module_lib/arduino..Arduino+send) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
* [.sendString(device, str)](#module_lib/arduino..Arduino+sendString) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
* [.stateAsync()](#module_lib/arduino..Arduino+stateAsync)
* [.state()](#module_lib/arduino..Arduino+state)
* [.writeAsync(device, str)](#module_lib/arduino..Arduino+writeAsync) ⇒ <code>Promise</code>
* [.end(serial, data)](#module_lib/arduino..Arduino+end) ⇒ <code>any</code>
* [.aliasSerial(device, serial)](#module_lib/arduino..Arduino+aliasSerial)
* [.connect(device, serial, confirm)](#module_lib/arduino..Arduino+connect) ⇒ <code>Promise.&lt;string&gt;</code>
* [.confirmEnd(data)](#module_lib/arduino..Arduino+confirmEnd)
* [.verify()](#module_lib/arduino..Arduino+verify) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.distinguish()](#module_lib/arduino..Arduino+distinguish) ⇒ <code>Promise.&lt;string&gt;</code>
* [.close()](#module_lib/arduino..Arduino+close) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.fakeConnect(serial)](#module_lib/arduino..Arduino+fakeConnect) ⇒ <code>Promise.&lt;boolean&gt;</code>
* [.openArduino(device)](#module_lib/arduino..Arduino+openArduino) ⇒ <code>Promise</code>
* [.closeArduino(device)](#module_lib/arduino..Arduino+closeArduino) ⇒ <code>Promise</code>
<a name="module_lib/arduino..Arduino+enumerate"></a>
#### arduino.enumerate() ⇒ <code>Promise</code>
Enumerate all connected devices that might be Arduinos
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise</code> - Resolves after enumerating
<a name="Arduino+sendAsync"></a>
<a name="module_lib/arduino..Arduino+sendAsync"></a>
### arduino.sendAsync(device, cmd) ⇒ <code>Promise</code>
#### arduino.sendAsync(device, cmd) ⇒ <code>Promise</code>
Send a command to an Arduino using async/await
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise</code> - Resolves after sending
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | Arduino identifier |
| device | <code>string</code> | The Arduino device identifier |
| cmd | <code>string</code> | Single character command to send |
<a name="Arduino+writeAsync"></a>
<a name="module_lib/arduino..Arduino+send"></a>
### arduino.writeAsync(device, str) ⇒ <code>Promise</code>
#### arduino.send(device, cmd) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
Sends a command to the specified Arduino and waits for a response.
Handles the communication lock to prevent sending multiple commands simultaneously.
Emits an 'arduino_send' event after successfully sending the command.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;(boolean\|string)&gt;</code> - Returns 'false' if the communication is locked, otherwise returns the response from the device.
**Throws**:
- <code>Error</code> Throws an error if the sendAsync method encounters an error.
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | The Arduino device identifier. |
| cmd | <code>string</code> | The command to be sent to the Arduino. |
<a name="module_lib/arduino..Arduino+sendString"></a>
#### arduino.sendString(device, str) ⇒ <code>Promise.&lt;(boolean\|string)&gt;</code>
Sends a string to the specified Arduino.
Handles different types of devices, including fake devices for testing purposes.
Waits for a specified delay before sending the string.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;(boolean\|string)&gt;</code> - Returns 'true' if the string is sent successfully, otherwise returns an error message.
**Throws**:
- <code>Error</code> Throws an error if the writeAsync method encounters an error.
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | The Arduino device identifier. |
| str | <code>string</code> | The string to be sent to the Arduino. |
<a name="module_lib/arduino..Arduino+stateAsync"></a>
#### arduino.stateAsync()
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
<a name="module_lib/arduino..Arduino+state"></a>
#### arduino.state()
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
<a name="module_lib/arduino..Arduino+writeAsync"></a>
#### arduino.writeAsync(device, str) ⇒ <code>Promise</code>
Send a string to an Arduino using async/await
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise</code> - Resolves after sending
| Param | Type | Description |
@ -45,27 +148,149 @@ Send a string to an Arduino using async/await
| device | <code>string</code> | Arduino identifier |
| str | <code>string</code> | String to send |
<a name="Arduino+openArduino"></a>
<a name="module_lib/arduino..Arduino+end"></a>
### arduino.openArduino(device) ⇒ <code>Promise</code>
#### arduino.end(serial, data) ⇒ <code>any</code>
Handles the end of communication with the Arduino.
Calculates the time taken for the communication, executes the callback,
and emits an 'arduino_end' event. Handles errors and stray data received.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>any</code> - The time taken for the communication in milliseconds.
| Param | Type | Description |
| --- | --- | --- |
| serial | <code>string</code> | The serial address of the Arduino device. |
| data | <code>string</code> | The data received from the Arduino. |
<a name="module_lib/arduino..Arduino+aliasSerial"></a>
#### arduino.aliasSerial(device, serial)
Associates an alias with an Arduinos serial address.
Used to map multi-purpose devices onto the same serial connection.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | The serial number of the target Arduino. |
| serial | <code>string</code> | The alias to be associated with the target device. |
<a name="module_lib/arduino..Arduino+connect"></a>
#### arduino.connect(device, serial, confirm) ⇒ <code>Promise.&lt;string&gt;</code>
Connects to an Arduino using its serial number.
Sets up the SerialPort instance and path for the device, and handles data communication.
Handles opening the connection and emitting 'arduino_end' or 'confirmEnd' events upon receiving data.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;string&gt;</code> - Resolves with the device path if the connection is successful.
**Throws**:
- <code>Error</code> Rejects with an error message if the connection fails.
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | The device identifier (common name). |
| serial | <code>string</code> | The serial address of the target Arduino (e.g., COM port on Windows). |
| confirm | <code>function</code> | A callback function to be executed upon receiving confirmation data. |
<a name="module_lib/arduino..Arduino+confirmEnd"></a>
#### arduino.confirmEnd(data)
Handles the confirmation data received from an Arduino.
Executes the confirmation callback function if the received data is present in the list of expected values.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
| Param | Type | Description |
| --- | --- | --- |
| data | <code>string</code> | The data received from the Arduino. |
<a name="module_lib/arduino..Arduino+verify"></a>
#### arduino.verify() ⇒ <code>Promise.&lt;boolean&gt;</code>
Verifies the connection to an Arduino by sending a connect command.
The confirmation callback checks if the received data matches the expected connect command.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;boolean&gt;</code> - Resolves with 'true' if the connection is verified successfully.
**Throws**:
- <code>Error</code> Rejects with an error message if the connection verification fails.
<a name="module_lib/arduino..Arduino+distinguish"></a>
#### arduino.distinguish() ⇒ <code>Promise.&lt;string&gt;</code>
Distinguishes the type of Arduino connected.
Sends a command to the device to identify its type and resolves the promise with the received type.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;string&gt;</code> - Resolves with the type of the connected Arduino-based device.
**Throws**:
- <code>Error</code> Rejects with an error message if the distinguish operation fails.
<a name="module_lib/arduino..Arduino+close"></a>
#### arduino.close() ⇒ <code>Promise.&lt;boolean&gt;</code>
Closes the connection to an Arduino.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;boolean&gt;</code> - Resolves with 'true' if the connection is closed successfully.
**Throws**:
- <code>Error</code> Throws an error if the closeArduino method encounters an error.
<a name="module_lib/arduino..Arduino+fakeConnect"></a>
#### arduino.fakeConnect(serial) ⇒ <code>Promise.&lt;boolean&gt;</code>
Establishes a fake connection to an Arduino for testing purposes.
Creates a fake SerialPort instance with custom write and string methods.
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise.&lt;boolean&gt;</code> - Resolves with 'true' if the fake connection is established successfully.
| Param | Type | Description |
| --- | --- | --- |
| serial | <code>string</code> | The device identifier of the fake Arduino. |
<a name="module_lib/arduino..Arduino+openArduino"></a>
#### arduino.openArduino(device) ⇒ <code>Promise</code>
Connect to an Arduino using async/await
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise</code> - Resolves after opening
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | Arduino identifier |
<a name="Arduino+closeArduino"></a>
<a name="module_lib/arduino..Arduino+closeArduino"></a>
### arduino.closeArduino(device) ⇒ <code>Promise</code>
#### arduino.closeArduino(device) ⇒ <code>Promise</code>
Close a connection to an Arduino using async/await
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
**Kind**: instance method of [<code>Arduino</code>](#module_lib/arduino..Arduino)
**Returns**: <code>Promise</code> - Resolves after closing
| Param | Type | Description |
| --- | --- | --- |
| device | <code>string</code> | Arduino identifier |
<a name="delay_1"></a>
## delay\_1
2023-07-16 Clarification
Previous versions of this script intermingled and even
swapped the usage of the terms 'serial' and 'device'.
From here on out, the terms will be used as such:
serial - a hardware address of a serial port
device - common name of a type of mcopy device (eg. camera,
projector, light) that is aliased to a serial port
**Kind**: global constant

179
app/lib/arduino/index.d.ts vendored Normal file
View File

@ -0,0 +1,179 @@
/// <reference types="node" />
import type { EventEmitter } from 'events';
import type { Config } from 'cfg';
/** @module lib/arduino */
/**
* Class representing the arduino communication features.
*/
export declare class Arduino {
private log;
private eventEmitter;
private cfg;
private path;
private known;
private serial;
private baud;
private queue;
private timer;
private locks;
private confirmExec;
private errorState;
private keys;
private values;
alias: any;
stateStr: any;
hasState: any;
constructor(cfg: Config, ee: EventEmitter, errorState: Function);
init(): Promise<void>;
/**
* Enumerate all connected devices that might be Arduinos
*
* @async
* @returns {Promise} Resolves after enumerating
**/
enumerate(): Promise<string[]>;
/**
* Send a command to an Arduino using async/await
*
* @param {string} device The Arduino device identifier
* @param {string} cmd Single character command to send
*
* @async
* @returns {Promise} Resolves after sending
**/
private sendAsync;
/**
* Sends a command to the specified Arduino and waits for a response.
* Handles the communication lock to prevent sending multiple commands simultaneously.
* Emits an 'arduino_send' event after successfully sending the command.
*
* @async
* @param {string} device - The Arduino device identifier.
* @param {string} cmd - The command to be sent to the Arduino.
* @returns {Promise<boolean|string>} Returns 'false' if the communication is locked, otherwise returns the response from the device.
* @throws {Error} Throws an error if the sendAsync method encounters an error.
**/
send(device: string, cmd: string): Promise<number>;
/**
* Sends a string to the specified Arduino.
* Handles different types of devices, including fake devices for testing purposes.
* Waits for a specified delay before sending the string.
*
* @async
* @param {string} device - The Arduino device identifier.
* @param {string} str - The string to be sent to the Arduino.
* @returns {Promise<boolean|string>} Returns 'true' if the string is sent successfully, otherwise returns an error message.
* @throws {Error} Throws an error if the writeAsync method encounters an error.
**/
sendString(device: string, str: string): Promise<number>;
/**
*
**/
private stateAsync;
/**
*
**/
state(device: string, confirm?: boolean): Promise<string>;
/**
* Send a string to an Arduino using async/await
*
* @param {string} device Arduino identifier
* @param {string} str String to send
*
* @returns {Promise} Resolves after sending
**/
private writeAsync;
/**
* Handles the end of communication with the Arduino.
* Calculates the time taken for the communication, executes the callback,
* and emits an 'arduino_end' event. Handles errors and stray data received.
*
* @param {string} serial - The serial address of the Arduino device.
* @param {string} data - The data received from the Arduino.
* @returns {any} The time taken for the communication in milliseconds.
**/
private end;
private error;
/**
* Associates an alias with an Arduinos serial address.
* Used to map multi-purpose devices onto the same serial connection.
*
* @param {string} device - The serial number of the target Arduino.
* @param {string} serial - The alias to be associated with the target device.
**/
aliasSerial(device: string, serial: string): void;
/**
* Connects to an Arduino using its serial number.
* Sets up the SerialPort instance and path for the device, and handles data communication.
* Handles opening the connection and emitting 'arduino_end' or 'confirmEnd' events upon receiving data.
*
* @async
* @param {string} device - The device identifier (common name).
* @param {string} serial - The serial address of the target Arduino (e.g., COM port on Windows).
* @param {function} confirm - A callback function to be executed upon receiving confirmation data.
* @returns {Promise<string>} Resolves with the device path if the connection is successful.
* @throws {Error} Rejects with an error message if the connection fails.
**/
connect(device: string, serial: string, confirm: any): Promise<any>;
/**
* Handles the confirmation data received from an Arduino.
* Executes the confirmation callback function if the received data is present in the list of expected values.
*
* @param {string} data - The data received from the Arduino.
**/
private confirmEnd;
/**
* Verifies the connection to an Arduino by sending a connect command.
* The confirmation callback checks if the received data matches the expected connect command.
*
* @async
* @returns {Promise<boolean>} Resolves with 'true' if the connection is verified successfully.
* @throws {Error} Rejects with an error message if the connection verification fails.
**/
verify(): Promise<unknown>;
/**
* Distinguishes the type of Arduino connected.
* Sends a command to the device to identify its type and resolves the promise with the received type.
*
* @async
* @returns {Promise<string>} Resolves with the type of the connected Arduino-based device.
* @throws {Error} Rejects with an error message if the distinguish operation fails.
**/
distinguish(): Promise<string>;
/**
* Closes the connection to an Arduino.
*
* @async
* @returns {Promise<boolean>} Resolves with 'true' if the connection is closed successfully.
* @throws {Error} Throws an error if the closeArduino method encounters an error.
**/
close(): Promise<boolean>;
/**
* Establishes a fake connection to an Arduino for testing purposes.
* Creates a fake SerialPort instance with custom write and string methods.
*
* @async
* @param {string} serial - The device identifier of the fake Arduino.
* @returns {Promise<boolean>} Resolves with 'true' if the fake connection is established successfully.
**/
fakeConnect(device: string): Promise<boolean>;
/**
* Connect to an Arduino using async/await
*
* @param {string} device Arduino identifier
*
* @returns {Promise} Resolves after opening
**/
private openArduino;
/**
* Close a connection to an Arduino using async/await
*
* @param {string} device Arduino identifier
*
* @returns {Promise} Resolves after closing
**/
private closeArduino;
private lock;
private unlock;
private isLocked;
}

View File

@ -1,16 +1,25 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
//import Log = require('log');
exports.Arduino = void 0;
/**
* 2023-07-16 Clarification
*
* Previous versions of this script intermingled and even
* swapped the usage of the terms 'serial' and 'device'.
* From here on out, the terms will be used as such:
*
* serial - a hardware address of a serial port
* device - common name of a type of mcopy device (eg. camera,
* projector, light) that is aliased to a serial port
*
**/
const delay_1 = require("delay");
const SerialPort = require('serialport');
const Readline = SerialPort.parsers.Readline;
const exec = require('child_process').exec;
const parser = new Readline('');
const log_1 = require("log");
const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');
const parser = new ReadlineParser({ delimiter: '\r\n' });
const newlineRe = new RegExp('\n', 'g');
const returnRe = new RegExp('\r', 'g');
let eventEmitter;
let cfg;
let arduino;
const KNOWN = [
'/dev/tty.usbmodem1a161',
'/dev/tty.usbserial-A800f8dk',
@ -21,30 +30,36 @@ const KNOWN = [
'/dev/ttyACM0',
'COM3'
];
/** @module lib/arduino */
/**
* Class representing the arduino communication features
**/
* Class representing the arduino communication features.
*/
class Arduino {
constructor(errorState) {
constructor(cfg, ee, errorState) {
this.path = {};
this.known = KNOWN;
this.alias = {};
this.serial = { connect: {}, projector: {}, camera: {}, light: {} };
this.serial = {};
this.baud = 57600;
this.queue = {};
this.timer = 0;
this.lock = false;
this.locks = {};
this.alias = {};
this.stateStr = {};
this.hasState = {};
this.cfg = cfg;
this.eventEmitter = ee;
this.errorState = errorState;
this.init();
}
async init() {
const Log = require('log');
this.log = await Log({ label: 'arduino' });
this.log = await (0, log_1.Log)({ label: 'arduino' });
this.keys = Object.keys(this.cfg.arduino.cmd);
this.values = this.keys.map((key) => this.cfg.arduino.cmd[key]);
}
/**
* Enumerate all connected devices that might be Arduinos
*
* @async
* @returns {Promise} Resolves after enumerating
**/
async enumerate() {
@ -85,63 +100,149 @@ class Arduino {
/**
* Send a command to an Arduino using async/await
*
* @param {string} device Arduino identifier
* @param {string} device The Arduino device identifier
* @param {string} cmd Single character command to send
*
* @async
* @returns {Promise} Resolves after sending
**/
async sendAsync(device, cmd) {
return new Promise((resolve, reject) => {
//this.log.info(`sendAsync ${cmd} -> ${device}`)
this.queue[cmd] = (ms) => {
return resolve(ms);
};
return this.serial[device].write(cmd, (err, results) => {
//this.log.info(`Device: ${device}`)
return this.serial[this.alias[device]].write(cmd, (err, results) => {
if (err) {
//console.error(err)
//this.log.error(err)
return reject(err);
}
//
});
});
}
async send(serial, cmd) {
const device = this.alias[serial];
let results;
console.log(`${cmd} -> ${serial}`);
if (this.locks[serial]) {
return false;
/**
* Sends a command to the specified Arduino and waits for a response.
* Handles the communication lock to prevent sending multiple commands simultaneously.
* Emits an 'arduino_send' event after successfully sending the command.
*
* @async
* @param {string} device - The Arduino device identifier.
* @param {string} cmd - The command to be sent to the Arduino.
* @returns {Promise<boolean|string>} Returns 'false' if the communication is locked, otherwise returns the response from the device.
* @throws {Error} Throws an error if the sendAsync method encounters an error.
**/
async send(device, cmd) {
const serial = this.alias[device];
let ms;
this.log.info(`send ${cmd} -> ${device}`);
if (this.isLocked(serial)) {
this.log.error(`send Serial ${serial} is locked`);
return 0;
}
this.timer = new Date().getTime();
this.locks[serial] = true;
await delay_1.delay(cfg.arduino.serialDelay);
this.lock(serial);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
try {
results = await this.sendAsync(device, cmd);
ms = await this.sendAsync(device, cmd);
}
catch (e) {
return console.error(e);
this.log.error(`Failed to send to ${device} @ ${serial}`, e);
return 0;
}
this.locks[serial] = false;
await eventEmitter.emit('arduino_send', cmd);
return results;
this.unlock(serial);
await this.eventEmitter.emit('arduino_send', cmd);
return ms;
}
async string(serial, str) {
const device = this.alias[serial];
let writeSuccess;
await delay_1.delay(cfg.arduino.serialDelay);
if (typeof this.serial[device].fake !== 'undefined'
&& this.serial[device].fake) {
return this.serial[device].string(str);
/**
* Sends a string to the specified Arduino.
* Handles different types of devices, including fake devices for testing purposes.
* Waits for a specified delay before sending the string.
*
* @async
* @param {string} device - The Arduino device identifier.
* @param {string} str - The string to be sent to the Arduino.
* @returns {Promise<boolean|string>} Returns 'true' if the string is sent successfully, otherwise returns an error message.
* @throws {Error} Throws an error if the writeAsync method encounters an error.
**/
async sendString(device, str) {
let ms;
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (typeof this.serial[this.alias[device]].fake !== 'undefined'
&& this.serial[this.alias[device]].fake) {
return this.serial[this.alias[device]].string(str);
}
else {
this.log.info(`sendString ${str} -> ${device}`);
try {
writeSuccess = await this.writeAsync(device, str);
ms = await this.writeAsync(device, str);
}
catch (e) {
return console.error(e);
this.log.error(`Error sending string to ${device}`, e);
return 0;
}
return writeSuccess;
this.unlock(this.alias[device]);
return ms;
}
}
/**
*
**/
async stateAsync(device, confirm = false) {
const cmd = this.cfg.arduino.cmd.state;
const serial = confirm ? this.alias['connect'] : this.alias[device];
return new Promise((resolve, reject) => {
this.queue[cmd] = (state) => {
this.stateStr[device] = state;
if (confirm) {
this.hasState[device] = true;
this.log.info(`Device ${device} supports state [${state}]`);
}
return resolve(state);
};
if (confirm) {
setTimeout(function () {
if (typeof this.queue[cmd] !== 'undefined') {
delete this.queue[cmd];
this.hasState[device] = false;
this.log.info(`Device ${device} does not support state`);
return resolve(null);
}
}.bind(this), 1000);
}
this.log.info(`stateAsync ${cmd} -> ${device}`);
return this.serial[serial].write(cmd, (err, results) => {
if (err) {
//this.log.error(err)
return reject(err);
}
});
});
}
/**
*
**/
async state(device, confirm = false) {
const serial = confirm ? this.alias['connect'] : this.alias[device];
let results;
if (this.isLocked(serial)) {
this.log.warn(`state Serial ${serial} is locked`);
return null;
}
this.timer = new Date().getTime();
this.lock(serial);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
try {
results = await this.stateAsync(device, confirm);
}
catch (e) {
this.log.error(`Error getting state from ${device}`, e);
return null;
}
this.unlock(serial);
await this.eventEmitter.emit('arduino_state', this.cfg.arduino.cmd.state);
return results;
}
/**
* Send a string to an Arduino using async/await
*
@ -152,7 +253,7 @@ class Arduino {
**/
async writeAsync(device, str) {
return new Promise((resolve, reject) => {
this.serial[device].write(str, function (err, results) {
this.serial[this.alias[device]].write(str, function (err, results) {
if (err) {
return reject(err);
}
@ -160,59 +261,104 @@ class Arduino {
});
});
}
/**
* Handles the end of communication with the Arduino.
* Calculates the time taken for the communication, executes the callback,
* and emits an 'arduino_end' event. Handles errors and stray data received.
*
* @param {string} serial - The serial address of the Arduino device.
* @param {string} data - The data received from the Arduino.
* @returns {any} The time taken for the communication in milliseconds.
**/
end(serial, data) {
const end = new Date().getTime();
const ms = end - this.timer;
let complete;
console.log(`${serial} -> ${data}`);
//this.log.info(`end ${serial} -> ${data}`)
if (this.queue[data] !== undefined) {
this.locks[serial] = false;
this.unlock(serial);
complete = this.queue[data](ms); //execute callback
eventEmitter.emit('arduino_end', data);
this.eventEmitter.emit('arduino_end', data);
delete this.queue[data];
}
else if (data === 'E') {
else if (data[0] === this.cfg.arduino.cmd.state) {
//this.log.info(`end serial -> ${serial}`)
this.unlock(serial);
complete = this.queue[this.cfg.arduino.cmd.state](data);
this.eventEmitter.emit('arduino_end', data);
delete this.queue[this.cfg.arduino.cmd.state];
return data;
}
else if (data[0] === this.cfg.arduino.cmd.error) {
this.log.error(`Received error from device ${serial}`);
this.unlock(serial);
this.error(serial, data);
//error state
//stop sequence
//throw error in ui
}
else {
//console.log('Received stray "' + data + '"'); //silent to user
this.log.info('Received stray "' + data + '"'); //silent to user
}
return ms;
}
aliasSerial(serial, device) {
//this.log.info(`Making "${serial}" an alias of ${device}`);
this.alias[serial] = device;
error(serial, data) {
this.log.error("ERROR", data);
}
async connect(serial, device, confirm) {
/**
* Associates an alias with an Arduinos serial address.
* Used to map multi-purpose devices onto the same serial connection.
*
* @param {string} device - The serial number of the target Arduino.
* @param {string} serial - The alias to be associated with the target device.
**/
aliasSerial(device, serial) {
//this.log.info(`Making "${serial}" an alias of ${device}`)
this.alias[device] = serial;
}
/**
* Connects to an Arduino using its serial number.
* Sets up the SerialPort instance and path for the device, and handles data communication.
* Handles opening the connection and emitting 'arduino_end' or 'confirmEnd' events upon receiving data.
*
* @async
* @param {string} device - The device identifier (common name).
* @param {string} serial - The serial address of the target Arduino (e.g., COM port on Windows).
* @param {function} confirm - A callback function to be executed upon receiving confirmation data.
* @returns {Promise<string>} Resolves with the device path if the connection is successful.
* @throws {Error} Rejects with an error message if the connection fails.
**/
async connect(device, serial, confirm) {
//this.log.info(`connect device ${device}`)
//this.log.info(`connect serial ${serial}`)
return new Promise(async (resolve, reject) => {
let connectSuccess;
this.path[serial] = device;
this.alias[serial] = device;
this.serial[device] = new SerialPort(this.path[serial], {
this.path[device] = serial;
this.aliasSerial(device, serial);
this.serial[serial] = new SerialPort({
path: serial,
autoOpen: false,
baudRate: cfg.arduino.baud,
parser: parser
baudRate: this.cfg.arduino.baud,
parser
});
this.locks[device] = false;
this.unlock(serial);
try {
connectSuccess = await this.openArduino(device);
}
catch (e) {
console.error('failed to open: ' + e);
this.log.error(`Failed to open ${device} @ ${serial}: ` + e);
return reject(e);
}
//console.log(`Opened connection with ${this.path[serial]} as ${serial}`);
this.log.info(`Opened connection with ${this.path[device]} as ${device}`);
if (!confirm) {
this.serial[device].on('data', async (data) => {
this.serial[this.alias[device]].on('data', async (data) => {
let d = data.toString('utf8');
d = d.replace(newlineRe, '').replace(returnRe, '');
return this.end(serial, d);
});
}
else {
this.serial[device].on('data', async (data) => {
this.serial[this.alias[device]].on('data', async (data) => {
let d = data.toString('utf8');
d = d.replace(newlineRe, '').replace(returnRe, '');
return await this.confirmEnd(d);
@ -221,46 +367,47 @@ class Arduino {
return resolve(this.path[serial]);
});
}
/**
* Handles the confirmation data received from an Arduino.
* Executes the confirmation callback function if the received data is present in the list of expected values.
*
* @param {string} data - The data received from the Arduino.
**/
confirmEnd(data) {
//console.dir(data)
if (data === cfg.arduino.cmd.connect
|| data === cfg.arduino.cmd.projector_identifier
|| data === cfg.arduino.cmd.camera_identifier
|| data === cfg.arduino.cmd.light_identifier
|| data === cfg.arduino.cmd.projector_light_identifier
|| data === cfg.arduino.cmd.projector_camera_light_identifier
|| data === cfg.arduino.cmd.projector_camera_identifier
|| data === cfg.arduino.cmd.projector_second_identifier
|| data === cfg.arduino.cmd.projectors_identifier
|| data === cfg.arduino.cmd.projector_second_forward
|| data === cfg.arduino.cmd.projector_second_backward
|| data === cfg.arduino.cmd.projector_second
|| data === cfg.arduino.cmd.projectors
|| data === cfg.arduino.cmd.camera_second_identifier
|| data === cfg.arduino.cmd.cameras_identifier
|| data === cfg.arduino.cmd.camera_second_forward
|| data === cfg.arduino.cmd.camera_second_backward
|| data === cfg.arduino.cmd.camera_second
|| data === cfg.arduino.cmd.cameras) {
if (this.values.indexOf(data) !== -1 && typeof this.confirmExec === 'function') {
this.confirmExec(null, data);
this.confirmExec = {};
this.confirmExec = null;
this.unlock(this.alias['connect']);
}
else if (data[0] === this.cfg.arduino.cmd.state) {
this.queue[this.cfg.arduino.cmd.state](data);
delete this.queue[this.cfg.arduino.cmd.state];
this.unlock(this.alias['connect']);
}
}
/**
* Verifies the connection to an Arduino by sending a connect command.
* The confirmation callback checks if the received data matches the expected connect command.
*
* @async
* @returns {Promise<boolean>} Resolves with 'true' if the connection is verified successfully.
* @throws {Error} Rejects with an error message if the connection verification fails.
**/
async verify() {
return new Promise(async (resolve, reject) => {
const device = this.alias['connect'];
const device = 'connect';
let writeSuccess;
this.confirmExec = function (err, data) {
if (data === cfg.arduino.cmd.connect) {
if (data === this.cfg.arduino.cmd.connect) {
return resolve(true);
}
else {
return reject('Wrong data returned');
}
};
await delay_1.delay(cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
try {
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.connect);
writeSuccess = await this.sendAsync(device, this.cfg.arduino.cmd.connect);
}
catch (e) {
return reject(e);
@ -268,64 +415,92 @@ class Arduino {
return resolve(writeSuccess);
});
}
/**
* Distinguishes the type of Arduino connected.
* Sends a command to the device to identify its type and resolves the promise with the received type.
*
* @async
* @returns {Promise<string>} Resolves with the type of the connected Arduino-based device.
* @throws {Error} Rejects with an error message if the distinguish operation fails.
**/
async distinguish() {
return new Promise(async (resolve, reject) => {
const device = this.alias['connect'];
const device = 'connect';
let writeSuccess;
let type;
this.confirmExec = function (err, data) {
if (data === cfg.arduino.cmd.projector_identifier) {
if (data === this.cfg.arduino.cmd.projector_identifier) {
type = 'projector';
}
else if (data === cfg.arduino.cmd.camera_identifier) {
else if (data === this.cfg.arduino.cmd.camera_identifier) {
type = 'camera';
}
else if (data === cfg.arduino.cmd.light_identifier) {
else if (data === this.cfg.arduino.cmd.light_identifier) {
type = 'light';
}
else if (data === cfg.arduino.cmd.projector_light_identifier) {
else if (data === this.cfg.arduino.cmd.projector_light_identifier) {
type = 'projector,light';
}
else if (data === cfg.arduino.cmd.projector_camera_light_identifier) {
else if (data === this.cfg.arduino.cmd.projector_camera_light_identifier) {
type = 'projector,camera,light';
}
else if (data === cfg.arduino.cmd.projector_camera_identifier) {
else if (data === this.cfg.arduino.cmd.projector_camera_identifier) {
type = 'projector,camera';
}
else if (data === cfg.arduino.cmd.projector_second_identifier) {
else if (data === this.cfg.arduino.cmd.projector_second_identifier) {
type = 'projector_second';
}
else if (data === cfg.arduino.cmd.projectors_identifier) {
else if (data === this.cfg.arduino.cmd.projectors_identifier) {
type = 'projector,projector_second';
}
else if (data === cfg.arduino.cmd.camera_second_identifier) {
else if (data === this.cfg.arduino.cmd.camera_second_identifier) {
type = 'camera_second';
}
else if (data === cfg.arduino.cmd.cameras_identifier) {
else if (data === this.cfg.arduino.cmd.cameras_identifier) {
type = 'camera,camera_second';
}
else if (data === cfg.arduino.cmd.camera_projectors_identifier) {
else if (data === this.cfg.arduino.cmd.camera_projectors_identifier) {
type = 'camera,projector,projector_second';
}
else if (data === cfg.arduino.cmd.cameras_projector_identifier) {
else if (data === this.cfg.arduino.cmd.cameras_projector_identifier) {
type = 'camera,camera_second,projector';
}
else if (data === cfg.arduino.cmd.cameras_projectors_identifier) {
else if (data === this.cfg.arduino.cmd.cameras_projectors_identifier) {
type = 'camera,camera_second,projector,projector_second';
}
else if (data === this.cfg.arduino.cmd.capper_identifier) {
type = 'capper';
}
else if (data === this.cfg.arduino.cmd.camera_capper_identifier) {
type = 'camera,capper';
}
else if (data === this.cfg.arduino.cmd.camera_capper_projector_identifier) {
type = 'camera,capper,projector';
}
else if (data === this.cfg.arduino.cmd.camera_capper_projectors_identifier) {
type = 'camera,capper,projector,projector_second';
}
return resolve(type);
};
await delay_1.delay(cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
try {
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.mcopy_identifier);
writeSuccess = await this.sendAsync(device, this.cfg.arduino.cmd.mcopy_identifier);
this.log.info(writeSuccess);
}
catch (e) {
return reject(e);
}
});
}
/**
* Closes the connection to an Arduino.
*
* @async
* @returns {Promise<boolean>} Resolves with 'true' if the connection is closed successfully.
* @throws {Error} Throws an error if the closeArduino method encounters an error.
**/
async close() {
const device = this.alias['connect'];
const device = 'connect';
let closeSuccess;
try {
closeSuccess = await this.closeArduino(device);
@ -335,31 +510,40 @@ class Arduino {
}
return closeSuccess;
}
;
async fakeConnect(serial) {
const device = '/dev/fake';
this.alias[serial] = device;
this.serial[device] = {
/**
* Establishes a fake connection to an Arduino for testing purposes.
* Creates a fake SerialPort instance with custom write and string methods.
*
* @async
* @param {string} serial - The device identifier of the fake Arduino.
* @returns {Promise<boolean>} Resolves with 'true' if the fake connection is established successfully.
**/
async fakeConnect(device) {
const serial = '/dev/fake';
this.aliasSerial(device, serial);
this.serial[serial] = {
write: async function (cmd, cb) {
const t = {
c: cfg.arduino.cam.time + cfg.arduino.cam.delay,
p: cfg.arduino.proj.time + cfg.arduino.proj.delay
c: this.cfg.arduino.cam.time + this.cfg.arduino.cam.delay,
p: this.cfg.arduino.proj.time + this.cfg.arduino.proj.delay,
A: 180,
B: 180
};
let timeout = t[cmd];
if (typeof timeout === 'undefined')
timeout = 10;
arduino.timer = +new Date();
await delay_1.delay(timeout);
arduino.end(serial, cmd);
this.timer = +new Date();
await (0, delay_1.delay)(timeout);
this.end(serial, cmd);
return cb();
},
}.bind(this),
string: async function (str) {
//do nothing
return true;
},
fake: true
};
//console.log('Connected to fake arduino! Not real! Does not exist!');
//this.log.info('Connected to fake arduino! Not real! Does not exist!')
return true;
}
/**
@ -371,7 +555,7 @@ class Arduino {
**/
async openArduino(device) {
return new Promise((resolve, reject) => {
return this.serial[device].open((err) => {
return this.serial[this.alias[device]].open((err) => {
if (err) {
return reject(err);
}
@ -388,7 +572,7 @@ class Arduino {
**/
async closeArduino(device) {
return new Promise((resolve, reject) => {
return this.serial[device].close((err) => {
return this.serial[this.alias[device]].close((err) => {
if (err) {
return reject(err);
}
@ -396,13 +580,18 @@ class Arduino {
});
});
}
lock(serial) {
//this.log.info(`Locked serial ${serial}`)
this.locks[serial] = true;
}
unlock(serial) {
//this.log.info(`Unlocked serial ${serial}`)
this.locks[serial] = false;
}
isLocked(serial) {
return typeof this.locks[serial] !== 'undefined' && this.locks[serial] === true;
}
}
if (typeof module !== 'undefined' && module.parent) {
module.exports = function (c, ee, errorState) {
eventEmitter = ee;
cfg = c;
arduino = new Arduino(errorState);
return arduino;
};
}
exports.Arduino = Arduino;
module.exports = { Arduino };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,49 +1,76 @@
<a name="Camera"></a>
<a name="module_lib/cam"></a>
## Camera
class representing camera functions
## lib/cam
**Kind**: global class
* [lib/cam](#module_lib/cam)
* [~Camera](#module_lib/cam..Camera)
* [.init()](#module_lib/cam..Camera+init)
* [.listen()](#module_lib/cam..Camera+listen)
* [.set()](#module_lib/cam..Camera+set)
* [.cap()](#module_lib/cam..Camera+cap)
* [.move()](#module_lib/cam..Camera+move)
* [.exposure()](#module_lib/cam..Camera+exposure)
* [.connectIntval()](#module_lib/cam..Camera+connectIntval)
* [.connectProcessing()](#module_lib/cam..Camera+connectProcessing)
* [.listener()](#module_lib/cam..Camera+listener)
* [.end()](#module_lib/cam..Camera+end)
* [Camera](#Camera)
* [.init()](#Camera+init)
* [.listen()](#Camera+listen)
* [.set()](#Camera+set)
* [.move()](#Camera+move)
* [.exposure()](#Camera+exposure)
* [.connectIntval()](#Camera+connectIntval)
* [.listener()](#Camera+listener)
* [.end()](#Camera+end)
<a name="module_lib/cam..Camera"></a>
<a name="Camera+init"></a>
### lib/cam~Camera
Class representing camera functions.
### camera.init()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+listen"></a>
**Kind**: inner class of [<code>lib/cam</code>](#module_lib/cam)
### camera.listen()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+set"></a>
* [~Camera](#module_lib/cam..Camera)
* [.init()](#module_lib/cam..Camera+init)
* [.listen()](#module_lib/cam..Camera+listen)
* [.set()](#module_lib/cam..Camera+set)
* [.cap()](#module_lib/cam..Camera+cap)
* [.move()](#module_lib/cam..Camera+move)
* [.exposure()](#module_lib/cam..Camera+exposure)
* [.connectIntval()](#module_lib/cam..Camera+connectIntval)
* [.connectProcessing()](#module_lib/cam..Camera+connectProcessing)
* [.listener()](#module_lib/cam..Camera+listener)
* [.end()](#module_lib/cam..Camera+end)
### camera.set()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+move"></a>
<a name="module_lib/cam..Camera+init"></a>
### camera.move()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+exposure"></a>
#### camera.init()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+listen"></a>
### camera.exposure()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+connectIntval"></a>
#### camera.listen()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+set"></a>
### camera.connectIntval()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+listener"></a>
#### camera.set()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+cap"></a>
### camera.listener()
**Kind**: instance method of [<code>Camera</code>](#Camera)
<a name="Camera+end"></a>
#### camera.cap()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+move"></a>
### camera.end()
**Kind**: instance method of [<code>Camera</code>](#Camera)
#### camera.move()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+exposure"></a>
#### camera.exposure()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+connectIntval"></a>
#### camera.connectIntval()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+connectProcessing"></a>
#### camera.connectProcessing()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+listener"></a>
#### camera.listener()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)
<a name="module_lib/cam..Camera+end"></a>
#### camera.end()
**Kind**: instance method of [<code>Camera</code>](#module_lib/cam..Camera)

71
app/lib/cam/index.d.ts vendored Normal file
View File

@ -0,0 +1,71 @@
import type { Arduino } from 'arduino';
import type { FilmOut } from 'filmout';
import type { Config } from 'cfg';
import type { WebContents } from 'electron';
interface CameraState {
pos: number;
dir: boolean;
capper: boolean;
}
/** @module lib/cam */
/**
* Class representing camera functions.
*/
export declare class Camera {
state: CameraState;
arduino: Arduino;
private intval;
private processing;
private log;
private cfg;
private filmout;
private ui;
private ipc;
private id;
/**
*
**/
constructor(arduino: Arduino, cfg: Config, ui: WebContents, filmout: FilmOut, second?: boolean);
/**
*
**/
private init;
/**
*
**/
private listen;
/**
*
**/
set(dir: boolean, id: string): Promise<number>;
/**
*
**/
cap(state: boolean, id: string): Promise<number>;
/**
*
**/
move(id: string): Promise<number>;
both(id: string): Promise<number>;
/**
*
**/
exposure(exposure: number, id: string): Promise<number>;
/**
*
**/
private connectIntval;
/**
*
**/
private connectProcessing;
/**
*
**/
private listener;
/**
*
**/
private end;
}
export {};

View File

@ -1,7 +1,15 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Camera = void 0;
const electron_1 = require("electron");
const intval_1 = require("intval");
/** class representing camera functions **/
const processing_1 = require("processing");
const delay_1 = require("delay");
const log_1 = require("log");
/** @module lib/cam */
/**
* Class representing camera functions.
*/
class Camera {
/**
*
@ -9,10 +17,13 @@ class Camera {
constructor(arduino, cfg, ui, filmout, second = false) {
this.state = {
pos: 0,
dir: true
dir: true,
capper: false
};
this.arduino = null;
this.intval = null;
this.processing = null;
this.ipc = electron_1.ipcMain;
this.id = 'camera';
this.arduino = arduino;
this.cfg = cfg;
@ -26,9 +37,7 @@ class Camera {
*
**/
async init() {
const Log = require('log');
this.log = await Log({ label: this.id });
this.ipc = require('electron').ipcMain;
this.log = await (0, log_1.Log)({ label: this.id });
this.listen();
}
/**
@ -37,6 +46,7 @@ class Camera {
listen() {
this.ipc.on(this.id, this.listener.bind(this));
this.ipc.on('intval', this.connectIntval.bind(this));
this.ipc.on('processing', this.connectProcessing.bind(this));
}
/**
*
@ -51,7 +61,15 @@ class Camera {
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
}
this.state.dir = dir;
if (this.intval) {
if (this.processing) {
try {
ms = await this.processing.setDir(dir);
}
catch (err) {
this.log.error(err);
}
}
else if (this.intval) {
try {
ms = await this.intval.setDir(dir);
}
@ -72,18 +90,47 @@ class Camera {
/**
*
**/
async move(frame, id) {
async cap(state, id) {
let cmd;
let ms;
if (state) {
cmd = this.cfg.arduino.cmd[`${this.id}_forward`];
}
else {
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
}
this.state.capper = state;
try {
ms = await this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error(err);
}
return await this.end(cmd, id, ms);
}
/**
*
**/
async move(id) {
const cmd = this.cfg.arduino.cmd[this.id];
let ms;
if (this.filmout.state.enabled) {
await this.filmout.start();
}
if (this.intval) {
if (this.processing) {
try {
ms = await this.processing.move();
}
catch (err) {
this.log.error(err);
}
}
else if (this.intval) {
try {
ms = await this.intval.move();
}
catch (err) {
this.log.error(err);
this.log.error(`Error moving intval ${this.id}: ${id}`, err);
}
}
else {
@ -101,14 +148,14 @@ class Camera {
//this.log.info('Camera move time', { ms });
return this.end(cmd, id, ms);
}
async both(frame, id) {
async both(id) {
const cmd = this.cfg.arduino.cmd[id];
let ms;
try {
ms = await this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error(`Error moving ${this.id}`, err);
this.log.error(`Error moving both ${this.id}: ${id}`, err);
}
//this.log.info('Cameras move time', { ms });
return await this.end(cmd, id, ms);
@ -116,11 +163,55 @@ class Camera {
/**
*
**/
exposure(exposure, id) {
let cmd = 'E';
this.intval.setExposure(this.id, exposure, (ms) => {
this.end(cmd, id, ms);
});
async exposure(exposure, id) {
const cmd = this.cfg.arduino.cmd.camera_exposure;
const str = `${exposure}`;
const started = +new Date();
let ms;
let confirmState;
let parts;
let confirmExposure;
if (this.intval) {
return this.intval.setExposure(exposure, (ms) => {
this.ui.send('timing', { c: 'c', ms: exposure });
return this.end(cmd, id, ms);
});
}
else if (this.arduino.hasState[this.id]) {
try {
ms = this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error('Error sending camera exposure command', err);
}
await (0, delay_1.delay)(1);
try {
ms = await this.arduino.sendString(this.id, str);
}
catch (err) {
this.log.error('Error sending camera exposure string', err);
}
await ms;
await (0, delay_1.delay)(1);
try {
confirmState = await this.arduino.state(this.id, false);
}
catch (err) {
this.log.error(`Error confirming set state`, err);
}
parts = this.arduino.stateStr[this.id].split('G');
if (parts.length > 1) {
parts = parts[1].split('H');
confirmExposure = parseInt(parts[0]);
if (!isNaN(confirmExposure)) {
this.log.info(`Exposure successfully set to ${confirmExposure}ms`);
this.ui.send('timing', { c: 'c', ms: exposure });
}
}
ms = (+new Date()) - started;
return await this.end(cmd, id, ms);
}
return 0;
}
/**
*
@ -129,6 +220,7 @@ class Camera {
return new Promise((resolve, reject) => {
if (arg.connect) {
this.intval = new intval_1.Intval(arg.url);
this.processing = null;
this.intval.connect((err, ms, state) => {
if (err) {
this.ui.send('intval', { connected: false });
@ -148,6 +240,17 @@ class Camera {
}
});
}
/**
*
**/
async connectProcessing(event, arg) {
return new Promise((resolve, reject) => {
this.processing = new processing_1.Processing(arg.url);
this.intval = null;
this.ui.send('processing', { connected: true, url: arg.url });
return resolve(true);
});
}
/**
*
**/
@ -160,9 +263,9 @@ class Camera {
this.log.error(err);
}
}
else if (typeof arg.frame !== 'undefined') {
else if (typeof arg.move !== 'undefined') {
try {
await this.move(arg.frame, arg.id);
await this.move(arg.id);
}
catch (err) {
this.log.error(err);
@ -171,6 +274,22 @@ class Camera {
else if (typeof arg.val !== 'undefined') {
this.state.pos = arg.val;
}
else if (typeof arg.capper !== 'undefined') {
try {
await this.cap(arg.capper, arg.id);
}
catch (err) {
this.log.error(err);
}
}
else if (typeof arg.exposure !== 'undefined') {
try {
await this.exposure(arg.exposure, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
@ -213,12 +332,15 @@ class Camera {
else if (cmd === this.cfg.arduino.cmd.camerass) {
message += 'Cameras both MOVED 1 frame each';
}
else if (cmd === this.cfg.arduino.camera_exposure) {
message += 'Camera set exposure';
}
message += ` ${ms}ms`;
this.log.info(message);
this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
await this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
return ms;
}
}
module.exports = function (arduino, cfg, ui, filmout, second) {
return new Camera(arduino, cfg, ui, filmout, second);
};
exports.Camera = Camera;
module.exports = { Camera };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

46
app/lib/capper/Readme.md Normal file
View File

@ -0,0 +1,46 @@
<a name="module_lib/capper"></a>
## lib/capper
* [lib/capper](#module_lib/capper)
* [~Capper](#module_lib/capper..Capper)
* [.init()](#module_lib/capper..Capper+init)
* [.listen()](#module_lib/capper..Capper+listen)
* [.capper()](#module_lib/capper..Capper+capper)
* [.listener()](#module_lib/capper..Capper+listener)
* [.end()](#module_lib/capper..Capper+end)
<a name="module_lib/capper..Capper"></a>
### lib/capper~Capper
Class representing capper functions.
**Kind**: inner class of [<code>lib/capper</code>](#module_lib/capper)
* [~Capper](#module_lib/capper..Capper)
* [.init()](#module_lib/capper..Capper+init)
* [.listen()](#module_lib/capper..Capper+listen)
* [.capper()](#module_lib/capper..Capper+capper)
* [.listener()](#module_lib/capper..Capper+listener)
* [.end()](#module_lib/capper..Capper+end)
<a name="module_lib/capper..Capper+init"></a>
#### capper.init()
**Kind**: instance method of [<code>Capper</code>](#module_lib/capper..Capper)
<a name="module_lib/capper..Capper+listen"></a>
#### capper.listen()
**Kind**: instance method of [<code>Capper</code>](#module_lib/capper..Capper)
<a name="module_lib/capper..Capper+capper"></a>
#### capper.capper()
**Kind**: instance method of [<code>Capper</code>](#module_lib/capper..Capper)
<a name="module_lib/capper..Capper+listener"></a>
#### capper.listener()
**Kind**: instance method of [<code>Capper</code>](#module_lib/capper..Capper)
<a name="module_lib/capper..Capper+end"></a>
#### capper.end()
**Kind**: instance method of [<code>Capper</code>](#module_lib/capper..Capper)

45
app/lib/capper/index.d.ts vendored Normal file
View File

@ -0,0 +1,45 @@
import type { FilmOut } from 'filmout';
import type { Arduino } from 'arduino';
import type { WebContents } from 'electron';
interface CapperState {
capper: boolean;
}
/** @module lib/capper */
/**
* Class representing capper functions.
*/
export declare class Capper {
private state;
private arduino;
private log;
private cfg;
private filmout;
private ui;
private ipc;
private id;
/**
*
**/
constructor(arduino: Arduino, cfg: any, ui: WebContents, filmout: FilmOut);
/**
*
**/
private init;
/**
*
**/
private listen;
/**
*
**/
capper(state: boolean, id: string): Promise<number>;
/**
*
**/
private listener;
/**
*
**/
private end;
}
export type { CapperState };

94
app/lib/capper/index.js Normal file
View File

@ -0,0 +1,94 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Capper = void 0;
const electron_1 = require("electron");
const log_1 = require("log");
/** @module lib/capper */
/**
* Class representing capper functions.
*/
class Capper {
/**
*
**/
constructor(arduino, cfg, ui, filmout) {
this.state = {
capper: false
};
this.arduino = null;
this.ipc = electron_1.ipcMain;
this.id = 'capper';
this.arduino = arduino;
this.cfg = cfg;
this.ui = ui;
this.filmout = filmout;
this.init();
}
/**
*
**/
async init() {
this.log = await (0, log_1.Log)({ label: this.id });
this.listen();
}
/**
*
**/
listen() {
this.ipc.on(this.id, this.listener.bind(this));
}
/**
*
**/
async capper(state, id) {
let cmd;
let ms;
if (state) {
cmd = this.cfg.arduino.cmd[`${this.id}_on`];
}
else {
cmd = this.cfg.arduino.cmd[`${this.id}_off`];
}
this.state.capper = state;
try {
ms = await this.arduino.send(this.id, cmd);
}
catch (err) {
this.log.error(err);
}
return await this.end(cmd, id, ms);
}
/**
*
**/
async listener(event, arg) {
if (typeof arg.state !== 'undefined') {
try {
await this.capper(arg.state, arg.id);
}
catch (err) {
this.log.error(err);
}
}
event.returnValue = true;
}
/**
*
**/
async end(cmd, id, ms) {
let message = '';
if (cmd === this.cfg.arduino.cmd.capper_on) {
message = 'Capper set to ON';
}
else if (cmd === this.cfg.arduino.cmd.capper_off) {
message = 'Capper set to OFF';
}
message += ` ${ms}ms`;
this.log.info(message);
await this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
return ms;
}
}
exports.Capper = Capper;
module.exports = { Capper };
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capper/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,uCAAmC;AAInC,6BAA0B;AAW1B,yBAAyB;AAEzB;;GAEG;AAEH,MAAa,MAAM;IAWlB;;QAEI;IACJ,YAAa,OAAiB,EAAE,GAAS,EAAE,EAAgB,EAAE,OAAiB;QAbtE,UAAK,GAAiB;YAC7B,MAAM,EAAG,KAAK;SACd,CAAC;QACM,YAAO,GAAa,IAAI,CAAC;QAKzB,QAAG,GAAoB,kBAAO,CAAC;QAC/B,OAAE,GAAY,QAAQ,CAAC;QAK9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,GAAG,GAAG,MAAM,IAAA,SAAG,EAAC,EAAE,KAAK,EAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC;IAED;;QAEI;IACI,MAAM;QACb,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,MAAM,CAAE,KAAe,EAAE,EAAW;QACjD,IAAI,GAAY,CAAC;QACjB,IAAI,EAAW,CAAC;QAEhB,IAAI,KAAK,EAAE;YACV,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;SAC5C;aAAM;YACN,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;SAC7C;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;QAE1B,IAAI;YACH,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;SAC3C;QAAC,OAAO,GAAG,EAAE;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACpB;QAED,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,QAAQ,CAAE,KAAoB,EAAE,GAAS;QACtD,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,WAAW,EAAE;YACrC,IAAI;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;aACrC;YAAC,OAAO,GAAG,EAAE;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aACpB;SACD;QACD,KAAK,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IAED;;QAEI;IACI,KAAK,CAAC,GAAG,CAAE,GAAY,EAAE,EAAW,EAAE,EAAW;QACxD,IAAI,OAAO,GAAY,EAAE,CAAC;QAE1B,IAAI,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;YAC3C,OAAO,GAAG,kBAAkB,CAAC;SAC7B;aAAM,IAAI,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE;YACnD,OAAO,GAAG,mBAAmB,CAAC;SAC9B;QAED,OAAO,IAAI,IAAI,EAAE,IAAI,CAAC;QAEtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAC,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACX,CAAC;CACD;AA7FD,wBA6FC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,CAAA"}

View File

@ -0,0 +1,11 @@
{
"name": "capper",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

0
app/lib/cfg/Readme.md Normal file
View File

30
app/lib/cfg/index.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
interface ConfigCommands {
[key: string]: string;
}
interface ConfigDeviceProfile {
time: number;
delay: number;
momentary: number;
}
interface ConfigBlackProfile {
before: number;
after: number;
}
interface ConfigProfile {
label: string;
cam: ConfigDeviceProfile;
proj?: ConfigDeviceProfile;
black?: ConfigBlackProfile;
light: boolean;
}
interface ConfigProfiles {
[key: string]: ConfigProfile;
}
interface Config {
version: string;
ext_port: number;
profiles: ConfigProfiles;
cmd: ConfigCommands;
arduino: any;
}
export type { Config };

3
app/lib/cfg/index.js Normal file
View File

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=index.js.map

1
app/lib/cfg/index.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cfg/index.ts"],"names":[],"mappings":""}

287
app/lib/client/index.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,267 @@
<a name="module_lib/cmd"></a>
## lib/cmd
* [lib/cmd](#module_lib/cmd)
* [~Assign all connected devices and mock devices as private classes.](#module_lib/cmd..Assign all connected devices and mock devices as private classes.)
* [new Assign all connected devices and mock devices as private classes.(cfg, proj, cam, light, alert, cam2, proj2, capper)](#new_module_lib/cmd..Assign all connected devices and mock devices as private classes._new)
* [~Commands](#module_lib/cmd..Commands)
* [.projector_forward()](#module_lib/cmd..Commands+projector_forward) ⇒ <code>integer</code>
* [.projector_backward()](#module_lib/cmd..Commands+projector_backward) ⇒ <code>integer</code>
* [.camera_forward(cmd)](#module_lib/cmd..Commands+camera_forward) ⇒ <code>integer</code>
* [.black_forward()](#module_lib/cmd..Commands+black_forward) ⇒ <code>integer</code>
* [.camera_backward(cmd)](#module_lib/cmd..Commands+camera_backward) ⇒ <code>integer</code>
* [.black_backward()](#module_lib/cmd..Commands+black_backward) ⇒ <code>integer</code>
* [.camera_second_forward(cmd)](#module_lib/cmd..Commands+camera_second_forward) ⇒ <code>integer</code>
* [.camera_second_backward(cmd)](#module_lib/cmd..Commands+camera_second_backward) ⇒ <code>integer</code>
* [.cameras_forward(cmd)](#module_lib/cmd..Commands+cameras_forward) ⇒ <code>integer</code>
* [.cameras_backward(cmd)](#module_lib/cmd..Commands+cameras_backward) ⇒ <code>integer</code>
* [.camera_forward_camera_second_backward(cmd)](#module_lib/cmd..Commands+camera_forward_camera_second_backward) ⇒ <code>integer</code>
* [.camera_backward_camera_second_forward(cmd)](#module_lib/cmd..Commands+camera_backward_camera_second_forward) ⇒ <code>integer</code>
* [.projector_second_forward()](#module_lib/cmd..Commands+projector_second_forward) ⇒ <code>integer</code>
* [.projector_second_backward()](#module_lib/cmd..Commands+projector_second_backward) ⇒ <code>integer</code>
* [.projectors_forward()](#module_lib/cmd..Commands+projectors_forward) ⇒ <code>integer</code>
* [.projectors_backward()](#module_lib/cmd..Commands+projectors_backward) ⇒ <code>integer</code>
* [.projector_forward_projector_second_backward()](#module_lib/cmd..Commands+projector_forward_projector_second_backward) ⇒ <code>integer</code>
* [.projector_backward_projector_second_forward()](#module_lib/cmd..Commands+projector_backward_projector_second_forward) ⇒ <code>integer</code>
* [.alert()](#module_lib/cmd..Commands+alert) ⇒ <code>integer</code>
* [.pause()](#module_lib/cmd..Commands+pause) ⇒ <code>integer</code>
* [.camera_exposure()](#module_lib/cmd..Commands+camera_exposure)
<a name="module_lib/cmd..Assign all connected devices and mock devices as private classes."></a>
### lib/cmd~Assign all connected devices and mock devices as private classes.
**Kind**: inner class of [<code>lib/cmd</code>](#module_lib/cmd)
<a name="new_module_lib/cmd..Assign all connected devices and mock devices as private classes._new"></a>
#### new Assign all connected devices and mock devices as private classes.(cfg, proj, cam, light, alert, cam2, proj2, capper)
| Param | Type | Description |
| --- | --- | --- |
| cfg | <code>object</code> | Configuration object |
| proj | <code>object</code> | Projector 1 |
| cam | <code>object</code> | Camera 1 |
| light | <code>object</code> | Light source |
| alert | <code>object</code> | Alert object |
| cam2 | <code>object</code> | (optional) Camera 2 |
| proj2 | <code>object</code> | (optional) Projector 2 |
| capper | <code>object</code> | Capper object |
<a name="module_lib/cmd..Commands"></a>
### lib/cmd~Commands
Class representing all commands bundled into methods.
**Kind**: inner class of [<code>lib/cmd</code>](#module_lib/cmd)
* [~Commands](#module_lib/cmd..Commands)
* [.projector_forward()](#module_lib/cmd..Commands+projector_forward) ⇒ <code>integer</code>
* [.projector_backward()](#module_lib/cmd..Commands+projector_backward) ⇒ <code>integer</code>
* [.camera_forward(cmd)](#module_lib/cmd..Commands+camera_forward) ⇒ <code>integer</code>
* [.black_forward()](#module_lib/cmd..Commands+black_forward) ⇒ <code>integer</code>
* [.camera_backward(cmd)](#module_lib/cmd..Commands+camera_backward) ⇒ <code>integer</code>
* [.black_backward()](#module_lib/cmd..Commands+black_backward) ⇒ <code>integer</code>
* [.camera_second_forward(cmd)](#module_lib/cmd..Commands+camera_second_forward) ⇒ <code>integer</code>
* [.camera_second_backward(cmd)](#module_lib/cmd..Commands+camera_second_backward) ⇒ <code>integer</code>
* [.cameras_forward(cmd)](#module_lib/cmd..Commands+cameras_forward) ⇒ <code>integer</code>
* [.cameras_backward(cmd)](#module_lib/cmd..Commands+cameras_backward) ⇒ <code>integer</code>
* [.camera_forward_camera_second_backward(cmd)](#module_lib/cmd..Commands+camera_forward_camera_second_backward) ⇒ <code>integer</code>
* [.camera_backward_camera_second_forward(cmd)](#module_lib/cmd..Commands+camera_backward_camera_second_forward) ⇒ <code>integer</code>
* [.projector_second_forward()](#module_lib/cmd..Commands+projector_second_forward) ⇒ <code>integer</code>
* [.projector_second_backward()](#module_lib/cmd..Commands+projector_second_backward) ⇒ <code>integer</code>
* [.projectors_forward()](#module_lib/cmd..Commands+projectors_forward) ⇒ <code>integer</code>
* [.projectors_backward()](#module_lib/cmd..Commands+projectors_backward) ⇒ <code>integer</code>
* [.projector_forward_projector_second_backward()](#module_lib/cmd..Commands+projector_forward_projector_second_backward) ⇒ <code>integer</code>
* [.projector_backward_projector_second_forward()](#module_lib/cmd..Commands+projector_backward_projector_second_forward) ⇒ <code>integer</code>
* [.alert()](#module_lib/cmd..Commands+alert) ⇒ <code>integer</code>
* [.pause()](#module_lib/cmd..Commands+pause) ⇒ <code>integer</code>
* [.camera_exposure()](#module_lib/cmd..Commands+camera_exposure)
<a name="module_lib/cmd..Commands+projector_forward"></a>
#### commands.projector\_forward() ⇒ <code>integer</code>
Move the projector one frame forward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projector_backward"></a>
#### commands.projector\_backward() ⇒ <code>integer</code>
Move the projector one frame backward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+camera_forward"></a>
#### commands.camera\_forward(cmd) ⇒ <code>integer</code>
Move the camera one frame forward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+black_forward"></a>
#### commands.black\_forward() ⇒ <code>integer</code>
Move the camera one frame forward with light off
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+camera_backward"></a>
#### commands.camera\_backward(cmd) ⇒ <code>integer</code>
Move the camera one frame backward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+black_backward"></a>
#### commands.black\_backward() ⇒ <code>integer</code>
Move the camera one frame forward, light set to black or off
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+camera_second_forward"></a>
#### commands.camera\_second\_forward(cmd) ⇒ <code>integer</code>
Move the second camera one frame forward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+camera_second_backward"></a>
#### commands.camera\_second\_backward(cmd) ⇒ <code>integer</code>
Move the second camera one frame backward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+cameras_forward"></a>
#### commands.cameras\_forward(cmd) ⇒ <code>integer</code>
Move the both cameras one frame forward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+cameras_backward"></a>
#### commands.cameras\_backward(cmd) ⇒ <code>integer</code>
Move the both cameras one frame backward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+camera_forward_camera_second_backward"></a>
#### commands.camera\_forward\_camera\_second\_backward(cmd) ⇒ <code>integer</code>
Move first camera one frame forward and rewind secondary camera one frame backward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+camera_backward_camera_second_forward"></a>
#### commands.camera\_backward\_camera\_second\_forward(cmd) ⇒ <code>integer</code>
Rewind first camera one frame backward and move secondary camera one frame forward
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
| Param | Type | Description |
| --- | --- | --- |
| cmd | <code>object</code> | Full cmd object |
<a name="module_lib/cmd..Commands+projector_second_forward"></a>
#### commands.projector\_second\_forward() ⇒ <code>integer</code>
Move the secondary projector forward one frame
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projector_second_backward"></a>
#### commands.projector\_second\_backward() ⇒ <code>integer</code>
Rewind the secondary projector backward one frame
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projectors_forward"></a>
#### commands.projectors\_forward() ⇒ <code>integer</code>
Move the both projectors forward one frame
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projectors_backward"></a>
#### commands.projectors\_backward() ⇒ <code>integer</code>
Rewind both projectors backwards one frame
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projector_forward_projector_second_backward"></a>
#### commands.projector\_forward\_projector\_second\_backward() ⇒ <code>integer</code>
Move the primary projector forward one frame and rewind the secondary projector
one frame backwards.
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+projector_backward_projector_second_forward"></a>
#### commands.projector\_backward\_projector\_second\_forward() ⇒ <code>integer</code>
Rewind the primary projector backwards one frame and move the secondary
projector forward one frame.
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+alert"></a>
#### commands.alert() ⇒ <code>integer</code>
Throws an alert to pause a sequence
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+pause"></a>
#### commands.pause() ⇒ <code>integer</code>
Pauses a sequence for a length of time
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)
**Returns**: <code>integer</code> - Length of action in ms
<a name="module_lib/cmd..Commands+camera_exposure"></a>
#### commands.camera\_exposure()
Sets the camera exposure (if supported).
**Kind**: instance method of [<code>Commands</code>](#module_lib/cmd..Commands)

179
app/lib/cmd/index.d.ts vendored Normal file
View File

@ -0,0 +1,179 @@
import type { Projector } from 'proj';
import type { Camera } from 'cam';
import type { Light } from 'light';
import type { Capper } from 'capper';
import type { Alert } from 'alert';
import type { Config } from 'cfg';
/** @module lib/cmd */
/**
* Class representing all commands bundled into methods.
*/
export declare class Commands {
proj: Projector;
cam: Camera;
light: Light;
cam2: Camera;
proj2: Projector;
capper: Capper;
alertObj: Alert;
private cfg;
private ipc;
/**
* @constructor
* Assign all connected devices and mock devices as private classes.
*
* @param {object} cfg Configuration object
* @param {object} proj Projector 1
* @param {object} cam Camera 1
* @param {object} light Light source
* @param {object} alert Alert object
* @param {object} cam2 (optional) Camera 2
* @param {object} proj2 (optional) Projector 2
* @param {object} capper Capper object
*
**/
constructor(cfg: Config, proj: Projector, cam: Camera, light: Light, alert: Alert, cam2?: Camera, proj2?: Projector, capper?: Capper);
/**
* Move the projector one frame forward
*
* @returns {integer} Length of action in ms
**/
projector_forward(): Promise<number>;
/**
* Move the projector one frame backward
*
* @returns {integer} Length of action in ms
**/
projector_backward(): Promise<number>;
/**
* Move the camera one frame forward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_forward(): Promise<number>;
/**
* Move the camera one frame forward with light off
*
* @returns {integer} Length of action in ms
**/
black_forward(): Promise<number>;
/**
* Move the camera one frame backward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_backward(): Promise<number>;
/**
* Move the camera one frame forward, light set to black or off
*
* @returns {integer} Length of action in ms
**/
black_backward(): Promise<number>;
/**
* Move the second camera one frame forward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_second_forward(): Promise<number>;
/**
* Move the second camera one frame backward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_second_backward(): Promise<number>;
/**
* Move the both cameras one frame forward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
cameras_forward(): Promise<number>;
/**
* Move the both cameras one frame backward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
cameras_backward(): Promise<number>;
/**
* Move first camera one frame forward and rewind secondary camera one frame backward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_forward_camera_second_backward(): Promise<number>;
/**
* Rewind first camera one frame backward and move secondary camera one frame forward
*
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
camera_backward_camera_second_forward(): Promise<number>;
/**
* Move the secondary projector forward one frame
*
* @returns {integer} Length of action in ms
**/
projector_second_forward(): Promise<number>;
/**
* Rewind the secondary projector backward one frame
*
* @returns {integer} Length of action in ms
**/
projector_second_backward(): Promise<number>;
/**
* Move the both projectors forward one frame
*
* @returns {integer} Length of action in ms
**/
projectors_forward(): Promise<number>;
/**
* Rewind both projectors backwards one frame
*
* @returns {integer} Length of action in ms
**/
projectors_backward(): Promise<number>;
/**
* Move the primary projector forward one frame and rewind the secondary projector
* one frame backwards.
*
* @returns {integer} Length of action in ms
**/
projector_forward_projector_second_backward(): Promise<number>;
/**
* Rewind the primary projector backwards one frame and move the secondary
* projector forward one frame.
*
* @returns {integer} Length of action in ms
**/
projector_backward_projector_second_forward(): Promise<number>;
/**
* Throws an alert to pause a sequence
*
* @returns {integer} Length of action in ms
**/
alert(cmd: any): Promise<number>;
/**
* Pauses a sequence for a length of time
*
* @returns {integer} Length of action in ms
**/
pause(cmd: any): Promise<number>;
/**
* Sets the camera exposure (if supported).
*
**/
camera_exposure(cmd: any): Promise<number>;
}

View File

@ -1,7 +1,13 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Commands = void 0;
const electron_1 = require("electron");
const uuid_1 = require("uuid");
const delay_1 = require("delay");
/** @module lib/cmd */
/**
* Class representing all commands bundled into methods.
*/
class Commands {
/**
* @constructor
@ -11,19 +17,25 @@ class Commands {
* @param {object} proj Projector 1
* @param {object} cam Camera 1
* @param {object} light Light source
* @param {object} alert Alert object
* @param {object} cam2 (optional) Camera 2
* @param {object} proj2 {optional} Projector 2
* @param {object} proj2 (optional) Projector 2
* @param {object} capper Capper object
*
**/
constructor(cfg, proj, cam, light, cam2 = null, proj2 = null) {
constructor(cfg, proj, cam, light, alert, cam2 = null, proj2 = null, capper = null) {
this.ipc = electron_1.ipcMain;
this.cfg = cfg;
this.proj = proj;
this.cam = cam;
this.light = light;
if (cam2)
this.alertObj = alert;
if (cam2 !== null)
this.cam2 = cam2;
if (proj2)
if (proj2 !== null)
this.proj2 = proj2;
this.ipc = require('electron').ipcMain;
if (capper !== null)
this.capper = capper;
}
/**
* Move the projector one frame forward
@ -31,14 +43,15 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_forward() {
const id = (0, uuid_1.v4)();
let ms;
try {
if (!this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.proj.move();
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.proj.move(id);
}
catch (err) {
throw err;
@ -51,14 +64,15 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_backward() {
const id = (0, uuid_1.v4)();
let ms;
try {
if (this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.proj.move();
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.proj.move(id);
}
catch (err) {
throw err;
@ -68,24 +82,25 @@ class Commands {
/**
* Move the camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_forward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_forward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (!this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.cam.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -99,20 +114,27 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async black_forward() {
const id = uuid_1.v4();
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let ms;
let ms = 0;
try {
if (!this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.capper) {
ms += await this.capper.capper(true, id);
}
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id); //make sure set to off
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms += await this.cam.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
if (this.capper) {
ms += await this.capper.capper(false, id);
}
}
catch (err) {
throw err;
@ -122,24 +144,25 @@ class Commands {
/**
* Move the camera one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_backward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_backward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.cam.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -153,20 +176,26 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async black_backward() {
const id = uuid_1.v4();
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let ms;
let ms = 0;
try {
if (this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
if (this.capper) {
ms += await this.capper.capper(true, id);
}
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id); //make sure set to off
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms += await this.cam.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
if (this.capper) {
ms += await this.capper.capper(false, id);
}
}
catch (err) {
throw err;
@ -176,24 +205,25 @@ class Commands {
/**
* Move the second camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_second_forward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_second_forward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (!this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam2.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.cam2.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -204,24 +234,25 @@ class Commands {
/**
* Move the second camera one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_second_backward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_second_backward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let ms;
try {
if (this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.cam2.move();
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.cam2.move(id);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -232,37 +263,36 @@ class Commands {
/**
* Move the both cameras one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async cameras_forward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async cameras_forward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
if (!this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(true, id);
}
if (!this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
ms = await this.cam.both();
ms = await this.cam.both(id);
}
else {
this.cam.move();
this.cam2.move();
both = [await this.cam.move, await this.cam2.move];
both = await Promise.all([this.cam.move(id), this.cam2.move(id)]);
ms = Math.max(...both);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -273,37 +303,36 @@ class Commands {
/**
* Move the both cameras one frame backward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async cameras_backward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async cameras_backward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
if (this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(false, id);
}
if (this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
ms = await this.cam.both();
ms = await this.cam.both(id);
}
else {
this.cam.move();
this.cam2.move();
both = [await this.cam.move, await this.cam2.move];
both = await Promise.all([this.cam.move(id), this.cam2.move(id)]);
ms = Math.max(...both);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -314,37 +343,36 @@ class Commands {
/**
* Move first camera one frame forward and rewind secondary camera one frame backward
*
* @param {array} rgb Color to set light for frames
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_forward_camera_second_backward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_forward_camera_second_backward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
if (!this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(true, id);
}
if (this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
ms = await this.cam.both();
ms = await this.cam.both(id);
}
else {
this.cam.move();
this.cam2.move();
both = [await this.cam.move, await this.cam2.move];
both = await Promise.all([this.cam.move(id), this.cam2.move(id)]);
ms = Math.max(...both);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -355,37 +383,36 @@ class Commands {
/**
* Rewind first camera one frame backward and move secondary camera one frame forward
*
* @param {array} rgb Color to set light for frame
* @param {object} cmd Full cmd object
*
* @returns {integer} Length of action in ms
**/
async camera_backward_camera_second_forward(rgb = [255, 255, 255]) {
const id = uuid_1.v4();
async camera_backward_camera_second_forward() {
const id = (0, uuid_1.v4)();
const off = [0, 0, 0];
let rgb = [255, 255, 255];
let both;
let ms;
try {
if (this.cam.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam.set(false, id);
}
if (!this.cam2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.cam2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.cam2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(rgb, id);
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
ms = await this.cam.both();
ms = await this.cam.both(id);
}
else {
this.cam.move();
this.cam.move();
both = [await this.cam.move, await this.proj2.move];
both = await Promise.all([this.cam.move(id), this.cam2.move(id)]);
ms = Math.max(...both);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.light.set(off, id);
}
catch (err) {
@ -399,14 +426,15 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_second_forward() {
const id = (0, uuid_1.v4)();
let ms;
try {
if (!this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.proj2.move();
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.proj2.move(id);
}
catch (err) {
throw err;
@ -419,14 +447,15 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_second_backward() {
const id = (0, uuid_1.v4)();
let ms;
try {
if (this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
ms = await this.proj2.move();
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
ms = await this.proj2.move(id);
}
catch (err) {
throw err;
@ -439,25 +468,24 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projectors_forward() {
const id = (0, uuid_1.v4)();
let both;
let ms;
try {
if (!this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(true, id);
}
if (!this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
ms = await this.proj.both();
ms = await this.proj.both(id);
}
else {
this.proj.move();
this.proj2.move();
both = [await this.proj.move, await this.proj2.move];
both = await Promise.all([this.proj.move(id), this.proj2.move(id)]);
ms = Math.max(...both);
}
}
@ -472,26 +500,24 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projectors_backward() {
const id = (0, uuid_1.v4)();
let both;
let ms;
try {
if (this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(false, id);
}
if (this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
//run one projector without await?
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
ms = await this.proj.both();
ms = await this.proj.both(id);
}
else {
this.proj.move();
this.proj2.move();
both = [await this.proj.move, await this.proj2.move];
both = await Promise.all([this.proj.move(id), this.proj2.move(id)]);
ms = Math.max(...both);
}
}
@ -507,26 +533,24 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_forward_projector_second_backward() {
const id = (0, uuid_1.v4)();
let both;
let ms;
try {
if (!this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(true, id);
}
if (this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(false, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
//run one projector without await?
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
ms = await this.proj.both();
ms = await this.proj.both(id);
}
else {
this.proj.move();
this.proj2.move();
both = [await this.proj.move, await this.proj2.move];
both = await Promise.all([this.proj.move(id), this.proj2.move(id)]);
ms = Math.max(...both);
}
}
@ -542,26 +566,24 @@ class Commands {
* @returns {integer} Length of action in ms
**/
async projector_backward_projector_second_forward() {
const id = (0, uuid_1.v4)();
let both;
let ms;
try {
if (this.proj.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj.set(false);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj.set(false, id);
}
if (!this.proj2.state.dir) {
await delay_1.delay(this.cfg.arduino.serialDelay);
await this.proj2.set(true);
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
await this.proj2.set(true, id);
}
await delay_1.delay(this.cfg.arduino.serialDelay);
//run one projector without await?
await (0, delay_1.delay)(this.cfg.arduino.serialDelay);
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
ms = await this.proj.both();
ms = await this.proj.both(id);
}
else {
this.proj.move();
this.proj2.move();
both = [await this.proj.move, await this.proj2.move];
both = await Promise.all([this.proj.move(id), this.proj2.move(id)]);
ms = Math.max(...both);
}
}
@ -570,8 +592,54 @@ class Commands {
}
return ms;
}
/**
* Throws an alert to pause a sequence
*
* @returns {integer} Length of action in ms
**/
async alert(cmd) {
const id = (0, uuid_1.v4)();
let ms;
try {
ms = await this.alertObj.start(cmd.light); //change this meta
}
catch (err) {
throw err;
}
return ms;
}
/**
* Pauses a sequence for a length of time
*
* @returns {integer} Length of action in ms
**/
async pause(cmd) {
const id = (0, uuid_1.v4)();
let ms;
try {
ms = await (0, delay_1.delay)(cmd.light * 1000); //delay is in seconds
}
catch (err) {
throw err;
}
return ms;
}
/**
* Sets the camera exposure (if supported).
*
**/
async camera_exposure(cmd) {
const id = (0, uuid_1.v4)();
let ms;
try {
ms = await this.cam.exposure(cmd.light, id);
}
catch (err) {
throw err;
}
return ms;
}
}
module.exports = function (cfg, proj, cam, light, cam2, proj2) {
return new Commands(cfg, proj, cam, light, cam2, proj2);
};
exports.Commands = Commands;
module.exports = { Commands };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

8
app/lib/delay/index.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Delay in an async/await function
*
* @param {integer} ms Milliseconds to delay for
*
* @returns {Promise} Promise to resolve after timeout
**/
export declare function delay(ms: number): Promise<number>;

View File

@ -1,4 +1,6 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.delay = void 0;
/**
* Delay in an async/await function
*
@ -8,8 +10,9 @@
**/
function delay(ms) {
return new Promise((resolve) => {
return setTimeout(resolve, ms);
return setTimeout(() => { resolve(ms); }, ms);
});
}
module.exports.delay = delay;
exports.delay = delay;
module.exports = { delay };
//# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,KAAK,CAAE,EAAW;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAa,EAAE,EAAE;QACpC,OAAO,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb;;;;;;IAMI;AAEJ,SAAgB,KAAK,CAAE,EAAW;IACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAa,EAAE,EAAE;QACpC,OAAO,UAAU,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACJ,CAAC;AAJD,sBAIC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}

View File

@ -1,74 +1,116 @@
<a name="Devices"></a>
<a name="module_lib/devices"></a>
## Devices
class representing the device discovery features
## lib/devices
**Kind**: global class
* [lib/devices](#module_lib/devices)
* [~Devices](#module_lib/devices..Devices)
* [new Devices()](#new_module_lib/devices..Devices_new)
* [.init()](#module_lib/devices..Devices+init)
* [.listen()](#module_lib/devices..Devices+listen)
* [.listener()](#module_lib/devices..Devices+listener)
* [.enumerate()](#module_lib/devices..Devices+enumerate)
* [.favor()](#module_lib/devices..Devices+favor)
* [.distinguish()](#module_lib/devices..Devices+distinguish)
* [.fakeProjector()](#module_lib/devices..Devices+fakeProjector)
* [.fakeCamera()](#module_lib/devices..Devices+fakeCamera)
* [.fakeLight()](#module_lib/devices..Devices+fakeLight)
* [.fakeCapper()](#module_lib/devices..Devices+fakeCapper)
* [.connectDevice()](#module_lib/devices..Devices+connectDevice)
* [.all()](#module_lib/devices..Devices+all)
* [.remember()](#module_lib/devices..Devices+remember)
* [.ready()](#module_lib/devices..Devices+ready)
* [Devices](#Devices)
* [.init()](#Devices+init)
* [.listen()](#Devices+listen)
* [.listener()](#Devices+listener)
* [.enumerate()](#Devices+enumerate)
* [.favor()](#Devices+favor)
* [.distinguish()](#Devices+distinguish)
* [.fakeProjector()](#Devices+fakeProjector)
* [.fakeCamera()](#Devices+fakeCamera)
* [.fakeLight()](#Devices+fakeLight)
* [.connectDevice()](#Devices+connectDevice)
* [.all()](#Devices+all)
* [.remember()](#Devices+remember)
* [.ready()](#Devices+ready)
<a name="module_lib/devices..Devices"></a>
<a name="Devices+init"></a>
### lib/devices~Devices
Class representing the device discovery features.
### devices.init()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+listen"></a>
**Kind**: inner class of [<code>lib/devices</code>](#module_lib/devices)
### devices.listen()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+listener"></a>
* [~Devices](#module_lib/devices..Devices)
* [new Devices()](#new_module_lib/devices..Devices_new)
* [.init()](#module_lib/devices..Devices+init)
* [.listen()](#module_lib/devices..Devices+listen)
* [.listener()](#module_lib/devices..Devices+listener)
* [.enumerate()](#module_lib/devices..Devices+enumerate)
* [.favor()](#module_lib/devices..Devices+favor)
* [.distinguish()](#module_lib/devices..Devices+distinguish)
* [.fakeProjector()](#module_lib/devices..Devices+fakeProjector)
* [.fakeCamera()](#module_lib/devices..Devices+fakeCamera)
* [.fakeLight()](#module_lib/devices..Devices+fakeLight)
* [.fakeCapper()](#module_lib/devices..Devices+fakeCapper)
* [.connectDevice()](#module_lib/devices..Devices+connectDevice)
* [.all()](#module_lib/devices..Devices+all)
* [.remember()](#module_lib/devices..Devices+remember)
* [.ready()](#module_lib/devices..Devices+ready)
### devices.listener()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+enumerate"></a>
<a name="new_module_lib/devices..Devices_new"></a>
### devices.enumerate()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+favor"></a>
#### new Devices()
Constructor assigns arduino, settings, UI browser window and cam objects
locally to this class for reference.
### devices.favor()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+distinguish"></a>
<a name="module_lib/devices..Devices+init"></a>
### devices.distinguish()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+fakeProjector"></a>
#### devices.init()
Initialize the log for "devices". Establish an ipc connection to the UI.
Start listening on that ipc connection.
### devices.fakeProjector()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+fakeCamera"></a>
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+listen"></a>
### devices.fakeCamera()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+fakeLight"></a>
#### devices.listen()
Listen to the "profile" channel for messages from the UI.
### devices.fakeLight()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+connectDevice"></a>
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+listener"></a>
### devices.connectDevice()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+all"></a>
#### devices.listener()
The "profile" channel callback. If a profile is changed, set it in the
local settings object.
### devices.all()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+remember"></a>
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+enumerate"></a>
### devices.remember()
**Kind**: instance method of [<code>Devices</code>](#Devices)
<a name="Devices+ready"></a>
#### devices.enumerate()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+favor"></a>
### devices.ready()
**Kind**: instance method of [<code>Devices</code>](#Devices)
#### devices.favor()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+distinguish"></a>
#### devices.distinguish()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+fakeProjector"></a>
#### devices.fakeProjector()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+fakeCamera"></a>
#### devices.fakeCamera()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+fakeLight"></a>
#### devices.fakeLight()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+fakeCapper"></a>
#### devices.fakeCapper()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+connectDevice"></a>
#### devices.connectDevice()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+all"></a>
#### devices.all()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+remember"></a>
#### devices.remember()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)
<a name="module_lib/devices..Devices+ready"></a>
#### devices.ready()
**Kind**: instance method of [<code>Devices</code>](#module_lib/devices..Devices)

84
app/lib/devices/index.d.ts vendored Normal file
View File

@ -0,0 +1,84 @@
import type { Settings } from 'settings';
import type { Arduino } from 'arduino';
import type { BrowserWindow } from 'electron';
interface Device {
serial: string;
device: string;
}
/** @module lib/devices */
/**
* Class representing the device discovery features.
*/
export declare class Devices {
settings: Settings;
connected: any;
private arduino;
private log;
private ui;
private ipc;
private mainWindow;
/**
* Constructor assigns arduino, settings, UI browser window and cam objects
* locally to this class for reference.
**/
constructor(arduino: Arduino, settings: Settings, mainWindow: BrowserWindow);
/**
* Initialize the log for "devices". Establish an ipc connection to the UI.
* Start listening on that ipc connection.
**/
private init;
/**
* Listen to the "profile" channel for messages from the UI.
**/
private listen;
/**
* The "profile" channel callback. If a profile is changed, set it in the
* local settings object.
**/
private listener;
/**
*
**/
enumerate(): Promise<boolean>;
/**
*
**/
private favor;
/**
*
**/
private distinguish;
/**
*
**/
private fakeProjector;
/**
*
**/
private fakeCamera;
/**
*
**/
private fakeLight;
/**
*
**/
private fakeCapper;
/**
*
**/
private connectDevice;
/**
*
**/
private all;
/**
*
**/
private remember;
/**
*
**/
private ready;
}
export type { Device };

View File

@ -1,24 +1,25 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Devices = void 0;
const electron_1 = require("electron");
const delay_1 = require("delay");
const Log = require("log");
const log_1 = require("log");
/** @module lib/devices */
/**
* class representing the device discovery features
*
*
**/
* Class representing the device discovery features.
*/
class Devices {
/**
* Constructor assigns arduino, settings, UI browser window and cam objects
* locally to this class for reference.
**/
constructor(arduino, settings, mainWindow, cam) {
constructor(arduino, settings, mainWindow) {
this.connected = {};
this.ipc = electron_1.ipcMain;
this.arduino = arduino;
this.settings = settings;
this.mainWindow = mainWindow;
this.ui = this.mainWindow.webContents;
this.cam = cam;
this.init();
}
/**
@ -26,57 +27,64 @@ class Devices {
* Start listening on that ipc connection.
**/
async init() {
this.log = await Log({ label: 'devices' });
this.ipc = require('electron').ipcMain;
this.log = await (0, log_1.Log)({ label: 'devices' });
this.listen();
}
/**
* Listen to the "profile" channel for messages from the UI.
**/
listen() {
this.ipc.on('profile', this.listener.bind(this));
this.ipc.handle('profile', this.listener.bind(this));
}
/**
* The "profile" channel callback. If a profile is changed, set it in the
* local settings object.
**/
listener(event, arg) {
this.log.info(`Saving profile ${arg.profile}`, 'SETTINGS', false, false);
this.settings.update('profile', arg.profile);
this.settings.save();
async listener(event, arg) {
if (typeof arg.profile !== 'undefined') {
this.log.info(`Saving profile ${arg.profile}`, 'SETTINGS', false, false);
this.settings.update('profile', arg.profile);
await this.settings.save();
}
if (typeof arg.timing !== 'undefined') {
this.log.info(`Saving timing info`, 'SETTINGS', false, false);
this.settings.update('timing', arg.timing);
await this.settings.save();
}
return true;
}
/**
*
**/
async enumerate() {
let devices;
let serials;
try {
devices = await this.arduino.enumerate();
serials = await this.arduino.enumerate();
}
catch (err) {
this.log.warn(err, 'SERIAL', false, true);
await delay_1.delay(1000);
await (0, delay_1.delay)(1000);
return this.all([]);
}
this.log.info(`Found ${devices.length} USB devices`, 'SERIAL', true, true);
devices = this.favor(devices);
return await this.all(devices);
this.log.info(`Found ${serials.length} USB devices`, 'SERIAL', true, true);
serials = this.favor(serials);
return await this.all(serials);
}
/**
*
**/
favor(devices) {
favor(serials) {
const past = this.settings.state.devices.filter((device) => {
if (device.arduino) {
if (device.serial) {
return device;
}
}).map((device) => {
return device.arduino;
return device.serial;
});
if (past.length === 0) {
return devices;
return serials;
}
devices.sort((a, b) => {
serials.sort((a, b) => {
if (past.indexOf(a) !== -1 && past.indexOf(b) === -1) {
return 1;
}
@ -85,23 +93,24 @@ class Devices {
}
return 0;
});
return devices;
return serials;
}
/**
*
**/
async distinguish(device) {
async distinguish(serial) {
let connectSuccess;
let verifySuccess;
let type;
let device;
//this.log.info(`distinguish() ${serial}`)
try {
connectSuccess = await this.arduino.connect('connect', device, true);
connectSuccess = await this.arduino.connect('connect', serial, true);
}
catch (err) {
this.log.error('Error connecting', err);
return null;
}
await delay_1.delay(2000);
await (0, delay_1.delay)(2000);
try {
verifySuccess = await this.arduino.verify();
}
@ -109,18 +118,25 @@ class Devices {
this.log.error('Error verifying device', err);
return null;
}
this.log.info(`Verified ${device} as mcopy device`, 'SERIAL', true, true);
await delay_1.delay(1000);
this.log.info(`Verified ${serial} as mcopy device`, 'SERIAL', true, true);
await (0, delay_1.delay)(1000);
try {
type = await this.arduino.distinguish();
device = await this.arduino.distinguish();
}
catch (err) {
this.log.error('Error distinguishing device', err);
return null;
}
this.remember('arduino', device, type);
this.log.info(`Determined ${device} to be ${type}`, 'SERIAL', true, true);
return type;
this.remember(device, serial, 'arduino');
this.log.info(`Determined ${device} to be ${device}`, 'SERIAL', true, true);
await (0, delay_1.delay)(100);
try {
await this.arduino.state(device, true);
}
catch (err) {
this.log.error('Error checking state capability', err);
}
return device;
}
/**
*
@ -131,24 +147,24 @@ class Devices {
await this.arduino.fakeConnect('projector');
}
catch (err) {
console.error(err);
this.log.error(`Error connecting to fake PRONECTOR device`, 'SERIAL', true, true);
this.log.error(`Error connecting to fake PROjECTOR device`, 'SERIAL', true, true);
this.log.error(err);
return false;
}
this.log.info('Connected to fake PROJECTOR device', 'SERIAL', true, true);
return true;
}
/**
*
**/
*
**/
async fakeCamera() {
this.connected.camera = '/dev/fake';
try {
await this.arduino.fakeConnect('camera');
}
catch (err) {
console.error(err);
this.log.error(`Error connecting to fake CAMERA device`, 'SERIAL', true, true);
this.log.error(err);
return false;
}
this.log.info('Connected to fake CAMERA device', 'SERIAL', true, true);
@ -163,17 +179,33 @@ class Devices {
await this.arduino.fakeConnect('light');
}
catch (err) {
console.error(err);
this.log.error(`Error connecting to fake LIGHT device`, 'SERIAL', true, true);
this.log.error(err);
return false;
}
this.log.info('Connected to fake LIGHT device', 'SERIAL', true, true);
return true;
}
/**
*
**/
async connectDevice(device, type) {
*
**/
async fakeCapper() {
this.connected.capper = '/dev/fake';
try {
await this.arduino.fakeConnect('capper');
}
catch (err) {
this.log.error(`Error connecting to fake CAPPER device`, 'SERIAL', true, true);
this.log.error(err);
return false;
}
this.log.info('Connected to fake CAPPER device', 'SERIAL', true, true);
return true;
}
/**
*
**/
async connectDevice(device, serial) {
let closeSuccess;
let connectSuccess;
try {
@ -183,10 +215,10 @@ class Devices {
this.log.error('Error closing arduino connection', err);
return false;
}
if (type === 'projector') {
this.connected.projector = device;
if (device === 'projector') {
this.connected.projector = serial;
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector', err);
@ -194,10 +226,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR`, 'SERIAL', true, true);
}
else if (type === 'camera') {
this.connected.camera = device;
else if (device === 'camera') {
this.connected.camera = serial;
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera', err);
@ -205,10 +237,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as CAMERA`, 'SERIAL', true, true);
}
else if (type === 'light') {
this.connected.light = device;
else if (device === 'light') {
this.connected.light = serial;
try {
connectSuccess = await this.arduino.connect('light', device, false);
connectSuccess = await this.arduino.connect('light', serial, false);
}
catch (err) {
this.log.error('Error connecting to light', err);
@ -216,12 +248,12 @@ class Devices {
}
this.log.info(`Connected to ${device} as LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,light') {
this.connected.projector = device;
this.connected.light = device;
this.arduino.aliasSerial('light', device);
else if (device === 'projector,light') {
this.connected.projector = serial;
this.connected.light = serial;
this.arduino.aliasSerial('light', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and light', err);
@ -229,14 +261,14 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,camera,light') {
this.connected.projector = device;
this.connected.camera = device;
this.connected.light = device;
this.arduino.aliasSerial('camera', device);
this.arduino.aliasSerial('light', device);
else if (device === 'projector,camera,light') {
this.connected.projector = serial;
this.connected.camera = serial;
this.connected.light = serial;
this.arduino.aliasSerial('camera', serial);
this.arduino.aliasSerial('light', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector, camera and light', err);
@ -244,12 +276,12 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA + LIGHT`, 'SERIAL', true, true);
}
else if (type === 'projector,camera') {
this.connected.projector = device;
this.connected.camera = device;
this.arduino.aliasSerial('camera', device);
else if (device === 'projector,camera') {
this.connected.projector = serial;
this.connected.camera = serial;
this.arduino.aliasSerial('camera', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and camera', err);
@ -257,10 +289,10 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA`, 'SERIAL', true, true);
}
else if (type === 'projector_second') {
this.connected.projector_second = device;
else if (device === 'projector_second') {
this.connected.projector_second = serial;
try {
connectSuccess = await this.arduino.connect('projector_second', device, false);
connectSuccess = await this.arduino.connect('projector_second', serial, false);
}
catch (err) {
this.log.error('Error connecting to secondary projector', err);
@ -268,115 +300,171 @@ class Devices {
}
this.log.info(`Connected to ${device} as PROJECTOR_SECOND`, 'SERIAL', true, true);
}
else if (type === 'projector,projector_second') {
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('projector_second', device);
else if (device === 'projector,projector_second') {
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('projector', device, false);
connectSuccess = await this.arduino.connect('projector', serial, false);
}
catch (err) {
this.log.error('Error connecting to projector and secondary projector', err);
return false;
}
}
else if (type === 'camera_second') {
this.connected.camera_second = device;
else if (device === 'camera_second') {
this.connected.camera_second = serial;
try {
connectSuccess = await this.arduino.connect('camera_second', device, false);
connectSuccess = await this.arduino.connect('camera_second', serial, false);
}
catch (err) {
console.error(err);
this.log.error(err);
return false;
}
}
else if (type === 'camera,camera_second') {
this.connected.camera = device;
this.connected.camera_second = device;
this.arduino.aliasSerial('camera_second', device);
else if (device === 'camera,camera_second') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.arduino.aliasSerial('camera_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_secondary and projector', err);
return false;
}
}
else if ('camera,projector,projector_second') {
this.connected.camera = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
else if (device === 'camera,projector,projector_second') {
this.connected.camera = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, projector and projector_second', err);
return false;
}
}
else if ('camera,camera_second,projector') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
this.arduino.aliasSerial('camera_second', device);
this.arduino.aliasSerial('projector', device);
else if (device === 'camera,camera_second,projector') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.connected.projector = serial;
this.arduino.aliasSerial('camera_second', serial);
this.arduino.aliasSerial('projector', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_second and projector', err);
return false;
}
}
else if ('camera,camera_second,projector,projector_second') {
this.connected.camera = device;
this.connected.camera_second = device;
this.connected.projector = device;
this.connected.projector_second = device;
this.arduino.aliasSerial('camera_second', device);
this.arduino.aliasSerial('projector', device);
this.arduino.aliasSerial('projector_second', device);
else if (device === 'camera,camera_second,projector,projector_second') {
this.connected.camera = serial;
this.connected.camera_second = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('camera_second', serial);
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', device, false);
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, camera_second, projector and projector_second', err);
return false;
}
}
else if (device === 'capper') {
this.connected.capper = serial;
try {
connectSuccess = await this.arduino.connect('capper', serial, false);
}
catch (err) {
this.log.error('Error connecting capper', err);
return false;
}
}
else if (device === 'camera,capper') {
this.connected.camera = serial;
this.connected.capper = serial;
this.arduino.aliasSerial('capper', serial);
try {
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera and capper', err);
return false;
}
}
else if (device === 'camera,capper,projector') {
this.connected.camera = serial;
this.connected.capper = serial;
this.connected.projector = serial;
this.arduino.aliasSerial('capper', serial);
this.arduino.aliasSerial('projector', serial);
try {
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper and projector', err);
return false;
}
}
else if (device === 'camera,capper,projector,projector_second') {
this.connected.camera = serial;
this.connected.capper = serial;
this.connected.projector = serial;
this.connected.projector_second = serial;
this.arduino.aliasSerial('capper', serial);
this.arduino.aliasSerial('projector', serial);
this.arduino.aliasSerial('projector_second', serial);
try {
connectSuccess = await this.arduino.connect('camera', serial, false);
}
catch (err) {
this.log.error('Error connecting to camera, capper, projector and projector_second', err);
return false;
}
}
return connectSuccess;
}
/**
*
**/
*
**/
//Cases for 1 or 2 arduinos connected
async all(devices) {
async all(serials) {
let c = {};
let p = {};
let l = {};
let type;
let device;
let d;
let cs = {};
let ps = {};
let capper = {};
let checklist = [];
let exposure;
let parts;
this.connected = {
projector: false,
camera: false,
light: false,
projector_second: false
projector_second: false,
capper: false
};
for (let device of devices) {
for (let serial of serials) {
try {
type = await this.distinguish(device);
device = await this.distinguish(serial);
}
catch (err) {
this.log.error('Error distinguishing device', err);
throw err;
}
try {
await this.connectDevice(device, type);
await this.connectDevice(device, serial);
}
catch (err) {
this.log.error('Error connecting to device', err);
@ -387,56 +475,82 @@ class Devices {
if (!this.connected.projector) {
await this.fakeProjector();
}
else if (this.arduino.hasState['projector']) {
p.state = true;
}
p.arduino = this.connected.projector;
if (!this.connected.camera) {
await this.fakeCamera();
}
else if (this.arduino.hasState['camera']) {
if (device.indexOf('camera') !== -1) {
parts = this.arduino.stateStr[device].split('G');
if (parts.length > 1) {
parts = parts[1].split('H');
exposure = parseInt(parts[0]);
if (!isNaN(exposure)) {
this.log.info(`Timing for [${device}] = ${exposure}`);
this.ui.send('timing', { c: 'c', ms: exposure });
}
}
}
c.state = true;
c.exposure = true;
}
c.arduino = this.connected.camera;
if (!this.connected.light) {
await this.fakeLight();
}
l.arduino = this.connected.light;
if (this.connected.camera_second) {
cs = { arduino: this.connected.camera_second };
cs.arduino = this.connected.camera_second;
}
if (this.connected.projector_second) {
ps = { arduino: this.connected.projector_second };
ps.arduino = this.connected.projector_second;
}
if (this.connected.capper) {
capper.arduino = this.connected.capper;
}
if (this.settings.state.camera && this.settings.state.camera.intval) {
c.intval = this.settings.state.camera.intval;
}
return this.ready(p, c, l, cs, ps);
return this.ready(p, c, l, cs, ps, capper);
}
/**
*
**/
remember(which, device, type) {
*
**/
remember(device, serial, type) {
let deviceEntry;
const match = this.settings.state.devices.filter((dev) => {
if (dev[which] && dev[which] === device) {
if (typeof dev.device !== 'undefined' && dev.device === device &&
typeof dev.serial !== 'undefined' && dev.serial === serial) {
return dev;
}
});
if (match.length === 0) {
deviceEntry = {
type: type
device,
type,
serial
};
deviceEntry[which] = device;
this.settings.state.devices.push(deviceEntry);
this.settings.update('devices', this.settings.state.devices);
this.settings.save();
}
}
/**
*
**/
ready(projector, camera, light, camera_second, projector_second) {
*
**/
ready(projector, camera, light, camera_second, projector_second, capper) {
let args = {
camera,
projector,
light,
profile: this.settings.state.profile
};
if (this.settings.state.timing) {
args.timing = this.settings.state.timing;
}
if (projector_second && projector_second.arduino) {
args.projector_second = projector_second;
this.settings.update('projector_second', projector_second);
@ -452,6 +566,11 @@ class Devices {
this.mainWindow.setSize(800, 800);
}
}
if (capper && capper.arduino) {
args.capper = capper;
this.mainWindow.setSize(800, 800);
this.settings.update('capper', capper);
}
this.settings.update('camera', camera);
this.settings.update('projector', projector);
this.settings.update('light', light);
@ -460,7 +579,6 @@ class Devices {
return true;
}
}
module.exports = function (arduino, settings, mainWindow, cam) {
return new Devices(arduino, settings, mainWindow, cam);
};
exports.Devices = Devices;
module.exports = { Devices };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
<a name="module_lib/display"></a>
## lib/display
<a name="module_lib/display..electron_1"></a>
### lib/display~electron\_1
Provides features for displaying a full screen display of images for the digital module.
**Kind**: inner constant of [<code>lib/display</code>](#module_lib/display)

18
app/lib/display/index.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
import type { System } from 'system';
export declare class Display {
private platform;
private displays;
private display;
private tmpdir;
private wv;
constructor(sys: System);
open(): Promise<void>;
show(src: string): Promise<void>;
showPath(pathStr: string): Promise<unknown>;
hide(): void;
close(): Promise<boolean>;
focus(): Promise<boolean>;
field(ratio: number): Promise<boolean>;
meter(): Promise<boolean>;
change(id: string): void;
}

View File

@ -1,22 +1,28 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.Display = void 0;
/**
* @module lib/display */
/**
* @module display
* Provides features for displaying a full screen display of images for the digital module.
**/
const electron_1 = require("electron");
const path_1 = require("path");
const url_1 = require("url");
const delay_1 = require("delay");
const { BrowserWindow } = require('electron');
const log_1 = require("log");
class WebView {
constructor(platform, display) {
this.opened = false;
this.showing = false;
this.loadWait = {};
this.ipc = electron_1.ipcMain;
const prefs = {
webPreferences: {
nodeIntegration: true,
allowRunningInsecureContent: false
allowRunningInsecureContent: false,
//enableRemoteModule: true,
contextIsolation: false
},
width: 800,
height: 600,
@ -24,16 +30,18 @@ class WebView {
minHeight: 600 //,
//icon: path.join(__dirname, '../../assets/icons/icon.png')
};
const pagePath = path_1.normalize(path_1.join(__dirname, '../../display.html'));
const pageUrl = url_1.format({
const pagePath = (0, path_1.normalize)((0, path_1.join)(__dirname, '../../display.html'));
const pageUrl = (0, url_1.format)({
pathname: pagePath,
protocol: 'file:'
});
this.init();
if (!display.primary) {
prefs.x = display.x + 50;
prefs.y = display.y + 50;
}
this.digitalWindow = new BrowserWindow(prefs);
this.digitalWindow = new electron_1.BrowserWindow(prefs);
require('@electron/remote/main').enable(this.digitalWindow.webContents);
this.digitalWindow.loadURL(pageUrl);
if (process.argv.indexOf('-d') !== -1 || process.argv.indexOf('--dev') !== -1) {
this.digitalWindow.webContents.openDevTools();
@ -45,30 +53,32 @@ class WebView {
//this.digitalWindow.hide();
this.platform = platform;
this.display = display;
this.ipc = require('electron').ipcMain;
this.ipc.on('display_load', this.onLoad.bind(this));
}
async init() {
this.log = await (0, log_1.Log)({ label: 'devices' });
}
async open() {
this.digitalWindow.show();
this.showing = true;
this.opened = true;
await this.digitalWindow.setFullScreen(true);
await delay_1.delay(300);
await (0, delay_1.delay)(300);
if (this.platform === 'osx') {
await delay_1.delay(300); //give macs an extra 300ms to open fullscreen
await (0, delay_1.delay)(300); //give macs an extra 300ms to open fullscreen
}
}
async show(src) {
const normalSrc = path_1.normalize(path_1.join(src));
const normalSrc = (0, path_1.normalize)((0, path_1.join)(src));
if (!this.digitalWindow) {
console.warn(`Cannot show "${src}" because window does not exist`);
this.log.warn(`Cannot show "${src}" because window does not exist`);
return false;
}
try {
this.digitalWindow.webContents.send('display', { src: normalSrc });
}
catch (err) {
console.error(err);
this.log.error('Error displaying ${normalSrc}', err);
}
this.showing = true;
return new Promise(function (resolve) {
@ -83,41 +93,41 @@ class WebView {
}
async focus() {
if (!this.digitalWindow) {
console.warn(`Cannot show focus screen because window does not exist`);
this.log.warn(`Cannot show focus screen because window does not exist`);
return false;
}
await delay_1.delay(500);
await (0, delay_1.delay)(500);
try {
this.digitalWindow.webContents.send('focus', { focus: true });
}
catch (err) {
console.error(err);
this.log.error(err);
}
}
async field(ratio) {
if (!this.digitalWindow) {
console.warn(`Cannot show field guide because window does not exist`);
this.log.warn(`Cannot show field guide because window does not exist`);
return false;
}
await delay_1.delay(500);
await (0, delay_1.delay)(500);
try {
this.digitalWindow.webContents.send('field', { field: true, ratio });
}
catch (err) {
console.error(err);
this.log.error(err);
}
}
async meter() {
if (!this.digitalWindow) {
console.warn(`Cannot show meter screen because window does not exist`);
this.log.warn(`Cannot show meter screen because window does not exist`);
return false;
}
await delay_1.delay(500);
await (0, delay_1.delay)(500);
try {
this.digitalWindow.webContents.send('meter', { meter: true });
}
catch (err) {
console.error(err);
this.log.error(err);
}
}
hide() {
@ -142,7 +152,7 @@ class Display {
constructor(sys) {
this.platform = sys.platform;
this.displays = sys.displays;
this.tmpdir = path_1.join(sys.tmp, 'mcopy_digital');
this.tmpdir = (0, path_1.join)(sys.tmp, 'mcopy_digital');
this.display = this.displays.find((display) => {
if (display.primary)
return true;
@ -184,7 +194,6 @@ class Display {
});
}
}
module.exports = function (sys) {
return new Display(sys);
};
exports.Display = Display;
module.exports = { Display };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

17
app/lib/exec/index.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
interface ExecOutput {
stdout: string;
stderr: string;
}
/**
* Promisified child_process.exec
*
* @param cmd
* @param arg
* @param opts See child_process.exec node docs
* @param {stream.Writable} opts.stdout If defined, child process stdout will be piped to it.
* @param {stream.Writable} opts.stderr If defined, child process stderr will be piped to it.
*
* @returns {Promise<{ stdout: string, stderr: stderr }>}
*/
export declare function exec(...args: string[]): Promise<ExecOutput>;
export type { ExecOutput };

View File

@ -1,5 +1,7 @@
'use strict';
const execRaw = require('child_process').exec;
Object.defineProperty(exports, "__esModule", { value: true });
exports.exec = void 0;
const child_process_1 = require("child_process");
/**
* Promisified child_process.exec
*
@ -28,7 +30,7 @@ async function exec(...args) {
opts = { maxBuffer: 1024 * 1024 };
}
return new Promise((resolve, reject) => {
const child = execRaw(cmd, opts, (err, stdout, stderr) => err ? reject(err) : resolve({
const child = (0, child_process_1.exec)(cmd, opts, (err, stdout, stderr) => err ? reject(err) : resolve({
stdout,
stderr
}));
@ -40,5 +42,6 @@ async function exec(...args) {
}
});
}
module.exports.exec = exec;
exports.exec = exec;
module.exports = { exec };
//# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exec/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI,CAAC,GAAG,IAAe;IACrC,IAAI,GAAG,GAAY,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,IAAI,GAAY,IAAI,CAAA;IACxB,IAAI,IAAI,GAAS,IAAI,CAAA;IAErB,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1D,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACjD,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;SAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACvC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QAClB,IAAI,GAAG,EAAE,SAAS,EAAG,IAAI,GAAG,IAAI,EAAE,CAAA;KAClC;IACE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EACjC,CAAC,GAAW,EAAE,MAAe,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7E,MAAM;YACN,MAAM;SACN,CAAC,CAAC,CAAC;QACC,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exec/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAEZ,iDAA+C;AAO/C;;;;;;;;;;GAUG;AACI,KAAK,UAAU,IAAI,CAAC,GAAG,IAAe;IAC5C,IAAI,GAAG,GAAY,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,IAAI,GAAY,IAAI,CAAA;IACxB,IAAI,IAAI,GAAS,IAAI,CAAA;IAErB,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1D,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACjD,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;SAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACvC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QAClB,IAAI,GAAG,EAAE,SAAS,EAAG,IAAI,GAAG,IAAI,EAAE,CAAA;KAClC;IACE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAkB,EAAE,MAAiB,EAAE,EAAE;QAC5D,MAAM,KAAK,GAAG,IAAA,oBAAO,EAAC,GAAG,EAAE,IAAI,EACjC,CAAC,GAAW,EAAE,MAAe,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7E,MAAM;YACN,MAAM;SACN,CAAC,CAAC,CAAC;QACC,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AA7BD,oBA6BC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,CAAA"}

8
app/lib/exit/index.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/**
* Exit process with either a 0 code or other
* specified failure code. Print message to console first.
*
* @param {string} msg Reason for exit
* @param {integer} code process exit code, default 0
**/
declare function exit(msg: string, code?: number): void;

View File

@ -16,5 +16,5 @@ function exit(msg, code = 0) {
process.exit(code);
}
}
module.exports.exit = exit;
module.exports = { exit };
//# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exit/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,IAAI,CAAE,GAAY,EAAE,OAAgB,CAAC;IAC7C,IAAI,IAAI,KAAK,CAAC,EAAE;QACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,IAAI,EAAE,CAAC;KACf;SAAM;QACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACnB;AACF,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exit/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,IAAI,CAAE,GAAY,EAAE,OAAgB,CAAC;IAC7C,IAAI,IAAI,KAAK,CAAC,EAAE;QACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,IAAI,EAAE,CAAC;KACf;SAAM;QACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACnB;AACF,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC"}