Like many buildings, the building we live in has a panel at the main entrance which allows guests to call their hosts. The guest initiates the call by looking up and dialing a apartment specific buzzer code, and the host can remotely unlock the front door by dialing 9 on their phone.
Occasionally, we’ve had the need for an extra set of keys when guests are visiting. Given the ubiquity of smart phones, I’ve thought: Wouldn’t it be great to build a web interface which would essentially pick up the phone and dial 9, permitting entrance to the building without a set of keys?
The easiest way to do this was to write an application that uses an analog modem, which can detect a ring, pick up the phone, and generate tones. Finding a suitable modem was the hardest part, given that there are so few applications for analog modems since the widespread use of broadband Internet in the late 1990s. Further complicating things was I was looking to use a Raspberry Pi – this meant I needed a modem with a USB interface that works with Linux. From my research, the TRENDnet TFM-561U modem seemed to be the best fit for this purpose – testing has since confirmed it works great.
I wrote the application itself in NodeJS. Using the administrative page (behind a firewall) the Host sets up a password, has the option of adding a note, and must set dates for when the password starts and stops working. Note that there’s no login – it’s hard enough to remember a password, let alone the corresponding login. The passwords are stored hashed (using bcrypt) – it’s assumed that there are very few logins setup, so when the guest logs in, the password they enter is compared against the hash of every password in the system.
The Internet facing, or guest page, is simply a passphrase box. When a guest enters a correct password, the system will wait for a “ring” (for up to 5 minutes by default). The guest can then dial the buzzer code. When the modem detects the ring from the main entrance, the application will instruct it to answer the phone, dial 9, and hang up. The building’s entry system will then unlock the door, permitting the guest to enter.
- I’ve only tested with my primary PC (Ubuntu Linux / Intel x86)
- Node runtime
- I’ve only tested with a TRENDnet TFM-561U modem
- I’ve only tested in my building
Setup and Run:
- Get the code! You can download from GitHub, or clone the repository https://github.com/raudette/lockandkey.git
- Install Node and the required modules. In an Ubuntu Linux environment, this can be done as follows:
sudo apt-get install nodejs
sudo npm install express sqlite3 bcrypt-nodejs node-validator fs body-parser serialport
- You may also want to look at the PM2 process manager for Node – it makes it really easy to automatically start Node applications on boot up, and a dynamic DNS service such as the one provided by dyn.com to access your
- Review the lockandkeyconfig.json configuration file.
- port: The port used by the public web interface (configure your router to expose this port to the Internet)
- adminport: The port used by the administrative interface. This is used to configure accounts
- unlocktimeout: Length of time, following a successful login, for which the system will pick up the phone and dial 9.
- modemmanufacturerstring: The string used to identify the modem which should be used by the application. Use the Linux dmesg command after plugging in a USB modem to see the manufacture string associated with your device. Use Conexant for the TRENDnet TFM-561U.
- You can start the program by running
- With the default values, to setup accounts, you can access the administrative interface at:
and the door opening interface at:
Complete source code and build details: lockandkey.zip
I can see this particular project being useful to others – let me know if you have any suggestions. For example, let me know if there is interest in a Raspberry Pi SD card image, a simple phone Android/iPhone app to avoid book marking the website, improvements to security, mandatory HTTPS, or eliminating the need for a dynamic DNS service in a home environment.