Smartes IoT Systems zur Anzeige des Status der Vereinshütte ohne KI und Blockchain. https://msv-buehl-moos.de/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Hendrik Schutter 80d2e3c1f9
added doc
2 weeks ago
backend restructure and cleanup 3 weeks ago
doc added doc 2 weeks ago
frontend added doc 2 weeks ago
node node payload structure 3 weeks ago
.gitignore added config for backend to .gitignore 3 weeks ago
.gitmodules new .gitignore 3 weeks ago
LICENSE Initial commit 4 weeks ago
README.md added doc 2 weeks ago

README.md

msv-clubhouse-node

  • Work in progress !
  • Technical demo

Overview

architecture diagram

Hardware

Build Node Firmware

  1. Clone repo
  2. Init GIT-submodules
git submodule init
git submodule update
  1. Set following defines via menuconfig:
AppEUI
DevEUI
AppKey
TTN LoRa frequency / region
  1. Build with ESP-IDF extension in VSCodium

MQTT Endpoint

pip3 install paho-mqtt

  • mkdir /opt/msv-clubhouse-backend/
  • cd /opt/msv-clubhouse-backend/
  • import msv_clubhouse_backend.py and config.py
  • Set the constants in config.py
  • chmod +x /opt/msv-clubhouse-backend/msv_clubhouse_backend.py
  • chown -R prometheus /opt/msv-clubhouse-backend/
  • nano /etc/systemd/system/msv-clubhouse-backend.service
  • systemctl daemon-reload && systemctl enable --now msv-clubhouse-backend.service

JS Payload Formatter

function Decoder(bytes, port) {
  var decoded = {};
  
  // temperature 
  rawTemp = bytes[0] + bytes[1] * 256;
  decoded.degreesC = sflt162f(rawTemp) * 100;
  
  // pressure 
  rawPressure = bytes[2] + bytes[3] * 256;
  decoded.pressure = sflt162f(rawPressure) * 100;
  
  // windspeed 
  rawWindspeed = bytes[4] + bytes[5] * 256;
  decoded.windspeed = sflt162f(rawWindspeed) * 100;
  
  // winddirection 
  rawWinddirection = bytes[6] + bytes[7] * 256;
  decoded.winddirection = sflt162f(rawWinddirection) * 100;
  
  if(bytes[8] === 0){
    decoded.dooropen = false;
  }else{
    decoded.dooropen = true;
  }
  
  
  return decoded;
}

function sflt162f(rawSflt16)
	{
	// rawSflt16 is the 2-byte number decoded from wherever;
	// it's in range 0..0xFFFF
	// bit 15 is the sign bit
	// bits 14..11 are the exponent
	// bits 10..0 are the the mantissa. Unlike IEEE format, 
	// 	the msb is transmitted; this means that numbers
	//	might not be normalized, but makes coding for
	//	underflow easier.
	// As with IEEE format, negative zero is possible, so
	// we special-case that in hopes that JavaScript will
	// also cooperate.
	//
	// The result is a number in the open interval (-1.0, 1.0);
	// 
	
	// throw away high bits for repeatability.
	rawSflt16 &= 0xFFFF;

	// special case minus zero:
	if (rawSflt16 == 0x8000)
		return -0.0;

	// extract the sign.
	var sSign = ((rawSflt16 & 0x8000) !== 0) ? -1 : 1;
	
	// extract the exponent
	var exp1 = (rawSflt16 >> 11) & 0xF;

	// extract the "mantissa" (the fractional part)
	var mant1 = (rawSflt16 & 0x7FF) / 2048.0;

	// convert back to a floating point number. We hope 
	// that Math.pow(2, k) is handled efficiently by
	// the JS interpreter! If this is time critical code,
	// you can replace by a suitable shift and divide.
	var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15);

	return f_unscaled;
	}

Grafana Dashboard

see frontend/

screenshot of grafana-dashboard

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close