drifterf
Posts: 138
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Update a file from usb with a GPIO button

Mon Jul 22, 2019 5:01 pm

Hi guys. so i have a project which works fine and trying to adapt it a bit.

current the pi is running a access control proximity reader through reading a CSV file. accepted codes trigger a pin which fires a relay and opens the automatic gate.

we currently goto the pi locally and update the csv file on site for any changes needed.

we want to update the csv file away from site and then have a simple way of loading it to the pi without hooking a screen up etc.

my idea is the following

1: put the updated file (lets say database.csv) on a memory stick.
2: goto site and plug the usb stick into the pi
3: press a button (a physical button connected to the pi) and it overwrites the existing csv file with the new

any help on doing this ?

i have posted current script below

many thanks in advance

Code: Select all

#!/usr/bin/env python

import pigpio, csv

FILE_TO_READ = 'database.csv'
CSV_ID_KEY = 'Number :'
CSV_NAME_KEY = 'Name   :'
CSV_TEL_KEY = 'Tel No :'

class decoder:

   """
   A class to read Wiegand codes of an arbitrary length.

   The code length and value are returned.

   EXAMPLE

   #!/usr/bin/env python

   import time

   import pigpio

   import wiegand

   def callback(bits, code):
      print("bits={} code={}".format(bits, code))

   pi = pigpio.pi()

   w = wiegand.decoder(pi, 14, 15, callback)

   while True:   
      time.sleep(60)

   w.cancel()

   pi.stop()
   """

   def __init__(self, pi, gpio_0, gpio_1, callback, bit_timeout=5):

      """
      Instantiate with the pi, gpio for 0 (green wire), the gpio for 1
      (white wire), the callback function, and the bit timeout in
      milliseconds which indicates the end of a code.

      The callback is passed the code length in bits and the value.
      """

      self.pi = pi
      self.gpio_0 = gpio_0
      self.gpio_1 = gpio_1

      self.callback = callback

      self.bit_timeout = bit_timeout

      self.in_code = False

      self.pi.set_mode(gpio_0, pigpio.INPUT)
      self.pi.set_mode(gpio_1, pigpio.INPUT)

      self.pi.set_pull_up_down(gpio_0, pigpio.PUD_UP)
      self.pi.set_pull_up_down(gpio_1, pigpio.PUD_UP)

      self.cb_0 = self.pi.callback(gpio_0, pigpio.FALLING_EDGE, self._cb)
      self.cb_1 = self.pi.callback(gpio_1, pigpio.FALLING_EDGE, self._cb)

   def _cb(self, gpio, level, tick):

      """
      Accumulate bits until both gpios 0 and 1 timeout.
      """

      if level < pigpio.TIMEOUT:

         if self.in_code == False:
            self.bits = 1
            self.num = 0

            self.in_code = True
            self.code_timeout = 0
            self.pi.set_watchdog(self.gpio_0, self.bit_timeout)
            self.pi.set_watchdog(self.gpio_1, self.bit_timeout)
         else:
            self.bits += 1
            self.num = self.num << 1

         if gpio == self.gpio_0:
            self.code_timeout = self.code_timeout & 2 # clear gpio 0 timeout
         else:
            self.code_timeout = self.code_timeout & 1 # clear gpio 1 timeout
            self.num = self.num | 1

      else:

         if self.in_code:

            if gpio == self.gpio_0:
               self.code_timeout = self.code_timeout | 1 # timeout gpio 0
            else:
               self.code_timeout = self.code_timeout | 2 # timeout gpio 1

            if self.code_timeout == 3: # both gpios timed out
               self.pi.set_watchdog(self.gpio_0, 0)
               self.pi.set_watchdog(self.gpio_1, 0)
               self.in_code = False
               self.callback(self.bits, self.num)

   def cancel(self):

      """
      Cancel the Wiegand decoder.
      """

      self.cb_0.cancel()
      self.cb_1.cancel()


def readFile(filename):
   data = []
   with open(filename, 'r') as file:
      reader = csv.DictReader(file)
      data = [row for row in reader]
   return data

