├── 12742838_10209047086800681_4717628274478051458_n.jpg ├── 608_10209047086560675_6615119933942145195_n.jpg ├── README.md ├── TM1637.jpg ├── back.jpg ├── front.jpg ├── grepRERA.png └── license.png /12742838_10209047086800681_4717628274478051458_n.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/12742838_10209047086800681_4717628274478051458_n.jpg -------------------------------------------------------------------------------- /608_10209047086560675_6615119933942145195_n.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/608_10209047086560675_6615119933942145195_n.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### update 2 | 3 | 2017 : Now, the RATP Group is letting everyone access their realtime API : I will release a proper code and tutorial for this project ASAP. 4 | 5 | #Paris Dashboard ⚡️ 6 | 7 | 🌀 Display the Paris Metro schedules 🚉 and the number of Velibs 🚲 (bicycle-system) available just near my home 😌. 8 | 9 | ![](front.jpg) 10 | 11 | ## Requirements 👜 12 | 13 | You need an Arduino board 💎 with PWM and Digital outputs. 14 | As "4-digit 7-segment display" 💫 I bought 3x TM1637 (3*~8€), which requires 1x PWM intput (CLK), 1x Digital intput (DIO) and 5V input for each. 15 | 16 | ![](back.jpg) 17 | 18 | ![](TM1637.jpg) 19 | 20 | 21 | It's very easy to communicate 📢 with a TM1637. 22 | 23 | ``` 24 | #include "TM1637Display.h" 25 | #define CLK_TM1637 7 26 | #define DIO_TM1637 42 27 | TM1637Display tm1637(CLK_TM1637,DIO_TM1637); 28 | 29 | void setup() 30 | { 31 | tm1637.setBrightness(0x0f); 32 | tm1637.showNumberDec(1337,false,4,0); 33 | } 34 | void loop() { 35 | } 36 | ``` 37 | using this [library](https://github.com/avishorp/TM1637). 38 | 39 | To communicate with my Arduino board, I use simply the ```screen``` shell function 💻. 40 | 41 | ## How it works ? 42 | 43 | ### Get RATP schedules 📋 and alerts 💩 in realtime 🌟 44 | 45 | #### GTFS Data 46 | 47 | Definition from Wikipedia (en) 48 | > A GTFS feed is a collection of CSV files (with extension .txt) contained within a .zip file. Together, the related CSV tables describe a transit system's scheduled operations. The specification is designed to be sufficient to provide trip planning functionality, but is also useful for other applications such as analysis of service levels and some general performance measures. GTFS only includes scheduled operations, and does not include real-time information. 49 | 50 | ##### Downloads 51 | 52 | - [STIF GTFS](http://opendata.stif.info/explore/dataset/offre-horaires-tc-gtfs-idf/table/) - all the STIF schedules for 3 next weeks (70MB compressed, +500MB uncompressed) 53 | - [RATP GTFS FULL](http://dataratp.opendatasoft.com/explore/dataset/offre-transport-de-la-ratp-format-gtfs/) - all the annual schedules 54 | - [RATP GTFS LINES](http://dataratp.download.opendatasoft.com/RATP_GTFS_LINES.zip) - a smaller package, divided by line 55 | 56 | It's a little bit difficult to understand how the data is linked 🔬, but you will find the *station-id* of your station in `stops.txt`, all the *stop schedules* (but not the full date, just hh:mm:ss) of your station in `stop_times.txt` (and all the trips).. 57 | 58 | ##### Parser 59 | 60 | I recommend to use a parser to aggregate the data. I extracted them with ["Node-GTFS"](https://github.com/brendannee/node-gtfs) which contains a lot of methods to query for agencies, routes, stops and times. But you can easily find another one in another language. 61 | 62 | #### Real time 63 | 64 | To detect if an issue happened 🔶, you can use the [Twitter Streaming API](https://dev.twitter.com/streaming/overview) and get all the new tweets of one RATP line. 65 | As they always use the same sentences, you will be able to detect if there is a problem or not, or when it has disappeared. 66 | 67 | This example will print the new tweets from *TWEET\_ID\_RATP\_LINE* using [TwitterAPI](https://github.com/geduldig/TwitterAPI) (python) 68 | 69 | ```python 70 | api = TwitterAPI(consumerKey,consumerSecret,accessToken, accessTokenSecret) 71 | 72 | r = api.request('statuses/filter', {'follow': TWITTER_ID_RATP_LINE }) 73 | 74 | for item in r: 75 | print(item['text'] if 'text' in item else item) 76 | ``` 77 | 78 | When there is a new tweet, you have to check 👓 what is happening. 79 | Check if it contains words that refer to an issue ( "colis", "ralenti", "interrompu") or an end of issue ("Retour", "reprise", "régulier" ) or other thing. 80 | 81 | Those words can be found by analyzing what are the most used words by the community manager. 82 | 83 | You can get the 💯x most used words in a file with : 84 | 85 | ```bash 86 | tr -c '[:alnum:]' '[\n*]' < file.txt | sort | uniq -c | sort -nr | head -100 87 | ``` 88 | 89 | *Just save a html page with a lot of tweets of one RATP line account and fire that query.* 90 | 91 | They always use the same sentences 😊 : 92 | 93 | ![grep RER A](grepRERA.png) 94 | 95 | Twitter accounts : 96 | 97 | - [RER A](https://twitter.com/RERA_RATP) 98 | - [RER B](https://twitter.com/RERB) 99 | - [RER C](https://twitter.com/RERC_SNCF) 100 | - [RER D](https://twitter.com/RERD_SNCF) 101 | - [RER E](https://twitter.com/RERE_SNCF) 102 | - [Line 1](https://twitter.com/Ligne1_RATP) 103 | - [Line 2](https://twitter.com/Ligne2_RATP) 104 | - [Line 3](https://twitter.com/Ligne3_RATP) 105 | - [Line 4](https://twitter.com/Ligne4_RATP) 106 | - [Line 5](https://twitter.com/Ligne5_RATP) 107 | - [Line 6](https://twitter.com/Ligne6_RATP) 108 | - [Line 7](https://twitter.com/Ligne7_RATP) 109 | - [Line 8](https://twitter.com/Ligne8_RATP) 110 | - [Line 9](https://twitter.com/Ligne9_RATP) 111 | - [Line 10](https://twitter.com/Ligne10_RATP) 112 | - [Line 11](https://twitter.com/Ligne11_RATP) 113 | - [Line 12](https://twitter.com/Ligne12_RATP) 114 | - [Line 13](https://twitter.com/Ligne13_RATP) 115 | - [Line 14](https://twitter.com/Ligne14_RATP) 116 | - [Tram 1](https://twitter.com/T1_RATP) 117 | - [Tram 2](https://twitter.com/T2_RATP) 118 | - [Tram 3A](https://twitter.com/T3a_RATP) 119 | - [Tram 3B](https://twitter.com/T3b_RATP) 120 | - Tram 4 (no account) 121 | - [Tram 5](https://twitter.com/T5_RATP) 122 | - [Tram 6](https://twitter.com/T6_RATP) 123 | - [Tram 7](https://twitter.com/T7_RATP) 124 | - [Tram 8](https://twitter.com/T8_RATP) 125 | 126 | 127 | 128 | 129 | #### Wap 💥 130 | You can "grep" the RATP wap site, but it's clearly not adviced ❗️ - the "CheckMyMetro" app got a lot of issues using this way with RATP. 131 | 132 | ```bash 133 | curl --silent -A "Mozilla/5.0" "http://wap.ratp.fr/{YOURURI}" 2>&1 | grep -E -o "([0-9]+) mn" 134 | ``` 135 | 136 | 137 | 138 | ### Get the number of available bikes 🚲 in a Velib station 139 | 140 | ✏️ Register an account [here](https://developer.jcdecaux.com) and get an API key 🔑. 141 | 142 | You can get what you want with a simple query (edit *STATIONID* and *KEY*) : 143 | 144 | ```bash 145 | URL_VELIB="https://api.jcdecaux.com/vls/v1/stations/{STATIONID}?contract=paris&apiKey={KEY}" 146 | curl --silent "$URL_VELIB" 2>&1 \ 147 | | grep -E -o "\"available_bikes\":[0-9]+," | \ 148 | | awk -F ':' '{ print $2 }' | cut -d , -f1; 149 | ``` 150 | 151 | 152 | ## About 👀 153 | 154 | 🙏 Special Thanks to : Pupanimbas, Wyb0t, Mathemagie, FrançoisG, E-S, & difrrr. 155 | 156 | If you have any question, open an issue. 157 | 158 | M.Berchon invited me to introduce this project at the « Paris Hardware Startup Meetup #2 » 159 | 160 | ![Paris Hardware Startup Meetup #2](./608_10209047086560675_6615119933942145195_n.jpg) 161 | ![Paris Hardware Startup Meetup #2](./12742838_10209047086800681_4717628274478051458_n.jpg) 162 | 163 | ![License](./license.png) 164 | -------------------------------------------------------------------------------- /TM1637.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/TM1637.jpg -------------------------------------------------------------------------------- /back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/back.jpg -------------------------------------------------------------------------------- /front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/front.jpg -------------------------------------------------------------------------------- /grepRERA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/grepRERA.png -------------------------------------------------------------------------------- /license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibaaj/Paris-Dashboard/536cb3b7d0bc8543a434a10e9120cd7339170b77/license.png --------------------------------------------------------------------------------