by:

Heute möchte ich mal ein kleines Gebäudeüberwachung und Visualisierungsprojekt von mir vorstellen. 

Angefangen hatte es eigentlich damit das ich den Ölverbrauch messen wollte, dass sollte sich dann aber als Problematischer herausstellen als gedacht, was ich euch hier kurz näher erörtern möchte.


Mein erster Gedanke war den Verbrauch über die Betriebsstunden zu messen. Dafür kaufte ich mir ein Geräuschpegel-Sensor.
Die Idee war das ich einfach über den doch relativ lauten Boiler die Betriebsstunden ablesen kann.  Die Methode hätte den Vorteil gehabt das sie a. nicht invasiv in das bestehene System eingreift und b. relativ günstig wäre.  Wäre, schlussendlich habe ich die Idee wieder verworfen da der Verbrauch wohl nicht mit dem Verbrenngeräusch korreliert. 
Eine weitere Idee, die deutlich invasiver gewesen wäre, war ein Durchflussmesser zu installieren, aber auch hier hätte ich zumindest zwei installieren müssen, 
scheinbar wird ein Teil des Heizöles wieder zurückgeleitet und ich hätte die Differenz berechnen müssen. Das war mir dann doch zu aufwändig und zu invasiv. 
Schlussendlich habe ich mich für eine Distanzmessung via Ultraschal entschieden, das ist ebenfalls wenig Invasiv, lässt aber den ungefähren verbrauch 
erahnen. Um die Messung zu verbessern nutze ich noch ein Temperatur Sensor, da sich offenbar die Schallgeschwindigkeit mit der Temperatur verändert.
Es ist unglaublich wieviel man bei so kleinen Projekten lernt. 

Welches Sensor Board  

Derzeit verwende ich Development Boards auf esp8266 basis, wie z.b. das NodeMCU V3 oder jetzt auch das wemos d1 mini. 
Das Board selbst hat ein WLan chip an Board, es ist relativ klein, verbraucht wenig Strom, hat genügend ein und ausgänge um kleine Hobby Projekte umzusetzen.
Außerdem gibt es eine große Community die auf Basis vom esp8266 Projekte realisiert, was bei Fragen doch sehr hilfreich ist.
Wer etwas mehr power benötigt und auch Bluetooth angewiesen ist, dem kann man auch den großen Bruder esp32 empfehlen. 

Welche Software für das Board

