Fire Fighters Friend

1,126

7

7

Posted

Introduction: Fire Fighters Friend

Idea and Inspiration

Firefighters often start helping from the floor that caused the fire, but this incident proved that it may not be the floor with maximum causalities. That got me thinking: What if firefighters could go to the floor that needed the most help first and as a result, saves more people! I was determined to do something that can empower firefighters to do their job optimally, aka save more people.

So with that, let's get started!

Step 1: THINGS USED IN THIS PROJECT

Hardware components:

  • Walabot×1
  • Raspberry Pi 3 Model B×1
  • Amazon Alexa Echo Dot×1

Software apps and online services:

  • Microsoft
  • WindowsWalabot API

Hand tools and fabrication machines:

  • Keyboard
  • Mouse
  • Monitor
  • Router

Step 2: RASPBERRY PI:

The Raspberry Pi part of this project is easy to set up. Simply install the required components and run the python file.

I used Ubuntu Mate as I tested on an Ubuntu computer originally and did not want to edit and modify that much code. First, go to the Walabot Site and download the Raspberry Pi SDK and install using gDebi.

Next, Install the required python packages

pip install enum<br>pip install requests 
cd /usr/share/walabot/python
pip install WalabotAPI-1.0.21.zip 																				

Next, plug in the Walabot via USB

Next, paste this code into "firefury.py", With that, you are all set up on the Raspberry Pi:

<p>from __future__ import print_function  <br>from sys import platform 
from os import system 
from imp import load_source 
from enum import Enum 
from os.path import join 
import time 
import requests 
import json 
if platform == 'win32': 
   modulePath = join('C:/', 'Program Files', 'Walabot', 'WalabotSDK', 
       'python', 'WalabotAPI.py') 
elif platform.startswith('linux'): 
   modulePath = join('/usr', 'share', 'walabot', 'python', 'WalabotAPI.py')     
import WalabotAPI as walabotAPI 
walabotAPI.Init() 
wlbt = load_source('WalabotAPI', modulePath) 
wlbt.Init() 
def PrintTrackerTargets(targets): 
   system('cls' if platform == 'win32' else 'clear') 
   if targets: 
       for i, target in enumerate(targets): 
           print(('y: {}'.format(target.yPosCm))) 
   else: 
       print('No Target Detected') 
class Placement(Enum): 
   Empty = 0  
   Back = 1  
   Front = 2   
class State(Enum): 
   Idle = 0  
   Bi = 1   
   Fi = 2   
   Bo = 3   
   Fo = 4  
def _get_placement(targets): 
   if len(targets) is 0: 
       return Placement.Empty 
   if targets[0].yPosCm > 0: 
       return Placement.Front 
   if targets[0].yPosCm <= 0: 
       return Placement.Back 
class PeopleCounter: 
   def __init__(self): 
       self.placement = Placement.Empty 
       self.state = State.Idle 
       self.count = 0 
       self.state_machine = { 
           State.Idle: 
               {Placement.Empty: State.Idle, 
                Placement.Back: State.Bi, 
                Placement.Front: State.Fo}, 
           State.Bi: 
               {Placement.Empty: State.Idle, 
                Placement.Back: State.Bi, 
                Placement.Front: State.Fi}, 
           State.Fi: 
               {Placement.Empty: State.Idle, 
                Placement.Back: State.Bi, 
                Placement.Front: State.Fi}, 
           State.Fo: 
               {Placement.Empty: State.Idle, 
                Placement.Back: State.Bo, 
                Placement.Front: State.Fo}, 
           State.Bo: 
               {Placement.Empty: State.Idle,   
                Placement.Back: State.Bo, 
                Placement.Front: State.Fo}, 
       } 
   def update_state_get_count(self, targets): 
       self.placement = _get_placement(targets) 
       prev_state = self.state 
       self.state = self.state_machine[self.state][self.placement] 
       if prev_state == State.Bo and self.state == State.Idle: 
           self._decrement() 
       elif prev_state == State.Fi and self.state == State.Idle: 
           self._increment() 
       return self.count 
   def _increment(self): 
       self.count += 1 
       return State.Idle 
   def _decrement(self): 
       self.count = max(self.count - 1, 0) 
       return State.Idle 
