I’ve recently started using ohmyzsh as a shell replacement on my Macbook at work. Lo and behold, I noticed that my numpad stopped working–it’s been an annoyance to say the least. I then stumbled on a post in which a user presented keybindings to put in one’s ~/.zshrc file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Keypad
# 0 . Enter
bindkey -s "^[Op" "0"
bindkey -s "^[Ol" "."
bindkey -s "^[OM" "^M"
# 1 2 3
bindkey -s "^[Oq" "1"
bindkey -s "^[Or" "2"
bindkey -s "^[Os" "3"
# 4 5 6
bindkey -s "^[Ot" "4"
bindkey -s "^[Ou" "5"
bindkey -s "^[Ov" "6"
# 7 8 9
bindkey -s "^[Ow" "7"
bindkey -s "^[Ox" "8"
bindkey -s "^[Oy" "9"
# + -  * /
bindkey -s "^[Ok" "+"
bindkey -s "^[Om" "-"
bindkey -s "^[Oj" "*"
bindkey -s "^[Oo" "/"

This has fixed the issue (and I’m sure that there are other ways of fixing the same problem–this one seems to be the easiest for me at the moment. I hope you’ll find it useful.

In my previous post, I noted that I had not yet managed to get multiple ghost blogs workig with SSL & caching. One blog, yes. Two or more, no. Well, I’ve managed to make a bit of progress and have things working. Here’s what I’m using now:

Getting Caching to Work

In Pedro Teixeira’s post, he had a setup working for a single blog, and there’s a single directive here that he’s set up:

1
2
3
proxy_pass So, while that will work just fine for an initial blog, you're going to have to name it something different in order to get Nginx to not complain. In my case, I just named it:

proxy_nameofmysite And ensured that this was consistent throughout the rest of my config. There are 5 instances of proxy_app present in his config. If you decide to use it, make sure that you change all 5 of those to whatever you choose to name your proxy directive. ##### SSL & Redirects This part took me a good few minutes to work out, and some insight from [serverfault](http://serverfault.com/questions/67316/in-nginx-how-can-i-rewrite-all-http-requests-to-https-while-maintaining-sub-dom) to get working properly. Here's the modification you need to make in order for this to work properly on your server:
1
2
3
4
5
6
7
8
9
server {
       listen         *:80;
       server_name    yoursite.com;
       return         301 https://$server_name$request_uri;
}

server {
    # Add support for SPDY and HTTPS
    listen *:443 ssl spdy;

I had initially included the server_name directive inside the server block containing the SSL directives, but realized that it was unnecessary. Just adding the above and making the necessary modifications should yield the results you need. After that, a reload should get you up and running without issues.

Cheers,

Aaron

I wanted to do a quick writeup on Pedro Teixeira’s ghost tuning post. Initially, I had stumbled across this, and wanted to share my success with at least getting this particular site to be a bit more performant. Per Pedro, I did an ApacheBench test with the following directives:

1
ab -c 500 -n 5000 http://aaronmsachs.com/

The results were the following (note: I did this test from my webhead):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# ab -c 500 -n 5000 http://aaronmsachs.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking aaronmsachs.com (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests


Server Software:        nginx
Server Hostname:        aaronmsachs.com
Server Port:            80

Document Path:          /
Document Length:        7722 bytes

Concurrency Level:      500
Time taken for tests:   100.588 seconds
Complete requests:      5000
Failed requests:        266
   (Connect: 0, Receive: 0, Length: 266, Exceptions: 0)
Write errors:           0
Non-2xx responses:      266
Total transferred:      38024248 bytes
HTML transferred:       36605424 bytes
Requests per second:    49.71 [#/sec] (mean)
Time per request:       10058.837 [ms] (mean)
Time per request:       20.118 [ms] (mean, across all concurrent requests)
Transfer rate:          369.16 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    4  10.6      0      43
Processing:     0 9671 2495.1  10438   13309
Waiting:        0 9671 2495.1  10438   13309
Total:          0 9675 2494.0  10438   13333

Percentage of the requests served within a certain time (ms)
  50%  10438
  66%  10534
  75%  10588
  80%  10616
  90%  10732
  95%  10803
  98%  11766
  99%  12489
 100%  13333 (longest request)

As you can see, it’s a bit rough. 100 seconds to serve up all those requests, and a mean time of 2494ms. Meh, it could be better. So with the tuning:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# ab -c 500 -n 5000 http://aaronmsachs.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking aaronmsachs.com (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests


Server Software:        nginx
Server Hostname:        aaronmsachs.com
Server Port:            80

Document Path:          /
Document Length:        2784 bytes

Concurrency Level:      500
Time taken for tests:   0.658 seconds
Complete requests:      5000
Failed requests:        0
Write errors:           0
Total transferred:      15446508 bytes
HTML transferred:       14025792 bytes
Requests per second:    7603.83 [#/sec] (mean)
Time per request:       65.756 [ms] (mean)
Time per request:       0.132 [ms] (mean, across all concurrent requests)
Transfer rate:          22939.98 [Kbytes/sec] received
 29     location ~ ^/(?:ghost/api) {

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    9   6.2      8      36
Processing:     5   13   8.6     11     217
Waiting:        4   10   8.2      9     215
Total:         12   22  13.1     18     226

Percentage of the requests served within a certain time (ms)
  50%     18
  66%     19
  75%     19
  80%     19
  90%     53
  95%     59
  98%     59
  99%     59
 100%    226 (longest request)

Daaaaaaaayuuuuuummmmmm! That’s fast! I mean, BLISTERINGLY quick! My hat off to Pedro–this bit of tweaking made some serious difference. I do want to give you a few of the gotchas that I ran across:

  • Nginx loads the config files (in my case, I have ~10) in alphabetical order. I was receiving the error:

    service nginx restart nginx: [emerg] the size 104857600 of shared memory zone “APP” conflicts with already declared size 0 in /etc/nginx/conf.d/cache.conf:2 nginx: configuration file /etc/nginx/nginx.conf test failed

    After discussing the issue with Pedro, he recommended looking over the following http://forum.nginx.org/read.php?2,9716,9716#msg-9716. This indicated that the config files may have been being loaded in the incorrect order, and that was the result of the error. Changing the name of cache.conf to 01cache.conf resolved the issue.

  • You may notice that if you blindly copy and paste, that you won’t be able to access your admin area. To fix this, either create the auth file specified in the config you pull from Pedro, or comment it out if you don’t need the added security. Restart nginx & you should be good to go

Some other things to note: I’ve not been able to get this to work across multiple ghost sites (I’m currently in a training class, so my attention’s a bit divided). Once I’ve been able to work this out, I’ll post what I have. In the mean time, give this a shot and let me know your results.

Cheers,

Aaron

EDIT: I now have multiple ghost blogs working (w/ SSL & caching). For the added stuff you need to add to your configs, check out the article here.

Just playing around with my spark core. I’ve managed to get a rudimentary motion detection system set up on it using code from Frenzy’s instructable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* 
 * //////////////////////////////////////////////////
 * //making sense of the Parallax PIR sensor's output
 * //////////////////////////////////////////////////
 *
 * Switches a LED according to the state of the sensors output pin.
 * Determines the beginning and end of continuous motion sequences.
 *
 * @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
 * @date:   3. September 2006 
 *
 * kr1 (cleft) 2006 
 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/
 *
 *
 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 
 * (http://www.parallax.com/detail.asp?product_id=555-28027)
 *
 * The sensor's output pin goes to HIGH if motion is present.
 * However, even if motion is present it goes to LOW from time to time, 
 * which might give the impression no motion is present. 
 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 
 * assuming continuous motion is present during these phases.
 *  
 */

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000;  

boolean lockLow = true;
boolean takeLowTime;  

int pirPin = 0;    //the digital pin connected to the PIR sensor's output
int ledPin = 1;


/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop(){

     if(digitalRead(pirPin) == HIGH){
       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         delay(50);
         }         
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){       
       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           delay(50);
           }
       }
  }

Here’s the wiring setup:

Pics:

The cool thing is that you can see the motion being detected by opening up Spark’s serial monitor:

So far, it’s pretty cool, and works as expected. Gonna see what else I can make it do.

This is more of a reference for me than it is anything else, but if you’ve stumbled upon it, and find it useful, please feel free to use.

In this case, I’m commenting out a large block of text in VIM. To do this:

  1. CTRL+v
  2. Arrow/move down the desired number of blocks
  3. Shift+I to insert
  4. sign to comment out multiple lines

  5. ESC
  6. Wait a moment, and the character is entered
  7. wq and we’re off

Take from Pixelbeat’s answer in Stackoverflow.