Nun angefangen habe ich mit der NodeMCU Firmware, hier wird mit LUA programmiert was besonders für Anfänger gut sein soll. 
Nach einem langen und schmerzgeplagten leidensweg, den ich hier nur kurz andeuten möchte, habe ich nach einigen Monaten 
auf Python, genauer Micopython (https://micropython.org/) gewechselt und es nicht bereut. 
Ich empfehle hier den Atom Editor und das pymakr Plugin, so kann man aus dem Editor direkt den Code hochladen und 
sieht gleich das Ergebnis. 
Als alternative zu LUA und Python gibts auch die gute alte Arduino IDE mit der C ähnlichen sprache. 
Hat ganz generell auch gut funktioniert, wer allerdings wie ich oft dinge ändert und ausprobiert ist mit
Micropython in sofern besser dran, als das Hochladen vom Code deutlich schneller geht, muss er nicht erst immer wieder
neu komepliert werden wie bei Arduino. Aber das ist natürlich nur geschmakssache. 
Am Ende kommt man mit jeder Platform zum Ziel, sollte sich auf einige Workarrounds gefasst machen.

Visualiserung

Nachdem ich schon die Hardware und darauf laufene Software selbstr gestrickt habe kann ich natürlich nicht ein bestehne Visualiserung verwenden. 
Nein ich hab mir natürlich meine eigene Dashboarding App gebaut, als basis kommt Laravel und fürs Frontend Vue.js in Einsatz.
Das System befindet sich zwar noch in Entwicklung, aber die Wichtigsten funktionen sind bereits im Einsatz und seit über ein Jahr im Dauerbetrieb. 

Funktionsumfang:
Erstellung von Dashboards
Konfiguration der einzelnen Charts (Farben, Labels, Typ: Line, Bar..) 
Verschachtelte Datenquellen 
Rest API 

 

Wer die Software testen möchte und oder mir feedback geben möchte ist herzlich eingeladen das an dieser stelle zu tun. 

 


Firmware
https://riot-os.org/
https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html

Visualisierung: 
https://gitlab.com/andreas83/home.io


Kommentare

by:

This is my first jQuery Plugin and a pre release of my responsive slider. The main reason for programming another javascript slider is for fun. Another reason was the existing slider did not feed my needs.

Goals

  1. Responsive
  2. Works with many pictures (+10000)
  3. Small footprint and easy to integrate
  4. No Flash
  5. Must be awesome (iam working on that)

Demo

  • /images/asia/22.jpg
  • /images/asia/7.jpg
  • /images/asia/27.jpg
  • /images/asia/30.jpg
  • /images/asia/29.jpg

SourceCode

$.fn.slider = function (options) {

  var settings = $.extend({
    interval: 2000,
    showCaption: false,
    dataClass: "imagedata",
    preload: 3
  }, options);

    /*
    todo
    var autoPlayback = true;
    */


  function LoaderImage(url) {
    var self = this;

    this.isLoaded = false;
    this.url = url;
    this.imgObj = new Image();
    this.load = function () {
      self.imgObj.src = self.url;
    }
    this.onLoad = undefined; // callback function

    this.imgObj.onload = function () { // load imgUrl into imgObj and call imgOnLoad when finished
      self.isLoaded = true;
      console.log("imgIsLoaded");
      if (self.onLoad)
        self.onLoad();
    };
  }

  //for every slider object, we attach the slider functionality
  $(this).each(function () {


    var items = [];
    var cnt = 0;
    $(this).find('ul.' + settings.dataClass)
      .children().each(function () {

        var item = new LoaderImage(
          decodeURI($(this).text())
        );

        // TODO: broken preloader
        if (cnt < settings.preload) {
          item.load();
        }

        items.push(item);
        ++cnt;
      });

    //we create a img tag
    var img = $('<img />').attr({
      "class": "img opaque",
      "src": items[0].url
    }).insertAfter($(this).find('ul.' +
      settings.dataClass));

    //we need a second one for overlay/transition effect        
    var oldimg = $('<img />').attr({
      "class": "img opaque",
      "src": items[0].url
    }).insertAfter(img);

    if (settings.showCaption)
      var caption = $('<span />').html(
        items[0].caption).insertAfter(
        img);

    var btnBox = $('<div />').attr({
      "class": "btnBox"
    }).insertBefore($(img));

    $(btnBox).append($('<span />').attr({
      "id": "preBtn",
      "class": "btn"
    }).html("Prev"));

    $(btnBox).append($('<span />').attr({
      "id": "nextBtn",
      "class": "btn"
    }).html("Next"));

    //we start rotation
    var i = 0;

    function gotoNext(back, isClick) {
      back = typeof back !==
        'undefined' ? back : false;
      isClick = typeof isClick !==
        'undefined' ? isClick : false;

      if (back)
      --i;
      else ++i;

      if (i < 0)
        i = cnt - 1;
      else if (i > cnt - 1)
        i = 0;


      var setImageFunc = function () {
        oldimg.removeClass("opaque");
        img.attr({
          "src": items[i].imgObj.src,
          "class": "opaque img"
        });
        var tmp = oldimg;
        oldimg = img;
        img = tmp;


      };

      if (!items[i].isLoaded) {
        items[i].onLoad = function () {
          setImageFunc();
        }
        items[i].load();
      } else {
        setImageFunc();
      }

    }

    var slideint = setInterval(
      function () {
        gotoNext()
      }, settings.interval);

    $($(this).find("#nextBtn")).click(
      function () {
        clearInterval(slideint);
        gotoNext(false);
        slideint = setInterval(
          function () {
            gotoNext()
          }, settings.interval);
      });

    $($(this).find("#preBtn")).click(
      function () {
        clearInterval(slideint);
        gotoNext(true);
        slideint = setInterval(
          function () {
            gotoNext()
          }, settings.interval);
      });
  });
} // end plugin

 

Integration

Please dont integrate my slider at this time, because its still an alpha. I know there is plenty of room for improvements, like pre loading, different animation, key binding etc...

Contribute

Feel free to make suggestions and/or code improvements

Thank You

Jakob Oberhummer and Michael Walloch for feedback and code improvements.

Chanelog

2013/12/08 added preloading, fixed rotation issue, improved transition
2013/10/02 inital release

Happy Hacking

Andreas


Kommentare

by:

Nachdem ich am Sonntag mit ein paar Freunden (Harry, Michi u Andi) Quadrocopter
fliegen war, ist mir am späten Abend die Idee gekommen ein kleinen GPS2SMS logger für Android zu schreiben.
Das kann z.b. hilfreich sein, wenn die UAV Drone ein Eigenleben entwickelt und
man nicht mehr genau weiss wo seine Drone (im besten fall sanft) gelandet ist.

Es hat sich herausgestellt das die Umsetzung mit dem "Scripting Layer for Android" extrem einfach ist.

import android

number="06604952349"

droid = android.Android()
droid.startLocating(0, 0)
event = droid.eventWait(1000).result
if event['name'] == "location":
    msg = "GPS Long: %f" % event['data']['network']['longitude'] 
    msg+= "Lat  %f" % event['data']['network']['latitude']
    droid.smsSend(number,msg)
droid.stopLocating()

Leider hab ich den Programmcode nicht getetstet, und bin mir daher nicht 100% sicher ob er funktioniert, werde das testing bald nachholen !!

Update

So jetzt ist das ganze auch getestet, damit es funktioniert, bitte nicht vergessen die letzte Version der SL4A herunterzuladen.


lg
Andreas


Kommentare

by:

Die Idee war Daten mit hilfe von Schawarz/Weiss Bildern zu übertragen.

Die Modulation und Demodulation der Daten ist zwar nicht besonders schnell, aber sie funktioniert. 


Kommentare

by:

Ladies and Gentleman, turn your lights on

SourceCode

#!/usr/bin/python

import pygame
import pygame.camera

class Capture(object):
    a = []
    allines = []
    found = 0
    def __init__(self):
        self.size = (640,480)
        # create a display surface. standard pygame stuff
        self.display = pygame.display.set_mode(self.size, 0)
        
        # this is the same as what we saw before
        self.clist = pygame.camera.list_cameras()
        if not self.clist:
            raise ValueError("Sorry, no cameras detected.")
        self.cam = pygame.camera.Camera(self.clist[0], self.size)
        self.cam.start()

        # create a surface to capture to.  for performance purposes
        # bit depth is the same as that of the display surface.
        self.snapshot = pygame.surface.Surface(self.size, 0, self.display)

    def get_and_flip(self):
        # if you don't want to tie the framerate to the camera, you can check 
        # if the camera has an image ready.  note that while this works
        # on most cameras, some will never return true.
        if self.cam.query_image():
            self.snapshot = self.cam.get_image(self.snapshot)

        # blit it to the display surface.  simple!
        self.display.blit(self.snapshot, (0,0))
        pygame.display.flip()

    def main(self):
        going = True
        while going:
            for event in pygame.event.get() :
              if event.type == pygame.KEYDOWN :
                if event.key == pygame.K_SPACE :
                  print "Space bar pressed down."
                elif event.key == pygame.K_ESCAPE :
                  print "Escape key pressed down."
              elif event.type == pygame.KEYUP :
                if event.key == pygame.K_SPACE :
                  del self.a[:]
                  del self.allines[:]

                elif event.key == pygame.K_ESCAPE :
                  pygame.quit()

            self.get_and_flip()



    def get_and_flip(self):
        self.snapshot = self.cam.get_image(self.snapshot)
        # threshold against the color we got before
        crect = pygame.draw.rect(self.display, (255,0,0), (145,105,30,30), 4)
        #self.ccolor = pygame.transform.average_color(self.snapshot, crect)
        mask = pygame.mask.from_threshold(self.snapshot, (240, 240, 255), (30, 30, 30))
        self.display.blit(self.snapshot,(0,0))
        # keep only the largest blob of that color
        connected = mask.connected_component()
        # make sure the blob is big enough that it isn't just noise
        if mask.count() > 100:
            # find the center of the blob
            coord = mask.centroid()
            self.a.append(coord)
            self.found = 0
        else:
            self.found = self.found+1

        #if we not found the threshold color more then 15 times
        #we create a new line 
        if self.found > 15:
            self.allines.append(self.a[:])
            del self.a[:]

        l = len(self.a)

        for i in range(len(self.allines)):
            if len(self.allines[i]) >1:
                pygame.draw.aalines(self.display, (255,255,255), 0, self.allines[i], 1)
        if l > 1:                
            pygame.draw.aalines(self.display, (255,255,255), 0, self.a, 1)
        pygame.display.flip()


pygame.init()
pygame.camera.init()
x = Capture()
x.main()

Happy Hacking

Andreas


Kommentare


Seiten: