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

reading a online database but have a fall over on the pi ?

Mon Aug 12, 2019 6:45 pm

hi, i have a system that reads a csv file on the pi itself at the moment and does its job as needed. i can update this csv file wih new data as i need.

ithe system is an access control system so when the proximity reader reads the correct number it triggers a gpio pin.

what i want to so is have my script read a csv file remotly (maybe a web address, http://mywebsite.co.uk/data.csv) but if the pi is not onlone or cannot see the file it falls over onto a database that is stored on the pi itself. the current start of my script which reads the data file is as follows:


import pigpio, csv, os

os.system("pigpiod")

FILE_TO_READ = '/home/pi/furniss/database/database.csv'
CSV_ID_KEY = 'Number :'
CSV_NAME_KEY = 'Name :'
CSV_TEL_KEY = 'Tel No :'

class decoder:



could i add this under the file to read /database.csv ?

FILE_TO_READ = /'http://mywebsite.co.uk/data.csv'

?

thanks

ghp
Posts: 1408
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: reading a online database but have a fall over on the pi ?

Mon Aug 12, 2019 7:59 pm

https://stackoverflow.com/questions/139 ... d-the-cont

Surround this with a try:...except Exception: and read the file in the exception branch.

User avatar
Douglas6
Posts: 4759
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL

Re: reading a online database but have a fall over on the pi ?

Tue Aug 13, 2019 12:28 am

And you might want to use the term 'failover' (https://en.m.wikipedia.org/wiki/Failover), instead of 'fall over' (https://www.dictionary.com/browse/fall-over).

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

Re: reading a online database but have a fall over on the pi ?

Tue Aug 13, 2019 4:17 pm

thank you for the comments and thats great. also thanks for the fallover-failover thing :)

isit possible you could help me add it to the code, im new and learning and if could see the differnce between my original code and one with the option of what i asked above this would really help me so i could continue to modify this script with this. appreciated in advance.

my current script is as follows

Code: Select all

#!/usr/bin/env python

import pigpio, csv, os

os.system("pigpiod")

FILE_TO_READ = '/home/pi/furniss/database/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__":

   print (" ")
   print ("Furniss.UK ACS - Version 1.1 - TLF")
   print (" ")

   import time
   import datetime
   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:
         now = datetime.datetime.now()
         print (now.strftime("%Y-%m-%d %H:%M:%S"))
         print("User='{}' Tel='{}' Wiegand bits={} Card Number={}".format(user[CSV_NAME_KEY], user[CSV_TEL_KEY], bits, value))
         print (" ")
         file = open("/home/pi/furniss/html/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 (" ")
         print("door secure")
         GPIO.output(18, GPIO.HIGH)
         print (" ")
         print (" --------------------------------------------")
      else:
         now = datetime.datetime.now()
         print (" ")
         print (now.strftime("%Y-%m-%d %H:%M:%S"))
         print("Access Denied = Wiegand bits={} Card Number={}".format(bits, value))
         file = open("/home/pi/furniss/html/events.txt", "w")
         file.write("Access Denied = Wiegand bits={} Card Number={}".format(bits, value))
         print (" ")
         print (" --------------------------------------------")
         print (" ")

   pi = pigpio.pi()

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



   while True:
      time.sleep(60)

   w.cancel()

   pi.stop()


Andyroo
Posts: 4465
Joined: Sat Jun 16, 2018 12:49 am
Location: Lincs U.K.

Re: reading a online database but have a fall over on the pi ?

Tue Aug 13, 2019 4:59 pm

I would use something like wget to download the file and if that fails then use the local copy rather than trying to read from a CSV on the net. This is not as up to date as reading the file directly but less prone to errors. Remember, EVERY command with the remote file will need error trapping.

It can be done (example here from 2013.

The other option is to move away from flat files and use MySQL and replication.
Need Pi spray - these things are breeding in my house...

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

Re: reading a online database but have a fall over on the pi ?

Tue Aug 13, 2019 5:24 pm

this is exactly as i want tbh !! could you help me put this in the code i posted above please ? as mentioned if i could see the differnce i could continue this project greatly on my own and learn. appreciated
Andyroo wrote:
Tue Aug 13, 2019 4:59 pm
I would use something like wget to download the file and if that fails then use the local copy rather than trying to read from a CSV on the net. This is not as up to date as reading the file directly but less prone to errors. Remember, EVERY command with the remote file will need error trapping.

It can be done (example here from 2013.

The other option is to move away from flat files and use MySQL and replication.

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

Re: reading a online database but have a fall over on the pi ?

Wed Aug 14, 2019 4:19 pm

anyone please ?

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

Re: reading a online database but have a fall over on the pi ?

Wed Aug 14, 2019 8:43 pm

Have a search for "urllib" and "urllib.urlopen" which allows a 'wget' to be done from within Python.

And you will probably want to add that to your "readFile" routine, though I would suggest starting with separate a proof of concept aside program to get urllib and fail-over detect working, and safely updating your disk-based database file. The last thing you want to do is to lose or corrupt your database file and lock everyone out.

And on that - How business critical, or otherwise critical, is this project, your code ?

Return to “Python”