Laser Billing Function

Layman’s

The laser billing is calculated using two hardware devices: A Teensy microcontroller and a Raspberry Pi. The Teensy adds to a running total of seconds known as odometer while the laser is firing and reports this to the Raspberry Pi when requested (every second).

The running total of time firing and cost is shown on the LCD display, this is controlled by the Teensy.

When a user logs in or out the Raspberry Pi updates a local database with the running total of seconds. This is uploaded to an online database for billing [online upload is not currently functional since the endpoint went offline].


Technical

Teensy

Pseudocode

main loop (no delay)
  if laser is firing
  add milliseconds firing to stored milliseconds
  add seconds in stored milliseconds to stored total time
  set stored milliseconds to remainder (remove seconds)

every 30 seconds
  save stored total time to EPROM

Code for above: Teensy main Loop

request status
  return total time + (total ms rounded to nearest second)

Code for above: Teensy Request Status

Note for future: Since the Pi is requesting the updated time every second, storing the total_time to EPROM is not necessary providing we keep a local record for power boots

Raspberry Pi

login
  set odometer start

logout
  save odometer to local database

Code for above:
Raspberry Pi Login
Raspberry Pi Logout

main loop (1 second delay)
  query status from Teensy
  display status on LCD
  display: minutes:seconds Cost $(minutes * cost per min) [minutes 3 char pad spaces, seconds 2 chars pad 0]

Code for above:
Query Status from Teensy
Display Status

Update online database [not currently functional]

if we have local db entries and it's time to update
  get local db records
  push timestamp (Epoc - seconds since 1/1/1970), event type (login / logout), userid (rfid tag), and odometer difference (total seconds ran) to online endpoint

Code for above:
Main loop is local db ready to upload
Get local db
Upload to online endpoint

[Online upload not currently functional since ssl. went offline]

How the data is used

Once this data is in ACE Grand Central the custom ACE Billing Plugin accesses when bills are triggered every month. Database entries in  ACE Grand Central are amended with the billing information. See repo for the plugin.

One comment

  1. I’m trying to set this up for Chattlab, in Chattanooga, TN.
    I’ve the bundle installed on a PI 3. When starting, I get the following error:

    Array values in the parameter to `Gem.paths=` are deprecated.
    Please use a String or nil.
    An Array ({“GEM_PATH”=>[“/home/pi/.rvm/gems/ruby-2.3.0”, “/home/pi/.rvm/rubies/ruby-2.3.0/lib/ruby/gems/2.3.0”]}) was passed in from bin/rails:3:in `load’
    /home/pi/.rvm/gems/ruby-2.3.0/gems/devise-4.7.2/lib/devise/rails/routes.rb:500:in `raise_no_secret_key’: Devise.secret_key was not set. Please add the following to your Devise initializer: (RuntimeError)

    config.secret_key = ‘45678ee0fe782111c876fcb074689725b6f5a69ddadeae2ea1dc45a5055b03baafda78c1583790f6f90eb8b771a876e31bc1fd84ad04684aba58cda95251d312′

    Please ensure you restarted your application after installing Devise or setting the key.
    from /home/pi/.rvm/gems/ruby-2.3.0/gems/devise-4.7.2/lib/devise/rails/routes.rb:228:in `devise_for’
    from /home/pi/amt-laser/config/routes.rb:22:in `block (2 levels) in ‘
    from /home/pi/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.7.2/lib/action_dispatch/routing/mapper.rb:856:in `scope’
    from /home/pi/amt-laser/config/routes.rb:14:in `block in ‘

    How should I fix this? I am not a rails developer and haven’t touched ruby in several years.
    I appreciate any assistance!

    -JEB

Leave a Reply

Your email address will not be published. Required fields are marked *