an IoT platform for vertical farming

as mentioned in [[2020-08-22-growing-microgreens]] this last year a significant portion of my time has been invested into an iot platform for managing a vertical farm setup https://gitlab.com/cxss/mcn - it has humble beginnings in my first ever react app some years ago & has been iterated upon in ideas/implementation to its current state.

this pic ripped straight from the pitch deck for a startup incubator i'm currently working at (though under a different project) describes its aims:

mcn pitch deck slide

im no business droid so this probably sucks at explaining what it does - but in a nutshell it takes the whole 'command and control' aspect of this kind of operation off from the hardware itself, and moves it over into the cloud - a SCADA system but Industry 4.0 (buzzwords yay!)

for example, instead of writing some C code for an embedded device that turns on the lights at 12pm by fetching the time from some NTP timeserver & setting it's port output to high if 12pm < CURRENT_TIME < 1pm, instead the devices receives a message from the cloud instructing it to just set a port high, the important point here is that the timing/other conditional logic is extracted out, such that behaviour of the overall system can be decided at a higher scope - instead of re-programming the device you just alter some variables on a website

now thats a very simple example but consider a system like a vertical farm where there are hundreds of inputs & outputs which need to change rapidly over the course of a day, running experiments to minmax yield:resources would incur significant issues when trying to re-program (even OTA) & orchestrate

attempt 1

the first attempt really was more a vehicle to learn React & Redux ([[2019-07-29-automating-plant-care]]) rather than a solid attempt at tackling this problem, after gaining a good appreciation for react (class based - totally depreciated now, great) & redux i dropped it over doing some more game dev with Lร–VE - redux just comes across now as someone who didn't know about pub-sub tries implementing pub-sub for the frontend, but with added steps, angular does a much better job of global state management through services via observables - but that's a topic for another post

attempt 1.5

in 2019 i was applying for some full-stack job through a graduate scheme, and as part of that i had to give some presentation on "something you're proud about", naturally being a cynic the sum of absolutely nothing came to mind so I decided to develop this idea out a bit more and present about it instead, you can read that presentation here.

Skjermbilde 2021-08-11 kl. 4.28.26 pm.png

still had no name for this thing other than hydroponics, classic

Skjermbilde 2021-08-11 kl. 4.28.02 pm.png

as part of this website i built some hardware around the esp-32 & learned some more C for collecting data & submitting it to the API, all of that is detailed here.

Skjermbilde 2021-08-11 kl. 4.27.53 pm.png

there used to be a video of this but it's been lost to the sands of time somewhere - anyways this app had a bit more going on with it, it supported a few more devices; an esp-32 & raspberry pi, with a time series database (InfluxDB) collecting the metrics - i still wasn't entirely sure of what i wanted to build at this point and the next iteration went more into developing it into a sort of social network for plant growing & hardware enthusiasts... not exactly a huge niche in retrospect

attempt 2

after getting said full-stack job & learning a bunch more about typescript & angular i figured i'd put those skills to use and put together this frankly quite nice looking webapp? it's a shame the whole thing was backed by neo4j which turned out to be a terrible idea due to the lack of ORM tooling for it, but i learned a bunch about its query language, cypher, graph databases & influx

Screenshot 2020-05-31 at 7.59.39 pm.png

after messing around with some twitter-like features, posting, liking, retweeting etc i switched gears into focusing it more as an IoT platform with the following features:

  • manage IoT devices to monitor your crops & add your own custom hardware
  • create job queues for carrying out tasks at certain intervals
  • remotely trigger events on micro-controllers, e.g. turn on light, open watering valve
  • alerts to notify when an action needs completing e.g. watering, re-seeding
  • compile timelines of growth & collate rotation plans
  • monitor all metrics on a front-end dashboard

before & after material to ibm switch

originally i started writing it using material angular but then moved to ibm carbon since that library looked sliiiiick

Screenshot 2020-09-25 at 10.16.26 am.png

dashboard & graphs

kind of got de-railed on this attempt by creating a domain specific language to carry out the job queues, which turned out to be another waste of time, but not without teaching me how to write a lexer, tokenizer & compiler

anyways here's a couple vids i managed to dig up showing some of it's functionality - i have so many pictures of other things it has but already feel like i turn my blog posts in glorified picture galleries but with garbage commentary so this'll suffice

if i had to estimate probably 65% of my time went into the frontend, of which is extremely biased on the amount of work required to progress made, i definitely need to pre-plan how the application will flow to avoid doing big re-writes half way through. i also find it pretty easy to slip up from seeing a nice design on dribbble and refactoring components to fit a new fancy design. it just adds a sum of zero new features for the cost of days of effort, as was the case with moving from material --> ibm

attempt 3

and here we are now, my third (and hopefully final) attempt, i don't think i'll have the time what with running a startup now to put any serious time investment into this, but i think i've refined the scope of the project through these iterations into something accomplishable by one person

as a bit of experimentation i wrote this thing in a weekend to test out rabbitmq https://gitlab.com/cxss/mqfc

so, attempt 3:

  • don't burn time on nice visualisations like network graphs etc.
  • pre-plan ui to fully map out all interactions
  • refine your scope, and then cut out 50% of the features
  • drop the whole "vertical farming" aspect and narrow scope onto just crops/user definable groupings
  • pick a stack that allows for rapid iteration in deployment

in terms of technical things:

  • rabbitmq + event driven architecture
  • go cli interface using bubbletea & lipgloss
    • ui is my achilles heel because the perfectionist side of me can spend faaar too long on implementation
  • serverless "backend"
    • infinite scale :0
    • avoid deployment
  • edge nodes in rust using rpi pico & micro:bit
    • gives me a reason to learn rust
              cli (go + bubbletea)
               |
               v
 fauna <--> serverless (typescript + graphql)
               ^
               |
            rabbitmq
           /   |    \
          v    |     v
      device   v    device (rust + rpi pico/micro:bit)
            device