def PeopleCounterApp(): 
   people_counter = PeopleCounter() 
   rArenaMin, rArenaMax, rArenaRes = 5, 120, 5 
   phiArenaMin, phiArenaMax, phiArenaRes = -60, 60, 3 
   thetaArenaMin, thetaArenaMax, thetaArenaRes = -20, 20, 10 
   walabotAPI.SetSettingsFolder() 
   walabotAPI.ConnectAny() 
   walabotAPI.SetProfile(wlbt.PROF_SENSOR) 
   walabotAPI.SetArenaR(rArenaMin, rArenaMax, rArenaRes) 
   walabotAPI.SetArenaPhi(phiArenaMin, phiArenaMax, phiArenaRes) 
   walabotAPI.SetArenaTheta(thetaArenaMin, thetaArenaMax, thetaArenaRes) 
   walabotAPI.SetDynamicImageFilter(walabotAPI.FILTER_TYPE_MTI) 
   walabotAPI.Start() 
   try: 
       num_of_people = 0 
       while True: 
            #Checks how many people there are
           walabotAPI.Trigger() 
           targets = walabotAPI.GetSensorTargets() 
           print (targets) 
           targets1 = len(walabotAPI.GetSensorTargets()) 
           Address = "75 Mountain Street, Brockton, CA" 
           floor = 3 
           Room = "12A" 
           payload={'Address':Address, 'floor' : floor, 'Room' : Room, 'Peeps': targets1} 
           r=requests.post("
           targets = sorted(targets, key=lambda x: x.zPosCm, reverse=True) 
           prev_num_of_people = num_of_people 
           num_of_people = people_counter.update_state_get_count(targets) 
           if prev_num_of_people != num_of_people: 
               print('# {} #\n'.format(num_of_people)) 
           time.sleep(1) 
   except KeyboardInterrupt: 
       pass 
   finally: 
       walabotAPI.Stop() 
       walabotAPI.Disconnect() 
   print('Terminated successfully!') 
if __name__ == '__main__': 
   PeopleCounterApp()    </p><p style="margin-left: 20px;"></p>

Step 3: Windows Server Deployment:

Since we want this program to only be administrable by Fire Department Admins, we are making all our servers and skills in their control therefore, in real deployment, you should not publish your skills.

You can use ngrok to create a static URL for localhost:5000 like I did. That way even if your computer gets a new IP address, you can still post the same URL

First, go to the MySQL Server site and download MySQL Server for Windows. Then, install it. Next, Install the required python packages

pip install flask
pip install flask_cors pip install pymysql pip install flask_sqlalchemy pip install flask_ask pip install pymysql

Next, create a new file called app1.py and paste the following code in:

from flask import Flask
from flask import request from flask_cors import CORS import json import requests import pymysql app = Flask(__name__) CORS(app) app.config["DEBUG"] = True db = pymysql.connect(host='localhost',port=3306,user='root',passwd='Srivibhu10',db='users') @app.route('/post', methods=['POST']) def Us(): Given_Address = request.json['Address'] Given_floor = request.json['floor'] Given_Room = request.json['Room'] Given_Peeps = request.json['Peeps'] cursor = db.cursor() select_Address = ("select count(*) from users.user where Address=%s ") select_Addrss_Floor = ("select count(*) from users.user where Address=%s and floor=%s") select_Addrss_Floor_Room = ("select count(*) from users.user where Address=%s and floor=%s and Room=%s") if len(Given_Address) > 0 and len(Given_floor) > 0 and len(Given_Room) > 0 and Given_Peeps != "0": #check if all values are present in database check_allfields=(Given_Address,Given_floor,Given_Room) cursor.execute(select_Addrss_Floor_Room,check_allfields) rows = cursor.fetchone() if rows[0] > 0: Update_noofpeople = ("UPDATE users.user set Peeps= %s where Address=%s and Floor=%s and Room=%s") updated_data=(Given_Peeps,Given_Address,Given_floor,Given_Room) cursor.execute(Update_noofpeople,updated_data) db.commit() cursor.close() return ("Hi..Updated") else: # Add new record Insert_newrecord=("Insert into users.user(Address,floor,Room,Peeps) VALUES (%s,%s,%s,%s)") Insert_allfields=(Given_Address,Given_floor,Given_Room,Given_Peeps) cursor = db.cursor() cursor.execute(Insert_newrecord,Insert_allfields) db.commit() cursor.close() return ("Hi....Inserted") else: return ("Hi in ELSE BLOCK ....") def GetPeopleCounts(Address): #return (Address) Input_Address = Address # check if this record is already present select_noofrows=("select floor,sum(peeps) from users.user where UPPER(Address)=UPPER(%s) group by floor order by sum(peeps) desc") cursor = db.cursor() cursor.execute(select_noofrows,Input_Address) #print(cursor.description) if cursor.rowcount > 0: #data = cursor.fetchall() return_msg = "Number of people in each floor at this address " for row in cursor: return_msg = return_msg + " Floor "+row[0]+" People "+str(int(row[1])) return (return_msg) ''' for row in cursor: #print(row) return(row) ''' else: return("No Records Found") db.commit() cursor.close() if __name__ == '__main__': app.run()

Step 4: Alexa Skill:

To finish our project off, lets create a skill leading to our flask_ask skill

Only the launch_intent matters to us. When the app launches, it immediately asks for the address, returns the values, and then quits out. This is a measure of saving time.

Lets create our Flask_Ask program now:
Simply create a file called flaskaskpy.py and paste the following code in:

If you are running this program off localhost, you should use Ngrok and forward port 5001

from flask import Flask
from flask_ask import Ask, request, session, question, statement from flask_cors import CORS import json from app1 import GetPeopleCounts app = Flask(__name__) ask = Ask(app, '/') app.config["DEBUG"] = True @ask.launch def launch(): speech_text = "What Address to check" return question(speech_text) @ask.intent('MainIntent') def MainIntent(Address): #return statement("{}".format(Address)) #print (GetPeopleCounts("{}".format(Address))) return statement(GetPeopleCounts("{}".format(Address))) if __name__ == '__main__': app.run(debug=True, port = 5001)

Step 5: Skill Creation:

Simply create a skill called fire fury and fill out the fields as Given in picture, after that, we can finally test out our device! Example Conversation: Human: "Alexa, open fire fury"Alexa: "Which address do you want to check?"Human: "75 Mountain Street, Brockton, CA"Alexa: "Floor 3 People 8, Floor 6 People 3, Floor 8 People 2, Floor 7 People 1 ".

Step 6: SCHEMATICS:

How the Architecture Works

1) The Walabot connected to the raspberry pi posts information to the server

