Sunday, June 25, 2017

ESP01 with multiple DS18B20 Temperature sensors POSTing to ElasticSearch

I posted some code to github for getting two (or more) temperature sensors working with an esp01 and sending that data to Elasticsearch. I use this in my house to monitor the intake and output of my Air Conditioning unit. This lets me see how well it is performing. There are limitless other use cases where you may want to monitor temps over time though. So this is an extremely easy and cheap way to do so.

All you need is listed below:

  1. ESP01 module
  2. DS18B20 temperature sensors
  3. 4700 Ohm resistor
  4. Basic computer and electronics skills


https://github.com/jf7979/ESP8266-Dual-Temp-Sensors-Elasticsearch-API




This would be the simple way to hookup one (or more) sensors.


Splunk: Lookup PTR record for an IP address field

Here is a quick way to lookup an IP address PTR record in Splunk using a simple 'lookup' command. I use this with a dashboard panel for a pfsense index (my pfsense machine syslog's to Splunk). The downside is that this does lookups on a per search basis so the searches take a longer time to load. I find it best to limit the amount of IP's prior to doing a PTR lookup to save time.



lookup dnslookup clientip as source_ip OUTPUT clienthost as PTR


Just replace the "source_ip" with whatever the IP field is you want looked up, and PTR is just the new cosmetic name of the column it adds.

Here's an example:


Sunday, December 25, 2016

Mini Portable Temp/Humidity Sensor (ESP01 + DHT22 + LiPo Battery)

I like making sensors, I have a few projects at any given time dealing with some sort of sensors. I finished one today, enough to call it done for now that is. It uses a basic DHT22 sensor with an ESP01 wifi module. You can also use a DHT11 but the 22's cost a little more and offer better accuracy.

There are plenty of tutroials out there on how to do this. The sort of unique thing for mine is I wanted the data put in to an ElasticSearch instance I run. I'm all about sensors and storing info, and ElasticSearch has been great for that. So since I already have an ELK setup running for things like my Geiger Counter, Nest Thermostat, and Weather Underground data, I figured having my own little temp/humidity modules adding data would be a great spot.

The problem with most tutorials out there is that they focused on creating a webpage you go to, or posting data to some website that offers IOT services. So my version 1 of this included just making the ESP have a basic webpage with the available temperature and humidity information on it. It would just constantly loop checking the sensor and providing the connection. That wasn't ideal as that involves me to visit the webpage either manually or with a script. So I used a script for a while and it worked fine, but I still wanted them to be standalone objects where I didn't need to have static IP's for them or modify the script everytime I added or removed one.

So version 2 I sat down and finally figured out how to have the ESP module post data to a Logstash instance and get it imported in to Elasticsearch. Turns out it was pretty easy to do.


First the Hardware. This is the working version and it's compact. Not the prettiest but it works fine. Here's what's inside it and some rough prices.


  • ESP01 module - $2
  • DHT22 sensor module - $3
  • TP4056 LiPo Charger - $1.20
  • 100 mAh LiPo battery - $4
  • Micro USB prt on the TP4056 and a Male USB port added for power as well $0.20
  • On/Off Switch $0.02
  • A Diode to drop the voltage just a little to the ESP $0.01
So about $11 per module. Cheaper if you just use a 3.3 volt regulator on a USB port to power it. But I wanted a battery to make it portable (put it where you want to measure something like a car or garage).







You can plug it in to Micro USB....

Or plug it in to one of the readily available USB plugs and let it be.



Here's a basic chart of the data the module POSTs to ELK. The temp is high because it's sitting on my computer tower running in battery only mode right now. I'm trying to see the run time on it, and I'll hopefully update the next sentance once I get a time.





And the data that's being collected each POST and stored.






And here's the code. The few parts you'd want to change are probably the Node name of the module, and your Logstash instance IP/Port.


#include
#include

const char* ssid     = "SSID Home";
const char* password = "P@ssword";

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);



void setup() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  pinMode(LED_BUILTIN, OUTPUT);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
  }
  dht.begin();
}




