├── stream_test.js ├── cpu_temp.py ├── README.md ├── LICENSE ├── actual_temp.py └── matrix_sensors.js /stream_test.js: -------------------------------------------------------------------------------- 1 | var IS = require('initial-state'); 2 | var bucket = IS.bucket('NodeJS SDK Example', 'YOUR_ACCESS_KEY_GOES_HERE'); 3 | 4 | // Push event to initial state 5 | bucket.push('Demo State', 'active'); 6 | 7 | setTimeout(function () { 8 | 9 | // Push another event 10 | bucket.push('Demo State', 'inactive'); 11 | 12 | }, 1000); 13 | -------------------------------------------------------------------------------- /cpu_temp.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from ISStreamer.Streamer import Streamer 3 | from time import sleep 4 | 5 | streamer = Streamer(bucket_name="Matrix Calibration", bucket_key="matrixcal", access_key="Your_Access_Key_Here") 6 | 7 | while True: 8 | cpu_temp = subprocess.check_output("vcgencmd measure_temp", shell=True) 9 | array = cpu_temp.split("=") 10 | array2 = array[1].split("'") 11 | 12 | cpu_tempf = float(array2[0]) * 9.0 / 5.0 + 32.0 13 | cpu_tempf = float("{0:.2f}".format(cpu_tempf)) 14 | streamer.log("CPU Temperature",cpu_tempf) 15 | print(cpu_tempf) 16 | sleep(300) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with the Matrix Creator - Sensor Box 2 | 3 | ![matrixmain](https://cloud.githubusercontent.com/assets/10930201/20942791/89e1e804-bbc2-11e6-9c4f-bb1e80c69b1b.png) 4 | 5 | A new add-on board for the Raspberry Pi is here and it is absolutely loaded with LEDs, sensors, and even a microphone array! Say hello to the stylishly circular [Matrix Creator](https://creator.matrix.one/#/index). It fits sleekly on top of your Raspberry Pi and conveniently looks like the top of the Amazon Echo ([which you can totally build with it](http://www.instructables.com/id/Build-a-DIY-Amazons-Alexa-With-a-Raspberry-Pi-and-/)). 6 | 7 | We're hear to get you up and running with the Matrix and also to show you how to stream all of its sensor data to Initial State! [Read more...](https://github.com/initialstate/matrix-creator-sensor-box/wiki) 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Initial State 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /actual_temp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright (c) 2014 Adafruit Industries 4 | # Author: Tony DiCola 5 | 6 | import Adafruit_DHT 7 | from ISStreamer.Streamer import Streamer 8 | from time import sleep 9 | 10 | # Sensor should be set to Adafruit_DHT.DHT11, 11 | # Adafruit_DHT.DHT22, or Adafruit_DHT.AM2302. 12 | sensor = Adafruit_DHT.DHT22 13 | 14 | # Example using a Raspberry Pi with DHT sensor 15 | # connected to GPIO 3. 16 | pin = 3 17 | 18 | streamer = Streamer(bucket_key="matrixcal", access_key="PLACE YOUR INITIAL STATE ACCESS KEY HERE") 19 | 20 | while True: 21 | # Try to grab a sensor reading. Use the read_retry method which will retry up 22 | # to 15 times to get a sensor reading (waiting 2 seconds between each retry). 23 | humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) 24 | 25 | # Note that sometimes you won't get a reading and 26 | # the results will be null (because Linux can't 27 | # guarantee the timing of calls to read the sensor). 28 | # If this happens try again! 29 | if humidity is not None and temperature is not None: 30 | 31 | temperatureF = 9.0/5.0*temperature+32 32 | streamer.log("Actual Temperature",temperatureF) 33 | print('Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity)) 34 | sleep(900) 35 | else: 36 | print('Failed to get reading. Try again!') 37 | -------------------------------------------------------------------------------- /matrix_sensors.js: -------------------------------------------------------------------------------- 1 | // Adapted from the Matrix-Creator-Malos repo 2 | 3 | // We connect to the creator with IP and port 4 | // The IP is the Pi's local IP 5 | // By default, MALOS has its 0MQ ports open to the world 6 | 7 | // Every device is identified by a base port. Then the mapping works 8 | // as follows: 9 | // BasePort => Configuration port. Used to config the device. 10 | // BasePort + 1 => Keepalive port. Send pings to this port. 11 | // BasePort + 2 => Error port. Receive errros from device. 12 | // BasePort + 3 => Data port. Receive data from device. 13 | 14 | // UNCOMMENT BELOW IF RUNNING FROM BOOT 15 | // function wait(ms){ 16 | // var start = new Date().getTime(); 17 | // var end = start; 18 | // while(end < start + ms) { 19 | // end = new Date().getTime(); 20 | // } 21 | // } 22 | // wait(60000); 23 | 24 | var creator_ip = '127.0.0.1' 25 | var creator_humidity_base_port = 20013 + 4 // port for Humidity driver. 26 | var creator_pressure_base_port = 20013 + (4 * 3) // port for Pressure driver. 27 | var creator_uv_base_port = 20013 + (4 * 4) // port for UV driver. 28 | var creator_imu_base_port = 20013 29 | 30 | var protoBuf = require("protobufjs") 31 | 32 | // Initial State SDK 33 | var IS = require('initial-state'); 34 | // Be sure to put your unique Access Key below 35 | var bucket = IS.bucket('Matrix Sensor Readings', 'Your_Access_Key_Here'); 36 | 37 | // Parse proto file 38 | var protoBuilder = protoBuf.loadProtoFile('/home/pi/matrix-creator-malos/protocol-buffers/malos/driver.proto') 39 | // Parse matrix_malos package (namespace). 40 | var matrixMalosBuilder = protoBuilder.build("matrix_malos") 41 | 42 | var zmq = require('zmq') 43 | 44 | 45 | // ********** Start error management. 46 | 47 | // Humidity sensor errors 48 | var errorSocketH = zmq.socket('sub') 49 | errorSocketH.connect('tcp://' + creator_ip + ':' + (creator_humidity_base_port + 2)) 50 | errorSocketH.subscribe('') 51 | errorSocketH.on('message', function(error_message) { 52 | process.stdout.write('Message received: Humidity error: ' + error_message.toString('utf8') + "\n") 53 | }); 54 | 55 | // Pressure sensor errors 56 | var errorSocketP = zmq.socket('sub') 57 | errorSocketP.connect('tcp://' + creator_ip + ':' + (creator_pressure_base_port + 2)) 58 | errorSocketP.subscribe('') 59 | errorSocketP.on('message', function(error_message) { 60 | process.stdout.write('Message received: Pressure error: ' + error_message.toString('utf8') + "\n") 61 | }); 62 | 63 | // UV sensor errors 64 | var errorSocketU = zmq.socket('sub') 65 | errorSocketU.connect('tcp://' + creator_ip + ':' + (creator_uv_base_port + 2)) 66 | errorSocketU.subscribe('') 67 | errorSocketU.on('message', function(error_message) { 68 | process.stdout.write('Message received: UV error: ' + error_message.toString('utf8') + "\n") 69 | }); 70 | 71 | // IMU sensor errors 72 | var errorSocketI = zmq.socket('sub') 73 | errorSocketI.connect('tcp://' + creator_ip + ':' + (creator_imu_base_port + 2)) 74 | errorSocketI.subscribe('') 75 | errorSocketI.on('message', function(error_message) { 76 | process.stdout.write('Message received: IMU error: ' + error_message.toString('utf8') + "\n") 77 | }); 78 | // ********** End error management. 79 | 80 | 81 | // ********** Start configuration. 82 | 83 | // Humidity sensor configuration 84 | var configSocketH = zmq.socket('push') 85 | configSocketH.connect('tcp://' + creator_ip + ':' + creator_humidity_base_port) 86 | var driverConfigProtoH = new matrixMalosBuilder.DriverConfig 87 | // 5 minutes between updates. 88 | driverConfigProtoH.delay_between_updates = 300.0 89 | // Stop sending updates 6 seconds after pings. 90 | driverConfigProtoH.timeout_after_last_ping = 6.0 91 | var hum_params_msg = new matrixMalosBuilder.HumidityParams 92 | // Real current temperature [Celsius] for calibration 93 | hum_params_msg.current_temperature = 23 94 | hum_params_msg.do_calibration = true 95 | driverConfigProtoH.set_humidity(hum_params_msg) 96 | // Send driver configuration. 97 | configSocketH.send(driverConfigProtoH.encode().toBuffer()) 98 | 99 | // Pressure sensor configuration 100 | var configSocketP = zmq.socket('push') 101 | configSocketP.connect('tcp://' + creator_ip + ':' + creator_pressure_base_port) 102 | // Now prepare valid configuration and send it. 103 | var driverConfigProtoP = new matrixMalosBuilder.DriverConfig 104 | // 5 minutes between updates. 105 | driverConfigProtoP.delay_between_updates = 300.0 106 | // Stop sending updates 6 seconds after pings. 107 | driverConfigProtoP.timeout_after_last_ping = 6.0 108 | configSocketP.send(driverConfigProtoP.encode().toBuffer()) 109 | 110 | // UV sensor configuration 111 | var configSocketU = zmq.socket('push') 112 | configSocketU.connect('tcp://' + creator_ip + ':' + creator_uv_base_port) 113 | // Send driver configuration. 114 | var driverConfigProtoU = new matrixMalosBuilder.DriverConfig 115 | // 5 minutes between updates. 116 | driverConfigProtoU.delay_between_updates = 300.0 117 | // Stop sending updates 6 seconds after pings. 118 | driverConfigProtoU.timeout_after_last_ping = 6.0 119 | configSocketU.send(driverConfigProtoU.encode().toBuffer()) 120 | 121 | // IMU sensor configuration 122 | var configSocketI = zmq.socket('push') 123 | configSocketI.connect('tcp://' + creator_ip + ':' + creator_imu_base_port) 124 | // Now prepare valid configuration and send it. 125 | var driverConfigProtoI = new matrixMalosBuilder.DriverConfig 126 | // 5 minutes between updates. 127 | driverConfigProtoI.delay_between_updates = 300.0 128 | // Stop sending updates 6 seconds after pings. 129 | driverConfigProtoI.timeout_after_last_ping = 6.0 130 | configSocketI.send(driverConfigProtoI.encode().toBuffer()) 131 | // ********** End configuration. 132 | 133 | 134 | // ********** Start updates - Here is where they are received. 135 | 136 | // Read from Humidity sensor 137 | var updateSocketH = zmq.socket('sub') 138 | updateSocketH.connect('tcp://' + creator_ip + ':' + (creator_humidity_base_port + 3)) 139 | updateSocketH.subscribe('') 140 | updateSocketH.on('message', function(buffer) { 141 | var hdata = new matrixMalosBuilder.Humidity.decode(buffer) 142 | // Print readings 143 | console.log(hdata) 144 | // Stream readings 145 | bucket.push(':sweat_drops:Humidity',hdata.humidity) 146 | bucket.push(':thermometer:Temperature',hdata.temperature) 147 | bucket.push('Temperature Raw',hdata.temperature_raw) 148 | }); 149 | 150 | // Read from Pressure sensor 151 | var updateSocketP = zmq.socket('sub') 152 | updateSocketP.connect('tcp://' + creator_ip + ':' + (creator_pressure_base_port + 3)) 153 | updateSocketP.subscribe('') 154 | updateSocketP.on('message', function(buffer) { 155 | var pdata = new matrixMalosBuilder.Pressure.decode(buffer) 156 | // Print readings 157 | console.log(pdata) 158 | // Stream readings 159 | bucket.push(':arrow_right::arrow_left:Pressure',pdata.pressure) 160 | bucket.push(':airplane_small:Altitude',pdata.altitude) 161 | bucket.push('Pressure Temperature',pdata.temperature) 162 | }); 163 | 164 | // Read from UV sensor 165 | var updateSocketU = zmq.socket('sub') 166 | updateSocketU.connect('tcp://' + creator_ip + ':' + (creator_uv_base_port + 3)) 167 | updateSocketU.subscribe('') 168 | updateSocketU.on('message', function(buffer) { 169 | var udata = new matrixMalosBuilder.UV.decode(buffer) 170 | // Print readings 171 | console.log(udata) 172 | // Stream readings 173 | bucket.push(':high_brightness:UV Index',udata.uv_index) 174 | bucket.push(':fire:UV Risk',udata.oms_risk) 175 | }); 176 | 177 | // Read from IMU sensor 178 | var updateSocketI = zmq.socket('sub') 179 | updateSocketI.connect('tcp://' + creator_ip + ':' + (creator_imu_base_port + 3)) 180 | updateSocketI.subscribe('') 181 | updateSocketI.on('message', function(imu_buffer) { 182 | var imuData = new matrixMalosBuilder.Imu.decode(imu_buffer) 183 | // Print readings 184 | console.log(imuData) 185 | // Stream readings 186 | bucket.push(':left_right_arrow:Yaw',imuData.yaw) 187 | bucket.push(':arrow_up_down:Pitch',imuData.pitch) 188 | bucket.push(':arrow_lower_left::arrow_upper_right:Roll',imuData.roll) 189 | }); 190 | // ********** End updates 191 | 192 | 193 | // ********** Ping the driver 194 | 195 | // Humidity driver 196 | var pingSocketH = zmq.socket('push') 197 | pingSocketH.connect('tcp://' + creator_ip + ':' + (creator_humidity_base_port + 1)) 198 | process.stdout.write("Sending pings every 5 seconds"); 199 | pingSocketH.send(''); // Ping the first time. 200 | setInterval(function(){ 201 | pingSocketH.send(''); 202 | }, 5000); 203 | 204 | // Pressure driver 205 | var pingSocketP = zmq.socket('push') 206 | pingSocketP.connect('tcp://' + creator_ip + ':' + (creator_pressure_base_port + 1)) 207 | //process.stdout.write("Sending pings every 5 seconds"); 208 | pingSocketP.send(''); // Ping the first time. 209 | setInterval(function(){ 210 | pingSocketP.send(''); 211 | }, 5000); 212 | 213 | // UV driver 214 | var pingSocketU = zmq.socket('push') 215 | pingSocketU.connect('tcp://' + creator_ip + ':' + (creator_uv_base_port + 1)) 216 | //process.stdout.write("Sending pings every 5 seconds"); 217 | pingSocketU.send(''); // Ping the first time. 218 | setInterval(function(){ 219 | pingSocketU.send(''); 220 | }, 5000); 221 | 222 | // IMU driver 223 | var pingSocketI = zmq.socket('push') 224 | pingSocketI.connect('tcp://' + creator_ip + ':' + (creator_imu_base_port + 1)) 225 | //process.stdout.write("Sending pings every 5 seconds"); 226 | pingSocketI.send(''); // Ping the first time. 227 | setInterval(function(){ 228 | pingSocketI.send(''); 229 | }, 5000); 230 | // ********** Ping the driver ends 231 | 232 | --------------------------------------------------------------------------------