2) The server stores the information in a MySQL Database

3) The Alexa intent is placed through the dash wand

4) It goes through the Alexa Skills Kit and the intent is passed to the server

5) The server calculates the amount of people on each floor and returns the floors in order of most people to least people

6) Emergency Services can save the most lives

Step 7: Raspberry Pi Walabot CodePython:

This is the code that connects the Walabot to the Raspberry Pi and sends requests to the server:

flaskaskpy.py Python

<p>from flask import Flask<br>from flask_ask import Ask, request, session, question, statement
from flask_cors import CORS
import json
from app1 import GetPeopleCounts</p><p>app = Flask(__name__)
ask = Ask(app, '/')
app.config["DEBUG"] = True</p><p>@ask.launch
def launch():
    speech_text = "Dibhu check"
    return question(speech_text)</p><p>@ask.intent('MainIntent')
def MainIntent(Address):
    #return statement("{}".format(Address))
    #print (GetPeopleCounts("{}".format(Address)))
    return statement(GetPeopleCounts("{}".format(Address)))</p><p>if __name__ == '__main__':
    app.run(debug=True, port = 5001)</p><p><strong>app1.pyPython</strong></p><pre><p>from flask import Flask<br>from flask import request
from flask_cors import CORS
import json
import requests
import pymysql</p><p>app = Flask(__name__)
CORS(app)
app.config["DEBUG"] = True
db = pymysql.connect(host='localhost',port=3306,user='root',passwd='Srivibhu10',db='users')</p><p>@app.route('/post', methods=['POST'])
def Us():
    Given_Address = request.json['Address']
    Given_floor = request.json['floor']
    Given_Room = request.json['Room']
    Given_Peeps = request.json['Peeps']</p><p>    cursor = db.cursor()</p><p>    select_Address =  ("select count(*) from users.user where Address=%s ")
    select_Addrss_Floor = ("select count(*) from users.user where Address=%s and floor=%s")
    select_Addrss_Floor_Room = ("select count(*) from users.user where Address=%s and floor=%s and Room=%s")</p><p>    if len(Given_Address) > 0 and len(Given_floor) > 0 and len(Given_Room) > 0 and Given_Peeps != "0":
        #check if all values are present in database
        check_allfields=(Given_Address,Given_floor,Given_Room)
        cursor.execute(select_Addrss_Floor_Room,check_allfields)
        rows = cursor.fetchone()
        if rows[0] > 0:
            Update_noofpeople = ("UPDATE users.user set Peeps= %s where Address=%s and Floor=%s and Room=%s")
            updated_data=(Given_Peeps,Given_Address,Given_floor,Given_Room)
            cursor.execute(Update_noofpeople,updated_data)
            db.commit()
            cursor.close()
            return ("Hi..Updated")
        else:
            # Add new record
             Insert_newrecord=("Insert into users.user(Address,floor,Room,Peeps) VALUES (%s,%s,%s,%s)")
             Insert_allfields=(Given_Address,Given_floor,Given_Room,Given_Peeps)
             cursor = db.cursor()
             cursor.execute(Insert_newrecord,Insert_allfields)
             db.commit()
             cursor.close()</p><p>             return ("Hi....Inserted")</p><p>    else:
        return ("Hi in ELSE BLOCK ....")</p><p>def GetPeopleCounts(Address):
    #return (Address)</p><p>    Input_Address = Address
    # check if this record is already present
    select_noofrows=("select floor,sum(peeps) from users.user where UPPER(Address)=UPPER(%s) group by floor order by sum(peeps) desc")
    cursor = db.cursor()
    cursor.execute(select_noofrows,Input_Address)
    #print(cursor.description)</p><p>    if cursor.rowcount > 0:</p><p>         #data = cursor.fetchall()
         return_msg = "Number of people in each floor at this address  "
         for row in cursor:
             return_msg = return_msg + "  Floor  "+row[0]+" People  "+str(int(row[1]))
         return (return_msg)
         '''
         for row in cursor:
            #print(row)</p><p>            return(row)
         '''
    else:
        return("No Records Found")</p><p>    db.commit()
    cursor.close()</p><p>if __name__ == '__main__':
    app.run()</p>

