Difference between revisions of "Space state"

From Hackerspace ACKspace
Jump to: navigation, search
m (moved github link to Mobile Spacestate Indicator since the code does space state indication, not setting the state)
 
(23 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{Project
 
{{Project
|State=Active
+
|Featured=No
|Members=Vicarious, xopr
+
|State=Completed
 +
|Members=Vicarious, xopr, Coolepascal, Prodigity
 
|Description=Show the current state (open or closed) of our space
 
|Description=Show the current state (open or closed) of our space
 +
|Picture=Spacestate_closed.jpg
 
}}
 
}}
<strike>For now we'll use our Skype account "ACK.space" to show whether the space is currently open or closed. Later we'll have a better set up.</strike>
 
  
Although we forgot to update this page, the SpaceState switch is working fine now. This is how it's done
+
== current implementation ==
 +
The current iteration of the spacestate switch works with [[Spacestate sensors]] over [[MQTT]] (using [https://tasmota.github.io/docs/ Tasmota]) to polulate the [[SpaceAPI]] and uses the template: <code>{"NAME":"ACKsensor","GPIO":[0,0,0,0,0,0,0,0,1,0,0,0,1,1],"FLAG":0,"BASE":18}</code>.
  
We found an huge powerswitch which we mounted to the space wall this switch is connected with a cable to the Space-Mac using an serial to usb converter. On the Mac a perl scripts reads the space state. If the space-state changes, the perlscripts uses wget to call an php script on the ACKspace website. The php scripts sets an space-state variable in a file. The same script is used to read the space-state variable and show the status on the webpage.  
+
[[Image:Spacestate_sensors_Picture.jpg|200px]]
  
<br>
+
Note that there are also (somewhat cheesy) renders of the switch: [[Media:spacestate-switch.zip|sketchup model]] and a derived [[Media:spacestate_mini.xcf|GIMP mini version]].
  
 +
The space state is connected to fuse group [[Fuse group::A]].
 +
== previous versions ==
 +
 +
=== ESP-01 version (2015-2021) ===
 +
[[Image:SpaceState.png|200px|left]]
 +
This sketch was a web client and will update the SpaceState
 +
 +
It reads the GPIO2 (pulled up) pin where the space state switch is connected to via ground.
 +
GPIO0 is reserved for onewire devices.
 +
 +
 +
==== hardware ====
 +
The new Raspberry PI replacement: fast boot times and no SD card corruption anymore, thanks to the [[ESP8266]]
 +
The hardware is simple enough to put on a small prototyping board.
 +
It has a 3v3 regulator and the 4k7 and 10k pull-ups for onewire and the spacestate switch respectively.
 +
 +
==== code ====
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-ESP8266-SpaceState_ino">
 +
===== ESP8266-SpaceState.ino =====
 +
<div class="mw-customtoggle-ESP8266-SpaceState_ino mw-code">Click here to view the source code</div>
 +
<pre class="mw-collapsible-content">
 +
/*
 +
  2015-07-05: Created by xopr
 +
 
 +
  Code based on http://iot-playground.com/2-uncategorised/41-esp8266-ds18b20-temperature-sensor-arduino-ide by Igor Jarc
 +
 +
  External libraries:
 +
  - https://github.com/milesburton/Arduino-Temperature-Control-Library
 +
 +
  This program is free software; you can redistribute it and/or
 +
  modify it under the terms of the GNU General Public License
 +
  version 2 as published by the Free Software Foundation.
 +
*/
 +
 +
#include <ESP8266WiFi.h>
 +
#include <OneWire.h>
 +
#include <DallasTemperature.h>
 +
 +
//AP definitions
 +
#define AP_SSID    "ACKspaceWifi"
 +
#define AP_PASSWORD "nospacenet"
 +
 +
#define API_SERVER  "ackspace.nl"
 +
#define API_KEY    "<YOUR_KEY>"
 +
 +
#define PIN_SWITCH  2
 +
 +
void updateSpaceState( bool _bState );
 +
 +
void setup()
 +
{
 +
  Serial.begin(115200);
 +
 +
  pinMode( PIN_SWITCH, INPUT_PULLUP );
 +
 
 +
  wifiConnect( );
 +
 +
}
 +
 +
 +
bool bState = false;
 +
unsigned long Time = 0;
 +
 +
void loop()
 +
{
 +
  if ( ( millis() - Time > 19900 ) || bState != digitalRead( PIN_SWITCH ) )
 +
  {
 +
    delay( 100 );
 +
   
 +
    bState = digitalRead( PIN_SWITCH );
 +
 +
    updateSpaceState( bState );
 +
    updateOldSpaceState( bState );
 +
    Time = millis();
 +
  }
 +
 +
  delay( 1 );
 +
}
 +
 +
void updateSpaceState( bool _bState )
 +
{
 +
    // Use WiFiClient class to create TCP connections
 +
  WiFiClient client;
 +
  if (!client.connect( API_SERVER, 80 ) )
 +
  {
 +
    Serial.println( "connection failed" );
 +
    return;
 +
  }
 +
 +
  // We now create a URI for the request
 +
  String url = "/spaceAPI/?update&state=";
 +
 +
  if ( _bState )
 +
    url += 0;
 +
  else
 +
    url += 1;
 +
 +
  url += "&key=";
 +
  url += API_KEY;
 +
 +
  Serial.print( "Requesting URL: " );
 +
  Serial.println( url );
 +
 +
  // This will send the request to the server
 +
  client.print( String("GET " ) + url + " HTTP/1.1\r\n" +
 +
                "Host: " + API_SERVER + "\r\n" +
 +
                "Connection: close\r\n\r\n");
 +
  delay( 10 );
 +
 +
  // Read all the lines of the reply from server and print them to Serial
 +
  while( client.available( ) )
 +
  {
 +
    String line = client.readStringUntil( '\r' );
 +
    Serial.print( line );
 +
  }
 +
 +
  Serial.println( );
 +
  Serial.println( "closing connection" );
 +
}
 +
 +
void updateOldSpaceState( bool _bState )
 +
{
 +
    // Use WiFiClient class to create TCP connections
 +
  WiFiClient client;
 +
  if (!client.connect( API_SERVER, 80 ) )
 +
  {
 +
    Serial.println( "connection failed" );
 +
    return;
 +
  }
 +
 +
  // We now create a URI for the request
 +
  String url = "/FORGOT_THE_URI";
 +
 +
  if ( _bState )
 +
    url += "KEY_TO_SET_THE_SPACE_CLOSED";
 +
  else
 +
    url += "KEY_TO_SET_THE_SPACE_OPEN";
 +
 +
  Serial.print( "Requesting URL: " );
 +
  Serial.println( url );
 +
 +
  // This will send the request to the server
 +
  client.print( String("GET " ) + url + " HTTP/1.1\r\n" +
 +
                "Host: " + API_SERVER + "\r\n" +
 +
                "Connection: close\r\n\r\n");
 +
  delay( 10 );
 +
 +
  // Read all the lines of the reply from server and print them to Serial
 +
  while( client.available( ) )
 +
  {
 +
    String line = client.readStringUntil( '\r' );
 +
    Serial.print( line );
 +
  }
 +
 +
  Serial.println( );
 +
  Serial.println( "closing connection" );
 +
}
 +
 +
void wifiConnect()
 +
{
 +
    Serial.print( "Connecting to " );
 +
    Serial.print( AP_SSID );
 +
    WiFi.begin( AP_SSID, AP_PASSWORD );
 +
    while ( WiFi.status() != WL_CONNECTED )
 +
    {
 +
        delay( 1000 );
 +
        Serial.print( "." );
 +
    }
 +
 
 +
    Serial.println( "" );
 +
    Serial.println( "WiFi connected" );
 +
 +
    // Print the IP address
 +
    Serial.println( WiFi.localIP( ) );
 +
}
 +
</pre>
 +
</div>
 +
 +
=== Raspberry Pi version (2011-2015) ===
 +
==== notes ====
 +
* [[User:Prodigity|Prodigity]] 23:34, 18 November 2014 (CET) Python script now doesn't crash and burn on failed connections
 +
* [[User:Prodigity|Prodigity]] 23:23, 18 November 2014 (CET) The raspberry pi now mounts root as READ ONLY with the help of this tutorial (http://blog.pi3g.com/2014/04/make-raspbian-system-read-only/)
 +
*: This has been done to prevent corruption of the SD card.
 +
* [[User:Prodigity|Prodigity]] 02:34, 11 November 2014 (CET) Space state indicator now has a third state; "?"
 +
: A php script now periodically runs on the server to check when the spacestate has last been set;
 +
: if it is has been longer then 5 minutes it sets the state to "?".
 +
: This has been done to prevent power outages and loss of internet connection leaving an incorrect state.
 +
 +
==== hardware ====
 +
Vicarious and Prodigity have revived the SpaceState switch; It now uses a raspberry pi.
 +
 +
The raspberry pi is currently running a python daemon which reads a GPIO pin every 10 seconds.
 +
This GPIO pin is connected to one end of the switch and a ground connection from the GPIO header is connected to another.
 +
When the switch is in the 'off' position the GPIO pin gets pulled up to +3.3v with the help of a 10K resistor,
 +
otherwise (when the switch is 'on') the GPIO pin gets pulled down.
 +
 +
The python script uses the RPi.GPIO, urllib2 and time library to accomplish its task.
 +
RPi.GPIO is used to easily read the GPIO pins from within python.
 +
urllib2 is used to post the spacestate to the website.
 +
Time is used to limit the amount of GPIO polls and more importantly, to limit the amount of network traffic.
 +
 +
==== code ====
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-spacestate_py">
 +
===== spacestate.py =====
 +
<div class="mw-customtoggle-spacestate_py mw-code">Click here to view the source code</div>
 +
<pre class="mw-collapsible-content">
 +
#!/usr/bin/python
 +
import time, urllib2
 +
import RPi.GPIO as GPIO
 +
GPIO.setmode(GPIO.BOARD)
 +
GPIO.setup(18, GPIO.IN)
 +
 +
# Check space switch for ever and ever ....
 +
while 1:
 +
        input_value = GPIO.input(18)
 +
        if input_value == 1: # Space closed
 +
                try:
 +
                        bla = urllib2.urlopen('..')
 +
                except:
 +
                        print "Couldn't connect.."
 +
        else:                # Space open
 +
                try:
 +
                        bla = urllib2.urlopen('..')
 +
                except:
 +
                        print "Couldn't connect.."
 +
        print input_value # for debugging purposes..
 +
        time.sleep(10) # Poll every 10 seconds..
 +
</pre>
 +
</div>
 +
 +
=== Mac version (2011) ===
 +
 +
==== hardware ====
 +
We found a huge power switch which we mounted to the space wall this switch is connected with a cable to the Space-Mac using an serial to usb converter. On the Mac a perl scripts reads the space state. If the space-state changes, the perlscripts uses wget to call an php script on the ACKspace website. The php scripts sets an space-state variable in a file. The same script is used to read the space-state variable and show the status on the webpage.
 +
 +
==== software ====
 
This is the perl script that does the thing on te Mac (note that this code is not yet the actual running version)
 
This is the perl script that does the thing on te Mac (note that this code is not yet the actual running version)
 +
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-spacestate_pl">
 +
===== spacestate.pl =====
 +
<div class="mw-customtoggle-spacestate_pl mw-code">Click here to view the source code</div>
 +
<pre class="mw-collapsible-content">
 
   #!/usr/bin/perl -wT
 
   #!/usr/bin/perl -wT
 
   # Title    : spacestate.pl
 
   # Title    : spacestate.pl
Line 54: Line 296:
 
       sleep(1);
 
       sleep(1);
 
   }
 
   }
 +
</pre>
 +
</div>
 +
 +
 +
=== Skype version (2010) ===
 +
This version used the ACK.space skype status to indicate whether we were open.
  
Here to put the php script running on the webserver.
+
== pics or it didn't happen ==
  <?php
 
      some code
 
  ?>
 
  
[[Image:Spacestate switch.jpg|left|400px|Spacestate switch.jpg]][[Image:Spacestate closed.jpg|left|400px|Spacestate closed.jpg]]
+
<gallery>
 +
Image:Spacestate switch.jpg|Spacestate switch
 +
Image:Spacestate closed.jpg|Spacestate closed
 +
Image:Spacestate open.jpg|Spacestate open
 +
</gallery>
  
[[Image:Spacestate open.jpg|left|400px|Spacestate open.jpg]]
+
Location: [[Location::hACKspace]] (between the two doors)
 +
[[Category:SpaceAPI]]

Latest revision as of 17:16, 19 May 2022

Project: Space state
Featured: No
State Completed
Members Vicarious, xopr, Coolepascal, Prodigity
GitHub No GitHub project defined. Add your project here.
Description Show the current state (open or closed) of our space
Picture
Spacestate closed.jpg


current implementation

The current iteration of the spacestate switch works with Spacestate sensors over MQTT (using Tasmota) to polulate the SpaceAPI and uses the template: {"NAME":"ACKsensor","GPIO":[0,0,0,0,0,0,0,0,1,0,0,0,1,1],"FLAG":0,"BASE":18}.

Spacestate sensors Picture.jpg

Note that there are also (somewhat cheesy) renders of the switch: sketchup model and a derived GIMP mini version.

The space state is connected to fuse group A.

previous versions

ESP-01 version (2015-2021)

SpaceState.png

This sketch was a web client and will update the SpaceState

It reads the GPIO2 (pulled up) pin where the space state switch is connected to via ground. GPIO0 is reserved for onewire devices.


hardware

The new Raspberry PI replacement: fast boot times and no SD card corruption anymore, thanks to the ESP8266 The hardware is simple enough to put on a small prototyping board. It has a 3v3 regulator and the 4k7 and 10k pull-ups for onewire and the spacestate switch respectively.

code

ESP8266-SpaceState.ino
Click here to view the source code
/*
  2015-07-05: Created by xopr
  
  Code based on http://iot-playground.com/2-uncategorised/41-esp8266-ds18b20-temperature-sensor-arduino-ide by Igor Jarc
 
  External libraries:
  - https://github.com/milesburton/Arduino-Temperature-Control-Library
 
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  version 2 as published by the Free Software Foundation.
*/

#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//AP definitions
#define AP_SSID     "ACKspaceWifi"
#define AP_PASSWORD "nospacenet"

#define API_SERVER  "ackspace.nl"
#define API_KEY     "<YOUR_KEY>"

#define PIN_SWITCH  2

void updateSpaceState( bool _bState );

void setup()
{
  Serial.begin(115200);

  pinMode( PIN_SWITCH, INPUT_PULLUP );
  
  wifiConnect( );

}


bool bState = false;
unsigned long Time = 0;

void loop()
{
  if ( ( millis() - Time > 19900 ) || bState != digitalRead( PIN_SWITCH ) )
  {
    delay( 100 );
    
    bState = digitalRead( PIN_SWITCH );

    updateSpaceState( bState );
    updateOldSpaceState( bState );
    Time = millis();
  }

  delay( 1 );
}

void updateSpaceState( bool _bState )
{
    // Use WiFiClient class to create TCP connections
  WiFiClient client;
  if (!client.connect( API_SERVER, 80 ) )
  {
    Serial.println( "connection failed" );
    return;
  }

  // We now create a URI for the request
  String url = "/spaceAPI/?update&state=";

  if ( _bState )
    url += 0;
  else
    url += 1;

  url += "&key=";
  url += API_KEY;

  Serial.print( "Requesting URL: " );
  Serial.println( url );

  // This will send the request to the server
  client.print( String("GET " ) + url + " HTTP/1.1\r\n" +
                "Host: " + API_SERVER + "\r\n" + 
                "Connection: close\r\n\r\n");
  delay( 10 );

  // Read all the lines of the reply from server and print them to Serial
  while( client.available( ) )
  {
    String line = client.readStringUntil( '\r' );
    Serial.print( line );
  }

  Serial.println( );
  Serial.println( "closing connection" );
}

void updateOldSpaceState( bool _bState )
{
    // Use WiFiClient class to create TCP connections
  WiFiClient client;
  if (!client.connect( API_SERVER, 80 ) )
  {
    Serial.println( "connection failed" );
    return;
  }

  // We now create a URI for the request
  String url = "/FORGOT_THE_URI";

  if ( _bState )
    url += "KEY_TO_SET_THE_SPACE_CLOSED";
  else
    url += "KEY_TO_SET_THE_SPACE_OPEN";

  Serial.print( "Requesting URL: " );
  Serial.println( url );

  // This will send the request to the server
  client.print( String("GET " ) + url + " HTTP/1.1\r\n" +
                "Host: " + API_SERVER + "\r\n" + 
                "Connection: close\r\n\r\n");
  delay( 10 );

  // Read all the lines of the reply from server and print them to Serial
  while( client.available( ) )
  {
    String line = client.readStringUntil( '\r' );
    Serial.print( line );
  }

  Serial.println( );
  Serial.println( "closing connection" );
}

void wifiConnect()
{
    Serial.print( "Connecting to " );
    Serial.print( AP_SSID );
    WiFi.begin( AP_SSID, AP_PASSWORD );
    while ( WiFi.status() != WL_CONNECTED )
    {
        delay( 1000 );
        Serial.print( "." );
    }
  
    Serial.println( "" );
    Serial.println( "WiFi connected" );

    // Print the IP address
    Serial.println( WiFi.localIP( ) );
}

Raspberry Pi version (2011-2015)

notes

A php script now periodically runs on the server to check when the spacestate has last been set;
if it is has been longer then 5 minutes it sets the state to "?".
This has been done to prevent power outages and loss of internet connection leaving an incorrect state.

hardware

Vicarious and Prodigity have revived the SpaceState switch; It now uses a raspberry pi.

The raspberry pi is currently running a python daemon which reads a GPIO pin every 10 seconds. This GPIO pin is connected to one end of the switch and a ground connection from the GPIO header is connected to another. When the switch is in the 'off' position the GPIO pin gets pulled up to +3.3v with the help of a 10K resistor, otherwise (when the switch is 'on') the GPIO pin gets pulled down.

The python script uses the RPi.GPIO, urllib2 and time library to accomplish its task. RPi.GPIO is used to easily read the GPIO pins from within python. urllib2 is used to post the spacestate to the website. Time is used to limit the amount of GPIO polls and more importantly, to limit the amount of network traffic.

code

spacestate.py
Click here to view the source code
#!/usr/bin/python
import time, urllib2
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(18, GPIO.IN)

# Check space switch for ever and ever ....
while 1:
        input_value = GPIO.input(18)
        if input_value == 1: # Space closed
                try:
                        bla = urllib2.urlopen('..')
                except:
                        print "Couldn't connect.."
        else:                # Space open
                try:
                        bla = urllib2.urlopen('..')
                except:
                        print "Couldn't connect.."
        print input_value # for debugging purposes..
        time.sleep(10) # Poll every 10 seconds..

Mac version (2011)

hardware

We found a huge power switch which we mounted to the space wall this switch is connected with a cable to the Space-Mac using an serial to usb converter. On the Mac a perl scripts reads the space state. If the space-state changes, the perlscripts uses wget to call an php script on the ACKspace website. The php scripts sets an space-state variable in a file. The same script is used to read the space-state variable and show the status on the webpage.

software

This is the perl script that does the thing on te Mac (note that this code is not yet the actual running version)

spacestate.pl
Click here to view the source code
   #!/usr/bin/perl -wT
   # Title    : spacestate.pl
   # Function : read spacestate switch en set action accordingly
   # Author   : Pascal Schiks (C) 2011

   #
   my $serialdev="/dev/tty.PL2303-000061FD";
   
   use strict;
   use IO::Handle;
   use Fcntl;

   my $TIOCMGET = 0x5415;

   my $spacestate=0;
   my $lastspacestate=$spacestate;
   while(1)
   {
      if(sysopen(SERIAL, $serialdev, O_RDWR))
      {
         my $mdmctl="";
         my $ioresult;
         unless(($ioresult=ioctl(SERIAL,  $TIOCMGET, $mdmctl))==-1)
         {
            $mdmctl = unpack('i',$mdmctl);
            $spacestate = ($mdmctl&64)==0 ? "open":"close";
            print "$spacestate\n" if($spacestate ne $lastspacestate);
         }
         else
         {
            print "Weet ik veel Error\n";
         }
         close(SERIAL);
         $lastspacestate = $spacestate;
      }
      else
      {
         print "Error, Could not open $serialdev\n";
      }
      sleep(1);
   }


Skype version (2010)

This version used the ACK.space skype status to indicate whether we were open.

pics or it didn't happen

Location: hACKspace (between the two doors)