Original Project: https://github.com/nfatkhiyev/letMeIn/
LetMeIn2 is a completely new re-write of LetMeIn that focuses on scalability and maintainability, while keeping cost-per-unit as low as possible. Current development uses the Tiny S2 to reduce costs.
A user, let's say Alice, visits the website, she selects a floor. Her phone POSTs to the server specifying where she is. The server will send an MQTT message on the letmein2/req topic with Alice's location. This will cause all letmein devices on floor to light up and make noise, indicating Alice's location. There will also be a message with an action button sent in Slack, listening for any updates to the request. Alice's phone will redirect her to a waiting screen (/anybody_home) that does another POST request (could be a GET) that waits for the server to give her a 200 response. On the backend, two things could happen: One is that someone on floor could hit one of the buttons (or respond by pressing the button in Slack) and go get her. That causes another MQTT message on the letmein2/ack topic, which answer's Alice's phone with a 200 message, and she's notified that someone is coming for her. The other is that nobody is there to answer the box (or maybe they don't like Alice), and after a set amount of time, the server sends Alice's phone a 408 message, and will send out a timeout message on the letmein2/ack topic.
Server: The LetMeIn2 server, presumably running in a container on OKD.
Guest: The person/device/browser trying to connect to the Server.
Knock: Noun/Verb. A request to be let in, or the act of making a request to be let in.
Client: The embedded device that subscribes to the letmein2/req
topic and listens for when a Gurst knocks
To subscribe to the Server as a Client, use this:
mosquitto_sub -h mqtt.csh.rit.edu -t letmein2/ack -t letmein2/req
You could also set up an app like MQTT Explorer
(Works on Mac and Linux. If you're using Windows, please stop.)
In production, the Server is deployed to OKD.
Check the /site
directory for instructions on how to run the Server.
Check the /embedded
directory for instructions on how to work on the Clients.
You can use a program like minicom
to connect a serial console.
You'll need:
- 5x Through-hole LEDs, any color, I used green. (Something like this)
- 1x E-Switch LS085R100F160C1A along with an arcade button
- 1x Pushbutton (like, one of those smol bois)
- 1x Piezo Buzzer
- 1x Tiny S2
For the LED connectors:
- 1x 10 2.54mm pitch Position Header
- 1x 10 2.54mm pitch Position Header (male)
This connector sucks. You should only need six headers to make the thing work. I hooked five of them up to GND when I was young and reckless.
Optional:
- 5x 680 ohm resistors for the LEDs (if you need to dim them)
If you'd like to socket your TinyS2, use these:
Connect the button switch to COM and NO so that when the switch is closed, the circuit is completed and the button press is registered.
Returns the homepage
Returns any relevant info that a client should be aware of. Currently only returns the current timeout period of the server.
Prompts a server to publish a request for a particular door.
Cancels a request that a client sends to the server.
Awaits an answer to a request made via the /request/:location
route.
Prompts a server to set up a "KnockSession" (not a real thing) that publishes a request on the MQTT network and opens a websocket connection with the client
A topic meant for sending requests to the LetMeIn network. The payload should be a location that is registered in the app. The app should have a location_map
defined. That looks like this:
var location_map = map[string]string{
"n_stairs": "North Side Stairwell",
"s_stairs": "South Side Stairwell",
"level_a": "Level A Elevator Lobby",
"level_1": "Level 1 Elevator Lobby",
"l_well": "L Well",
}
So, for example, you could publish on topic letmein2/req
with payload level_1
to indicate to the devices that you're waiting to be let in on the NRH Level 1 Elevator Lobby.
A topic meant for letting Clients acknowledge a Knock. The payload should be the location/ID of the device acknowledging. These aren't in a database anywhere, but they ought to be.
Note the Slack location in the client map, this will be used to send dynamic messages in Slack when a Knock is received or modified.
var client_map = map[string]string {
"usercenter": "User Center",
"lounge": "Lounge",
"luser": "Luser Center",
"software": "Software Room",
"server": "Server Room",
"slack": "Slack"
}
For example, you could publish on letmein2/ack
with payload usercenter
to let a waiting Guest know that you've heard their Knock and are coming to let them in.
A topic for notifying all Clients that a Knock is being cancelled. The payload should be a location from the above location_map
.
If you publish on topic letmein2/nvm
with payload s_stairs
, that indicates that any pending Knock originating from the South Side Stairwell should be ignored (and that Clients should turn their lights/sound off!)
Upon receiving any of these requests, the server will also send a Slack message to a predefined channel in a Slack workspace. The message it sends will also have a Rescue button, which will allow you to send a letmein/ack
back, completing the request. Basically an acknowledge button but for lazy people who don't want to go to the button itself. The message will also self-update when a) the knock is acknowledged, b) the knock is timed out, or c) the knock is cancelled.
Ensure that the application is given the scope connections:write
, and make sure it is added to the channel (/invite <app_name>
or @<app_name>
).
To set up 2 way messaging, you need to define a Request URL (your_server_url/actions
) within your Slack bot's settings . You can find this setting at App Homepage >> Your_App >> Interactivity & Shortcuts (under Features) >> Interactivity >> Request URL. Make sure Interactivity is toggled 'On,' and that your request URL uses HTTPS. If you don't do this, the Rescue button does not do anything.