-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1356 lines (1261 loc) · 65 KB
/
Copy pathindex.html
File metadata and controls
1356 lines (1261 loc) · 65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en" data-theme="cmyk">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FerretCode | Portfolio</title>
<link rel="icon" href="images/favicon.ico" type="image/x-icon" />
<link
href="https://cdn.jsdelivr.net/npm/daisyui@4.11.1/dist/full.min.css"
rel="stylesheet"
type="text/css"
/>
<script src="https://cdn.tailwindcss.com"></script>
<link
href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap"
rel="stylesheet"
/>
<meta content="Portfolio of FerretCode" property="og:title" />
<meta
content="Embedded systems & Full-stack engineer. Explore my projects and work experience with hardware, firmware, Kubernetes, hardware, and more."
property="og:description"
/>
<meta content="https://frrt.space" property="og:url" />
<meta content="./images/pfp.png" property="og:image" />
<meta content="#34a1eb" name="theme-color" />
</head>
<body style="font-family: "Montserrat", sans-serif">
<div class="navbar text-primary-content">
<div class="flex-1">
<a
tabindex="0"
class="btn btn-ghost btn-circle avatar"
href="/"
>
<div class="w-10 rounded-full">
<img alt="Logo" src="./images/pfp.png" />
</div>
</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1 hidden lg:flex">
<li>
<a
class="btn btn-primary mx-2"
href="https://techrocks.frrt.space"
>Blog</a
>
</li>
<li>
<a
class="btn btn-secondary mx-2"
href="https://github.com/FerretCode"
target="_blank"
>GitHub</a
>
</li>
<li>
<a
class="btn btn-success mx-2"
href="mailto:ferret@frrt.space"
target="_blank"
>Contact</a
>
</li>
</ul>
<div class="dropdown dropdown-end lg:hidden">
<button tabindex="0" class="btn btn-ghost btn-circle">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h7"
/>
</svg>
</button>
<ul
tabindex="0"
class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52"
>
<li><a href="#projects">Projects</a></li>
<li>
<a
href="https://github.com/FerretCode"
target="_blank"
>GitHub</a
>
</li>
<li>
<a href="mailto:ferret@frrt.space" target="_blank"
>Contact</a
>
</li>
</ul>
</div>
</div>
</div>
<div class="hero mt-6">
<div class="hero-content flex-col lg:flex-row-reverse">
<img
src="./images/hero.png"
alt="Code window illustration"
class="w-full max-w-sm rounded-lg md:max-w-2xl"
/>
<div class="text-primary-content">
<h1 class="text-5xl font-bold">FerretCode</h1>
<p class="py-6">
Multi-stack software engineer. I love building embedded
systems and hardware, internal tooling, full-stack
applications, and infrastructure tools.
</p>
<a class="btn btn-primary" href="#work">See My Work</a>
</div>
</div>
</div>
<div class="flex mt-10">
<div class="m-auto max-w-4xl text-center">
<h2 class="text-3xl font-bold mb-4">About Me</h2>
<p>
I'm a embedded and full-stack developer with a focus on
infrastructure, automation, and embedded systems. My work
often focuses in multiple stacks, from developer tools and
cloud-native apps to embedded hardware design and smallsat
subsystems. Much of my skill appears at the meeting of
software and hardware, with experience in technologies like
Go, Kubernetes, Docker, and more, alongside PCB design,
LoRa/IoT, and space electronics.
</p>
</div>
</div>
<div id="work" class="flex mt-16">
<div class="m-auto px-4">
<h2 class="text-3xl font-bold text-center mb-8">Experience</h2>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">
Embedded Systems & Research Engineer @ OSU CEOAS
</h2>
<h3>
<div class="badge badge-success">
April 2025 - Present
</div>
</h3>
<h3 class="flex flex-wrap gap-2">
<div class="badge badge-primary">C/C++</div>
<div class="badge badge-primary">CUDA/HPC</div>
<div class="badge badge-secondary">Node.js/Python</div>
<div class="badge badge-secondary">Embedded Linux</div>
<div class="badge badge-secondary">KiCad</div>
</h3>
<p>
Developing low-power embedded wildlife monitoring devices and network topologies using ESP32 and custom PCB hardware.
Refactored large-scale data labeling and training pipelines for NOAA and USFS to improve performance and maintainability.
Previously implemented RAG-based LLM workflows and interfaces for climate data synthesis and user automation.
</p>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">
SWE Intern @ Semiconductor Company
</h2>
<h3>
<div class="badge badge-success">
June 2025 - September 2025
</div>
</h3>
<h3>
<div class="badge badge-primary">C#</div>
<div class="badge badge-secondary">gRPC</div>
<div class="badge badge-secondary">
Hardware
</div>
<div class="badge badge-secondary">Testing</div>
</h3>
<p>
Built and tested software to control a cluster
of semiconductor manufacturing devices.
Collaborated with a sizeable team in an Agile
software environment, and ensured a high level
of code quality and maintainability.
</p>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">
Contract DevOps Engineer @ Norse Projects
</h2>
<h3>
<div class="badge badge-success">
July 2022 - November 2022
</div>
</h3>
<h3>
<div class="badge badge-primary">DevOps</div>
<div class="badge badge-secondary">
Kubernetes
</div>
<div class="badge badge-secondary">ArgoCD</div>
<div class="badge badge-secondary">Docker</div>
</h3>
<p>
Designed and implemented a CI/CD pipeline for
automatically deploying feature-branch
development environments in Kubernetes,
improving development efficiency and reducing
manual errors. Created a build pipeline and
staging environments using Kubernetes, Docker,
GCP, and ArgoCD to deploy a NextJS + Strapi app
for ecommerce applications. Automated the
creation of feature-branch staging environments
based on pull requests, with private ingress for
testing.
</p>
</div>
</div>
</div>
</div>
</div>
<div id="projects" class="flex mt-16">
<div class="m-auto px-4">
<h2 class="text-3xl font-bold text-center mb-8">
Featured Projects
</h2>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">MESS/OSUSat</h2>
<h3>
<div class="badge badge-primary">Embedded</div>
<div class="badge badge-secondary">STM32</div>
<div class="badge badge-secondary">C</div>
<div class="badge badge-secondary">KiCad</div>
<div class="badge badge-secondary">
Space Hardware
</div>
<div class="badge badge-secondary">RF</div>
</h3>
<p>
Modular bus for building climate science devices
meant to be launched as a
<span
class="tooltip link"
data-tip="Small satellite standard"
>CubeSat</span
>
or
<span
class="tooltip link"
data-tip="High Altitude Balloon"
>HAB</span
>
payload. The current configuration includes
mounting rails, 18650 battery pack and
power/protection system, LoRa communications
board, on-board-computer for system management,
and a switching camera-filter payload for
running
<span
class="tooltip link"
data-tip="Normalized Difference Vegitation Index"
>NDVI</span
>
and
<span
class="tooltip link"
data-tip="Normalized Difference Chlorophyll Index"
>BG/NDCI</span
>
climate algorithms.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/osusat"
target="_blank"
class="btn btn-primary flex-1"
>View on GitHub</a
>
<button
class="btn btn-outline btn-secondary flex-1"
onclick="modal_osusat.showModal()"
>
Read Writeup
</button>
</div>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">Locomotive</h2>
<h3>
<div class="badge badge-primary">
Cloud-native
</div>
<div class="badge badge-secondary">Go</div>
<div class="badge badge-secondary">
Containers
</div>
<div class="badge badge-secondary">GraphQL</div>
</h3>
<p>
A Railway observability tool for streaming logs
from services to other platforms. Deployed as a
sidecar container, it subscribes to deployment
logs and forwards them to an ingress/webhook URL
for further processing outside of Railway.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/ferretcode/locomotive"
target="_blank"
class="btn btn-primary flex-1"
>
View on GitHub
</a>
<button
class="btn btn-outline btn-secondary flex-1"
onclick="modal_locomotive.showModal()"
>
Read Writeup
</button>
</div>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">Scavenger</h2>
<h3>
<div class="badge badge-primary">
Full-stack
</div>
<div class="badge badge-secondary">Go</div>
<div class="badge badge-secondary">
Containers
</div>
<div class="badge badge-secondary">
Websockets
</div>
<div class="badge badge-secondary">
Web-scraping
</div>
</h3>
<p>
A self-hostable platform for building
web-scraping pipelines. Allows developers to
describe in plain english the content they're
looking for, create a data schema, and then
connect over websocket to their workflow to get
real-time web-scraping data.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/ferretcode/scavenger"
target="_blank"
class="btn btn-primary flex-1"
>View on GitHub</a
>
<button
class="btn btn-outline btn-secondary flex-1"
onclick="modal_scavenger.showModal()"
>
Read Writeup
</button>
</div>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">RFID Inventory Tracker</h2>
<h3>
<div class="badge badge-primary">Embedded</div>
<div class="badge badge-secondary">RP2040</div>
<div class="badge badge-secondary">C</div>
<div class="badge badge-secondary">KiCad</div>
<div class="badge badge-secondary">Go</div>
<div class="badge badge-secondary">
PostgreSQL
</div>
<div class="badge badge-secondary">Redis</div>
</h3>
<p>
An RP2040 based embedded device for
automatically tracking warehouse inventory and
ingress using RFID tags and MQTT. Also exposes a
Golang based internal dashboard for registering
products and viewing product inventory.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/ferretcode/rfid-inventory-tracker"
target="_blank"
class="btn btn-primary flex-1"
>View on GitHub</a
>
<a
class="btn btn-outline btn-secondary flex-1"
href="https://techrocks.frrt.space/posts/building-embedded-cloud-integrations-with-mqtt"
>
Read Writeup
</a>
</div>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">FleetOS</h2>
<h3>
<div class="badge badge-primary">Embedded</div>
<div class="badge badge-secondary">STM32</div>
<div class="badge badge-secondary">C</div>
<div class="badge badge-secondary">KiCad</div>
<div class="badge badge-secondary">Go</div>
<div class="badge badge-secondary">
TimescaleDB
</div>
<div class="badge badge-secondary">Redis</div>
</h3>
<p>
An open-source telmatics device and platform for
realtime fleet tracking. Uses secure embedded
devices with GPS and cellular support to track
vehicle location. Also exposes a dashboard to
manage fleet devices and view locations/routes.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/fleetos"
target="_blank"
class="btn btn-primary flex-1"
>View on GitHub</a
>
<button
class="btn btn-outline btn-secondary flex-1"
onclick="modal_fleetos.showModal()"
>
Read Writeup
</button>
</div>
</div>
</div>
<div class="card w-full bg-neutral text-neutral-content">
<div class="card-body">
<h2 class="card-title">Switchyard</h2>
<h3>
<div class="badge badge-primary">
Cloud-native
</div>
<div class="badge badge-secondary">
Containers
</div>
<div class="badge badge-secondary">Go</div>
<div class="badge badge-secondary">
Microservices
</div>
<div class="badge badge-secondary">GraphQL</div>
<div class="badge badge-secondary">
Infrastructure
</div>
</h3>
<p>
Pluggable Railway infrastructure management
toolset, and the Railway hackathon winning
project. Includes services for autoscaling,
feature-flags, distributed worker scheduling,
and error and incident observability reporting.
</p>
<div class="flex gap-3 mt-4">
<a
href="https://github.com/ferretcode/switchyard"
target="_blank"
class="btn btn-primary flex-1"
>View on GitHub</a
>
<button
class="btn btn-outline btn-secondary flex-1"
onclick="modal_switchyard.showModal()"
>
Read Writeup
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="gallery" class="flex mt-16 mb-10">
<div class="m-auto px-4 w-full max-w-5xl">
<h2 class="text-3xl font-bold text-center mb-8">
Project Gallery
</h2>
<div
class="carousel w-full rounded-box h-96 bg-base-300 shadow-xl"
>
<div id="slide1" class="carousel-item relative w-full">
<img
src="./images/compute-deck.jpg"
class="w-full object-cover"
/>
<div
class="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2"
>
<a href="#slide4" class="btn btn-circle glass">❮</a>
<a href="#slide2" class="btn btn-circle glass">❯</a>
</div>
</div>
<div id="slide2" class="carousel-item relative w-full">
<img
src="./images/linklet.jpg"
class="w-full object-cover"
/>
<div
class="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2"
>
<a href="#slide1" class="btn btn-circle glass">❮</a>
<a href="#slide3" class="btn btn-circle glass">❯</a>
</div>
</div>
<div id="slide3" class="carousel-item relative w-full">
<img
src="./images/eps-root.png"
class="w-full object-cover"
/>
<div
class="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2"
>
<a href="#slide2" class="btn btn-circle glass">❮</a>
<a href="#slide4" class="btn btn-circle glass">❯</a>
</div>
</div>
<div id="slide4" class="carousel-item relative w-full">
<img
src="./images/px1.png"
class="w-full object-cover"
/>
<div
class="absolute flex justify-between transform -translate-y-1/2 left-5 right-5 top-1/2"
>
<a href="#slide3" class="btn btn-circle glass">❮</a>
<a href="#slide1" class="btn btn-circle glass">❯</a>
</div>
</div>
</div>
<div class="flex justify-center w-full py-2 gap-2">
<a href="#slide1" class="btn btn-xs">1</a>
<a href="#slide2" class="btn btn-xs">2</a>
<a href="#slide3" class="btn btn-xs">3</a>
<a href="#slide4" class="btn btn-xs">4</a>
</div>
</div>
</div>
<footer
class="footer footer-center p-10 mt-20 bg-base-200 text-base-content rounded"
>
<div>
<p>
Built by FerretCode - 2025
<a
class="link link-primary"
href="https://github.com/FerretCode"
target="_blank"
>GitHub</a
>
·
<a
class="link link-secondary"
href="https://discord.gg/xk43udsvKA"
target="_blank"
>Discord</a
>
</p>
</div>
</footer>
<dialog id="modal_locomotive" class="modal">
<div
class="modal-box w-11/12 max-w-5xl bg-neutral text-neutral-content"
>
<form method="dialog">
<button
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
>
✕
</button>
</form>
<h3 class="font-bold text-2xl mb-6">
Locomotive - Technical Deep Dive
</h3>
<div class="flex flex-col lg:flex-row gap-8">
<div class="lg:w-2/3">
<h4 class="text-xl font-bold text-primary mb-2">
Architecture
</h4>
<p class="mb-4">
Locomotive deploys as a sidecar container in an
existing Railway project. It leverages the internal
Railway GraphQL API to subscribe to deployment log
streams. The user configures the application using a
Railway template, and environment variables.
Locomotive is pointed at an external ingest URL,
where log lines are sent using a specified format
and processed by the consumer.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Key Challenges
</h4>
<ul class="list-disc list-inside mb-4 space-y-2">
<li>
Handling deployments updating and restarting
gracefully without dropping log lines.
</li>
<li>
Reconstructing Railway's fragmented log lines
from the GraphQL API into full log lines useable
by external consumers.
</li>
<li>
Packaging unstructured text logs into objects
useable by other platforms.
</li>
</ul>
<h4 class="text-xl font-bold text-primary mb-2">
Tech Stack Details
</h4>
<p class="mb-4">
Written in Go. Heavy use of Goroutines & channels
for handling multiple internal tasks at once,
including incoming log lines and forwarding logs to
external platforms. Locomotive is packaged as a
Docker container and deployed using a Railway
template. GraphQL is used to subscribe to incoming
logs, events, and other important details about
monitored deployments.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Achievements
</h4>
<p>
Received multiple sponsorships from Railway to
expand the feature set and improve reliability.
Shipped well over 1m+ logs with 100% uptime.
Deployed in 30+ user applications.
</p>
</div>
<div class="lg:w-1/3 flex flex-col gap-4">
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<img
src="./images/slack.png"
alt="Image of Slack With Locomotive Logs"
class="rounded"
/>
<p class="text-xs text-center mt-2 opacity-70">
Logs Shipped to Slack
</p>
</div>
</div>
</div>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
<dialog id="modal_scavenger" class="modal">
<div
class="modal-box w-11/12 max-w-5xl bg-neutral text-neutral-content"
>
<form method="dialog">
<button
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
>
✕
</button>
</form>
<h3 class="font-bold text-2xl mb-6">
Scavenger - Technical Deep Dive
</h3>
<div class="flex flex-col lg:flex-row gap-8">
<div class="lg:w-2/3">
<h4 class="text-xl font-bold text-primary mb-2">
Architecture
</h4>
<p class="mb-4">
Scavenger is a Dockerized self-hostable platform
that allows developers to quickly create web
scraping pipelines. Users create workflows by
describing in english what content they want, and
then defining a structured schema for the data to be
packaged in. Each web scraping job uses an LLM to
analyze the page content & extract the requested
information. Each unit of data is streamed over
websocket, where consuming applications can connect
and retrieve data in real time. Built for
BeaverHacks in 24 hours.
</p>
<p class="mb-4">
The technical implementation involved a monolithic
Golang application that used dependency injection to
spin up workflow containers on the seleted cloud
platform (or locally via Docker +
self-orchestration). Each workflow container is
written in a multithreaded Python application using
Crawl4AI to scrape and package the page content. For
each workflow, a new private websocket endpoint
(only accessible via API key) is spun up that
consumers connect to. Workflows are scheduled using
user-specified cron strings to run at intervals.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Key Challenges
</h4>
<ul class="list-disc list-inside mb-4 space-y-2">
<li>
Integrating the GCP cloud compute API & getting
containers to reliably spin up and pass health
checks.
</li>
<li>
Implementing concurrency reliably in Python
workflows.
</li>
<li>
Implementing reliable Websocket connections &
statistics tracking for workflows
</li>
</ul>
<h4 class="text-xl font-bold text-primary mb-2">
Tech Stack Details
</h4>
<p class="mb-4">
Written in Go. Used Gorilla websockets for websocket
connections, and listened concurrently for both
workflow & consumer connections. Implemented a
websocket reverse proxy between the workflow & the
user for streaming. Used Docker for deployment, and
MongoDB for workflow & document storage. Google
Cloud Run API for GCP integration, and Docker CLI
package for local orchestration. Used Pulumi for
user-facing IaC to simplify deployment on GCP.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Achievements
</h4>
<p>
Built in under 24 hours for BeaverHacks with a high
level of polish. Collaborated with a team of 3 other
developers & wrote high-quality and maintainable
code that allowed easy expansions after the event.
</p>
</div>
<div class="lg:w-1/3 flex flex-col gap-4">
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/XYN0cpBTbPg?si=MAmqPyzD280GCd9W"
title="YouTube video player"
frameborder="0"
allow="
accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture;
web-share;
"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
></iframe>
<p class="text-xs text-center mt-2 opacity-70">
Project Showcase
</p>
</div>
</div>
</div>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
<dialog id="modal_fleetos" class="modal">
<div
class="modal-box w-11/12 max-w-5xl bg-neutral text-neutral-content"
>
<form method="dialog">
<button
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
>
✕
</button>
</form>
<h3 class="font-bold text-2xl mb-6">
FleetOS - Technical Deep Dive
</h3>
<div class="flex flex-col lg:flex-row gap-8">
<div class="lg:w-2/3">
<h4 class="text-xl font-bold text-primary mb-2">
Architecture
</h4>
<p class="mb-4">
FleetOS is an open-source telmatics device used for
fleet tracking. It integrates with a backend ingest
platform over MQTT. The device uses a GNSS chip, a
cellular modem, and an STM32 to track and transmit
fleet locational data. The backend uses Golang and
EMQX for ingress, and stores data in a TimescaleDB
database for chronological data. The dashboard
allows for fleet managers to view locations,
introduce geofences, and manage devices remotely. An
authentication strategy using pre-baked certificates
is used to ensure no spoofing or interception occurs
between the device and the server.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Key Challenges
</h4>
<ul class="list-disc list-inside mb-4 space-y-2">
<li>
Integrating the GNSS chip. It requires
filtering, impedance matching, and knowledge of
various communication protocols and antenna
considerations.
</li>
<li>
Managing possible frequency collisions between
GNSS and cellular.
</li>
<li>
Keeping devices secure & designing an
authentication strategy.
</li>
</ul>
<h4 class="text-xl font-bold text-primary mb-2">
Tech Stack Details
</h4>
<p class="mb-4">
Device uses a simple STM32 F-series MCU, a Quectel
NEO-M9N GNSS chip, and a Quectel BC65PB-04-STD
cellular modem. Backend is written in Go, and MQTT
is handled via an EMQX broker.
</p>
<h4 class="text-xl font-bold text-primary mb-2">
Achievements
</h4>
<p>
Learned about managing frequency & RF conflicts,
implementing complex RF circuitry, and security in
embedded devices. Worked with and led a team of 4
others to plan and execute project requirements.
</p>
</div>
<div class="lg:w-1/3 flex flex-col gap-4">
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<img
src="./images/fleetos-system.png"
alt="Image of Slack With Locomotive Logs"
class="rounded"
/>
<p class="text-xs text-center mt-2 opacity-70">
System Architecture
</p>
</div>
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<img
src="./images/fleetos-device.png"
alt="Image of Slack With Locomotive Logs"
class="rounded"
/>
<p class="text-xs text-center mt-2 opacity-70">
Device Architecture
</p>
</div>
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<img
src="./images/fleetos-backend.png"
alt="Image of Slack With Locomotive Logs"
class="rounded"
/>
<p class="text-xs text-center mt-2 opacity-70">
Backend Architecture
</p>
</div>
<div
class="bg-base-300 p-2 rounded-lg shadow-lg text-black"
>
<img
src="./images/fleetos-authentication.png"
alt="Image of Slack With Locomotive Logs"
class="rounded"
/>
<p class="text-xs text-center mt-2 opacity-70">
Authentication Strategy
</p>
</div>
</div>
</div>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
<dialog id="modal_osusat" class="modal">
<div
class="modal-box w-11/12 max-w-5xl bg-neutral text-neutral-content"
>
<form method="dialog">
<button
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
>
✕
</button>
</form>