Step 8: Video of It Working With a Known & Unknown Address:

Share

    Recommendations

    • Science of Cooking

      Science of Cooking
    • Pocket-Sized Contest

      Pocket-Sized Contest
    • Microcontroller Contest

      Microcontroller Contest
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    Where does Alexa get these figures from? Who is reporting to Alexa how many people are on each floor? How is this data 'live' and accurate to the minute? When the fire occurs, how many people leave the building immediately, before emergency crews arrive? Can Alexa account for these people? It's all well and good to know how many people live in the building and on what floors before emergency crews arrive, but if 90% of those people get out of the building safely when the fire occurs, where do the emergency crews now have to concentrate their search efforts to find the remaining lost / trapped people?

    5 Comments

    Hi 2014pceevnecrishi,

    First let me say a good lot of effort was put into your idea and presentation.

    Now I must say; I have worked in both I.T. and Firefighting for 15+ years, so I have a lot to say about this instructable, the first being; things don't work the way you think they would in a compartment fire environment, where air and internal surface temperatures are typically above several hundred degrees. The Walabot may detect a mouse in your walls given the temperature difference between concrete / plaster etc. and a warm blooded mammal, but you must consider that a compartment fire will have heated the walls, and also the occupants, to nearly the same temperature, even down low near the floor. Human = only 37 degrees C. If the floor is not above 37 degrees, then there is not sufficient fire in the room for the occupants to even become trapped in the first place. They could likely still find the door and walk out. eg: stove / cooking fire.

    The greatest challenge for a firefighter, even when in the same room as trapped occupants and using some of the best thermal imaging cameras available to aid in search and rescue (because you cannot see through smoke, so you are looking for 'human' shapes and movement at best), is that the occupants and everything in the room are close to the same temperature.

    Try this paper (http://fire.nist.gov/bfrlpubs/fire02/PDF/f02082.pdf) for calculating room temperatures in compartment fires. A nutshell example: a 5m x 5m room with a 2m ceiling at flashover (roughly 3:30 minutes for a typical living room) will have an average air temperature in excess of 220 degrees C, which means down low (floor): around 70 degrees C. and up high (ceiling): over 700 degrees C.

    Think on that a little and see if you come up with some improvements on your concept. If you can fill some gaps, I'm sure rescue crews would be very interested ;)

    Could add an explanation of what the Walabot is and what role it plays in this project?

    Hi Ian01

    As Walabot is like heart of this project, actually walabot is a device having multi-functionalities like:

    1. See through objects

    2. People tracking and fall detection

    3. Distance & depth measurement

    4. Range measurement

    5. Breathing monitoring

    6. Basic directional info

    In case of my project, I am tracking People with the help of walabot, for more info am providing you walabot DIY link: https://walabot.com/diy

    That could be useful, that's a neat idea :)