def authenticateFromFile(id):
   for row in readFile(FILE_TO_READ):
      if CSV_ID_KEY in row and row[CSV_ID_KEY] == id:
         return row
   return False

if __name__ == "__main__":

   import time
   import RPi.GPIO as GPIO
   import pigpio
   import wiegand

   GPIO.setmode(GPIO.BCM)
   GPIO.setwarnings(False)

   def callback(bits, value):
      user = authenticateFromFile('{}'.format(value))
      if user:
         print("User='{}' Tel='{}' Wiegand bits={} Card Number={}".format(user[CSV_NAME_KEY], user[CSV_TEL_KEY], bits, value))
         file = open("www/events.txt", "w")
         file.write("Last Access: Wiegand bits={}\n".format(bits))
         file.write("\nCard value={}".format(value))
         GPIO.setup(18,GPIO.OUT)
         print("door released")
         GPIO.output(18,GPIO.LOW)
         time.sleep(5)
         print("door secure")
         GPIO.output(18, GPIO.HIGH)
      else:
         print("Access Denied = Wiegand bits={} Card Number={}".format(bits, value))
         file = open("www/events.txt", "w")
         file.write("Access Denied = Wiegand bits={} Card Number={}".format(bits, value))



   pi = pigpio.pi()

   w = wiegand.decoder(pi, 14, 15, callback)



   while True:
      time.sleep(60)

   w.cancel()

   pi.stop()


PhatFil
Posts: 1437
Joined: Thu Apr 13, 2017 3:55 pm
Location: Oxford UK

Re: Update a file from usb with a GPIO button

Mon Jul 22, 2019 9:45 pm

If your Pi is connected to the web you could enable ssh or vnc access and remotely log onto the pi,
https://www.realvnc.com/en/raspberrypi/

drifterf
Posts: 138
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Update a file from usb with a GPIO button

Tue Jul 23, 2019 11:58 am

Hi, this is not a option for this project. i need to put a csv file on a memory stick, take it to the pi, plug in, press a physical button so it copys and overwrites the old file

hippy
Posts: 6248
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Update a file from usb with a GPIO button

Tue Jul 23, 2019 1:38 pm

You could check for the insertion of the USB stick and the presence of the file, check if the file is the same as the current and update it if not. That's a fully automated system without any button push required.

However you choose to do it I would suggest developing the code to update the file independently of what you already have. Get it working then integrate it into your existing code.

PhatFil
Posts: 1437
Joined: Thu Apr 13, 2017 3:55 pm
Location: Oxford UK

Re: Update a file from usb with a GPIO button

Tue Jul 23, 2019 2:05 pm

Ok had to check.. In that case yes, your plan could work. in fact no need for the button. write a small script to look for your update file in a known location on the thumb drive every 60 seconds or so. And if/when it finds it perform the copy.
Use an obscure directory path/filename to avoid accidents....


You might find it expedient to add some sort of tests and checks, for example is the new file actually newer? perhaps compare file dates? also is the file size reasonable? just be mindful that you dont want checks and tests that stop you from doing things you want to do.

adding some sort of output device a buzzer or led so you can provide the user some sort of feedback on progress and success of the operation. flash a led while copying, flash rapidly if an error and turn on when done and finished until the usb is removed perhaps?

write a small log file to the usb drive too perhaps so you can verify the operation worked as expected too.

If however your file is a shared resource its possible that it could be in use at the time you attempt to replace it. So it would probably be wise if possible signal your app to leave the file alone or shut down your application copy the file and restart your application.

this will give you an idea about how to go about looking for a file using python.
https://www.geeksforgeeks.org/file-sear ... ng-python/

python is probably the most accessible vehicle for you to use tho not the only option.

drifterf
Posts: 138
Joined: Sat Dec 08, 2018 9:09 am
Location: Northants, England

Re: Update a file from usb with a GPIO button

Tue Jul 23, 2019 3:27 pm

this is great, i will have a read through and let you know my results. doing away with the button is even better !

Return to “Python”