void loop() {
  

  // Read humidity
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  WiFiClient client;

  String PostData = "{\"node\": \"LivingRoom\",\"humidity\": ";
  PostData += (float)h, 2;
  PostData += ",";
  PostData += "\"temp_c\": ";
  PostData += (float)t, 2;
  PostData += ",";
  PostData += "\"temp_f\": ";
  PostData += (float)f, 2;
  PostData += "}";


  const uint16_t port = 8080;
  const char* host = "192.168.1.18";

  if (client.connect(host, port)) {
    digitalWrite(LED_BUILTIN, LOW);
    client.println("POST /posts HTTP/1.1");
    client.println("Host: 192.168.1.18");
    client.println("Cache-Control: no-cache");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(PostData.length());
    client.println();
    client.println(PostData);
    client.stop();
    digitalWrite(LED_BUILTIN, HIGH);
  }

  delay(60000);

  
}






Friday, December 23, 2016

ESP8266 - Create tons of SSID's...with style

First off, the inspiration and most of the credit comes from this blog post. It gave me an idea to create a module that has some extended capabilities. So I set to work. And spoiler, I made it and it works fine.

Random SSID AP's are neat but the esp can do a lot more (more than I know how to do I'm sure). So I decided to add some features. Since there are 2 GPIO's and two states, I could come up with 4 variations in the actions of that script. So before building or coding anything, I decided what I wanted it to do (without knowing if it was even possible).


  • Mimic Mode - This would scan local access points and spoof them.
  • Static Mode - This would be a single static SSID that would be blasted out.
  • List Mode - This would be a similar to static, but from a preset list it loops through.
  • Random Mode - essentially the same thing as the blog post that inspired this.
First things first. I'm not that good with arduino and this is my first esp8266 project. But there are a lot of examples and truthfully, I'm pretty good a copy/pasting other peoples code and getting it to work how I want. So the code probably isn't the best and definitely isn't pretty. The only coding language I know is bash, so if anything it's probably written in more of a scripting way.

Here's the kicker from the original blog post. That's cool that one esp can do all those fake esp's, but what about more. What about.....8 :). What about.....16 :). Well that's what I decided to do. The module has 8-16 available sockets when plugged in. Here's a picture real quick so you know what it looks like as I continue to talk about it.


A few notes:
  • The LED display at the top is a pre-bought voltage meter. These are great and cheap (get them on eBay). Since the ESP modules are sensitive to voltage, I added one. 
  • Three slide switches.
    • Upper right - Power
    • Lower ones connect to the two GPIO pins and set the Mode of operation listed above
  • USB pcb plug bolted on
  • Right above the USB plug is a buck converter set to drop the 5 volts USB down to about 3.8 volts for the ESP modules
  • All of the sockets for the ESP's (2x4's) are all connected in parallel, which sucked to solder.


I said up to 16, why are there only 8 modules? Well, power. I used this with a USB power bank that is rated to provide up to 2.4 amps. That amperage is able to power 8 of them steadily, but not 16. That dips the voltage too much and most of the modules end up not starting up. So here's what I did. The back PCB plate with the other 8 sockets is removable. I did this by using 4 brass standoffs to separate the PCB's. With 4 posts, I could provide positive power, negative power, and the two GPIO pin settings. Just pinch the wire between the posts and it makes it easy to add the second board with sockets or remove it and have a blank board as a back. Bam, easy.



About the Code. 
The hardest thing to program was the Mimic Mode. This one scans for local access points to mimic. Scan, store, reproduce. But just mimicking isn't good enough. The SSID's need to be slightly different. This is because the exact same SSID's will normally jsut be grouped together. So I came up with a simple way to avoid this from happening for the host machines. Just add spaces. So here's what I did. When broadcasting any of the SSID's, every loop adds a space to teh SSID until it hits the max SSID length. So guest wifi will be guest wifi , guest wifi  , guest wifi   , guest wifi    , etc. Easy for a computer to tell the difference but near impossible to tell for a human. 

The GPIO settings. So the ESP (to start up properly) needs the gpio pins set to HIGH to start properly. Opposite from most things Arduino, OFF is HIGH and ON is LOW essentially. If the ESP starts with the GPIO pins LOW, it won't start at all and will end up in flash mode or something else. So in the VOID SETUP section, the modules wait 5 seconds after power on for the GPIO pins to be set, then reads them. One they are read, it sets the parameters for whatever mode is selected. 

The relevant code about the Mode selection (the delays were for some watchdog issues that may have been unrelated...):


  if (switchGPIO0 == HIGH && switchGPIO2 == HIGH)
  {
    mimicMode = true;
    scan = true;
    delay(1);
  }
  else if (switchGPIO0 == LOW && switchGPIO2 == HIGH)
  {
    randomMode = true;
    delay(1);
  }
  else if (switchGPIO0 == HIGH && switchGPIO2 == LOW)
  {
    listMode = true;
    delay(1);
  }
  else //(switchGPIO0 == LOW && switchGPIO2 == LOW)
  {
    staticMode = true;
    delay(1);
  }


So by having each pin in a given on/off position, you have 4 modes it can be configured to do. Since mimic mode is the coolest mode, and the pin defaults are HIGH, that's the defaulkt mode if no switches are toggled.

Really that's pretty much it. It can broadcast a crap ton of stuff. It's hard to measure since it overloads most wifi modules I've checked. Like a built in wifi card in a netbook and an external Alfa adapter I checked. Seems that when there' sover 255 AP's available, stuff starts having problems.

Here's a quick video of it in Mimic Mode. There are 5 flashes to set the mode, and then 3 more in Mimic Mode to let all the ESP's finish their scan. The once any broadcasting in any more starts, it flashes the built in Blue LED on and off for each loop. It sends a lot out since it looks steady once started.



And the current code (it ain't pretty) in Arduino IDE. I'm sure it can be better but for a silly project, I'm calling it done:


#include

extern "C" {
#include "user_interface.h"
}


byte channel;
int wifiCount = 0;
int fullPacket;
int switchGPIO0;
int switchGPIO2;
String wifissid;

bool promiscuousMode = false;

bool mimicMode = false;
bool scan = false;

bool randomMode = false;
int randomStart;

bool listMode = false;
char* networkList[] = {"attwifi", "HomeNetwork", "Starbucks", "guest", "ATT_8765", "Beaches", "Seagulls" };


bool staticMode = false;
String staticNet = "¯\\_(ツ)_/¯";





void setup() {
  delay(1);
  WiFi.mode(WIFI_STA);
  // Initialize the LED_BUILTIN pin as an output
  pinMode(LED_BUILTIN, OUTPUT);

  // Initialize the GPIO pins as inputs
  pinMode(0, INPUT);
  pinMode(2, INPUT);
  // Wait 5 seconds to set switches
  for (int i = 0; i < 5; ++i)
  {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
  }

  // Check the GPIO config set up and determine the operation mode being used
  switchGPIO0 = digitalRead(0);
  switchGPIO2 = digitalRead(2);
  delay(1);

  if (switchGPIO0 == HIGH && switchGPIO2 == HIGH)
  {
    mimicMode = true;
    scan = true;
    delay(1);
  }
  else if (switchGPIO0 == LOW && switchGPIO2 == HIGH)
  {
    randomMode = true;
    delay(1);
  }
  else if (switchGPIO0 == HIGH && switchGPIO2 == LOW)
  {
    listMode = true;
    delay(1);
  }
  else //(switchGPIO0 == LOW && switchGPIO2 == LOW)
  {
    staticMode = true;
    delay(1);
  }


}







void loop() {

  // Write blue LED HIGH (off)
  digitalWrite(LED_BUILTIN, HIGH);

  // Do an initial scan to find available network names
  if (scan == true)
  {
    wifiCount = WiFi.scanNetworks();
    // Make sure this doesn't run again now that the scan is done
    scan = false;
    // Wait 3 seconds for the other modules before starting
    for (int i = 0; i < 3; ++i)
    {
      digitalWrite(LED_BUILTIN, LOW);
      delay(500);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(500);
    }
  }
  else if (randomMode == true)
  {
    wifiCount = 50;
    // So after 50 loops below, pick a new random number
    randomStart = random(23560);
  }
  else if (listMode == true)
  {
    wifiCount = 6;

  }
  else if (staticMode == true)
  {
    wifiCount = 1;
  }




  if (promiscuousMode == false)
  {
    promiscuousMode = true;
    wifi_set_opmode(STATION_MODE);
    wifi_promiscuous_enable(1);
  }


  delay(1);




  // Start looping through SSID's
  for (int i = 0; i < wifiCount; ++i)
  {
    // Get the SSID to use this round (increasing array value changes SSID)
    if (mimicMode == true)
    {
      // Pick a random SSID
      //int wifiCountArray = wifiCount - 1;
      wifissid = WiFi.SSID(random(wifiCount));
    }
    else if (randomMode == true)
    {
      // Just start at the picked random number and add 1 each loop
      int randVal = randomStart + 1;
      wifissid = String(randVal);
    }
    else if (listMode == true)
    {
      wifissid = networkList[i];
    }
    else
    {
      wifissid = staticNet;
    }



    // Beacon Packet buffer ( this resets the variable every loop. weird things happened when it was global... )
    uint8_t packet[128] = { 0x80, 0x00, 0x00, 0x00,
                            /*4*/   0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                            /*10*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                            /*16*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                            /*22*/  0xc0, 0x6c,
                            /*24*/  0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
                            /*32*/  0x64, 0x00,
                            /*34*/  0x01, 0x04,
                            /* SSID */
                            /*36*/  0x00, 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                            /*71*/  0x01, 0x08, 0x82, 0x84,
                            /*75*/  0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01,
                            /*83*/  0x05, 0x20
                          };


    // Get the SSID length to modify that length value in the beacon
    int wifiLength = wifissid.length();
    // Array spot to start printing SSID
    int ssidSpot = 38;
    // If the SSID is too long, cut it
    if (wifiLength > 30)
    {
      wifiLength = 30;
    }


    // Start printing the SSID in to the packet array at the start spot stated above
    for (int i = 0; i < wifiLength; ++i)
    {
      packet[ssidSpot] = wifissid[i];
      ++ssidSpot;
    }

    // BROADCAST LOOP. Start with 1 space added to SSID and continue until 30 characters long
    for (int j = wifiLength; j < 30; ++j)
    {
      // Kill the "add a space each iteration" looping here if you want



      // Add a space right after the SSID that was printed above
      packet[ssidSpot] = packet[84];
      // Print the now complete SSID length right before the SSID start spot in packet
      packet[37] = j + 1;



      // Move to the next array spot after the last space was added
      ++ssidSpot;

      // Pick a channel to use
      channel = random(1, 12);
      wifi_set_channel(channel);

      // Change the last array value in the "ending" part of the SSID beacon to the channel being used
      packet[83] = channel;
      // Just copying the left off ssid spot for the second part of the packet to start
      int packetPartTwo = ssidSpot;

      // Print the complete second packet portion in to the complete packet array now that the SSID is printed in
      for (int m = 71; m < 84; ++m)
      {
        packet[packetPartTwo] = packet[m];
        ++packetPartTwo;
      }

      // Random MAC address
      packet[10] = packet[16] = random(256);
      packet[11] = packet[17] = random(256);
      packet[12] = packet[18] = random(256);
      packet[13] = packet[19] = random(256);
      packet[14] = packet[20] = random(256);
      packet[15] = packet[21] = random(256);

      // Broadcast the Beacons!
      fullPacket = packetPartTwo; // + 1;
      // Write blue LED LOW (on)
      digitalWrite(LED_BUILTIN, LOW);
      wifi_send_pkt_freedom(packet, fullPacket, 0);
      wifi_send_pkt_freedom(packet, fullPacket, 0);
      wifi_send_pkt_freedom(packet, fullPacket, 0);


      // Write blue LED HIGH (off)
      digitalWrite(LED_BUILTIN, HIGH);

      delay(10);
    }
    delay(10);
  }
  delay(10);
}










Wednesday, November 2, 2016

Cisco AA20270 Power Supply

So I have some old crappy Cisco routers. Cpecifically I'm working with a Cisco 2610. It's a junk router these days, so I have other plans for it.




Anyways, I wanted to use the built in power supply for my project and not provide an external one. Turns out, it's similar to ATX power supplies where it won't turn on unless you do a little dance. For an ATX power supply, there is a well documented PWR_ON pin to tap to ground. And voila, power. For this power supply, no documentation I could find.

So with a little bit of poking and testing, I found out it's super easy. I checked the pins on the router board itself and noticed that the +5v and GND had continuity. So I pulled out a high wattage resistor (to hopefully not blow something up if I was wrong) and connected them. Ta-da. That's how you turn on a Cisco AA20270 Power Supply. Now I have 12v and 5v supplies to use.



So... it's pretty obvious with this power supply to tell when it isn't "on". It has an audible clicking at about 3.5Hz and you don't get a constant power. Th clicking is essentially the power supply checking if it can enable fullpower or not.


Simply tap that GRD to a +5v pin, and you're good though. Here's the clicking sound and showing you get constant voltage once you connect +5v to GND.


EDIT: I think It just needs some sort of current going rather than just connecting wires. The connecting wires actually carry a current through them so you can't just do a basic connection like with an ATX power supply. Use a high watt resistor or an actual load.


Wednesday, September 21, 2016

IR floodlights off of Landscape Lighting

So I bought a Dahua POE PTZ camera off eBay. Great camera and I'm happy with it, but it has no built in IR lights. That's a problem at night. It has much better IR sensitivity than my Hikvisions, but just not good enough.

Installing an IR flood light is easy to do. Just buy one off eBay and plug it in. But I didn't want to run extra wires and I didn't want to take up another outlet (or use a powerstrip) in my garage.

I already have some landscape lighting installed with a way overpowered power box running them since I installed LED lights recently. So I set out to run my IR floodlights off of my lanscape lighting.

This proved to be not challenging at all. You just need the right parts.


  • Infrared LED flood lights
  • Full bridge rectifier (best to get one with a heatsink)
  • A standard lanscape lighting tap
  • Various plugs and wires


The rectifier I got is a 50 amp 1000 volt one with a heatsink off of eBay for $2 with free shipping. I already happened to have some plugs that fit the terminals on it.


The lanscape lighting tap is meant to run another similar landscape cable to another part of the path/area. Or to actually tap in a light. It uses sharp prings to dig in to the cable you are connecting to, and the new cable. These work well and provide a reasonably water proofed connection. Available at pretty much anywhere that sells landscape lighting (got mine at Lowes).


So forst install a short wire to the new tap part on the tap. I used speaker wire since I didn't have any more lanscape wire to use. Then added terminals.


Then you just hook up the terminals from the tap to the AC sides of the rectifier. And hook up your cable going to the IR lights to the positive and negative sides (be sure to check and verify this before installing).


This is a temporary place to put this set up while I work on maybe designing a 3D printed enclosure for it all.


Now I can power 2 LED IR floodlights for my camera using my already installed landscape lighting that runs on 12 volts AC.

Sunday, September 4, 2016

Rope Cutter

I was looking at getting some paracord, maybe only 10 feet or so. Just because I kept needing small amounts of rope when twine simply wouldn't cut it. Well it turns out it's way more cost effective to buy in bulk for paracord. So instead or 10 or 20 feet, I bought 1000 feet in a spool.



So now I had a bulky spool of rope to manage every time I wanted to cut some length. So my solution was to mount it somewhere, and have a cutting tool readily available. The problem was, I lose tools a lot. So I needed a mounted cutting tool. So off to the 3D printer. I designed a small little tool that mounts to my wooden shelves right next to the paracord spool. So now I can just pull a length and cut it real quick.



I thought ahead a little about the blade to use. Since there are two common blades relatively the same side, I designed it to accept both blades in the cutter.





So you just loop it through the hole, loop around the notches (to get tension on the rope) and then a quick wiggle against the blade to cut it. Here's the 3D stl file.