feature/backend #4
							
								
								
									
										155
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										155
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -113,4 +113,157 @@ dkms.conf | ||||
| *.out | ||||
| *.app | ||||
|  | ||||
| config.py | ||||
| # ---> Python | ||||
| # Byte-compiled / optimized / DLL files | ||||
| __pycache__/ | ||||
| *.py[cod] | ||||
| *$py.class | ||||
|  | ||||
| # C extensions | ||||
| *.so | ||||
|  | ||||
| # Distribution / packaging | ||||
| .Python | ||||
| build/ | ||||
| develop-eggs/ | ||||
| dist/ | ||||
| downloads/ | ||||
| eggs/ | ||||
| .eggs/ | ||||
| lib/ | ||||
| lib64/ | ||||
| parts/ | ||||
| sdist/ | ||||
| var/ | ||||
| wheels/ | ||||
| share/python-wheels/ | ||||
| *.egg-info/ | ||||
| .installed.cfg | ||||
| *.egg | ||||
| MANIFEST | ||||
|  | ||||
| # PyInstaller | ||||
| #  Usually these files are written by a python script from a template | ||||
| #  before PyInstaller builds the exe, so as to inject date/other infos into it. | ||||
| *.manifest | ||||
| *.spec | ||||
|  | ||||
| # Installer logs | ||||
| pip-log.txt | ||||
| pip-delete-this-directory.txt | ||||
|  | ||||
| # Unit test / coverage reports | ||||
| htmlcov/ | ||||
| .tox/ | ||||
| .nox/ | ||||
| .coverage | ||||
| .coverage.* | ||||
| .cache | ||||
| nosetests.xml | ||||
| coverage.xml | ||||
| *.cover | ||||
| *.py,cover | ||||
| .hypothesis/ | ||||
| .pytest_cache/ | ||||
| cover/ | ||||
|  | ||||
| # Translations | ||||
| *.mo | ||||
| *.pot | ||||
|  | ||||
| # Django stuff: | ||||
| *.log | ||||
| local_settings.py | ||||
| db.sqlite3 | ||||
| db.sqlite3-journal | ||||
|  | ||||
| # Flask stuff: | ||||
| instance/ | ||||
| .webassets-cache | ||||
|  | ||||
| # Scrapy stuff: | ||||
| .scrapy | ||||
|  | ||||
| # Sphinx documentation | ||||
| docs/_build/ | ||||
|  | ||||
| # PyBuilder | ||||
| .pybuilder/ | ||||
| target/ | ||||
|  | ||||
| # Jupyter Notebook | ||||
| .ipynb_checkpoints | ||||
|  | ||||
| # IPython | ||||
| profile_default/ | ||||
| ipython_config.py | ||||
|  | ||||
| # pyenv | ||||
| #   For a library or package, you might want to ignore these files since the code is | ||||
| #   intended to run in multiple environments; otherwise, check them in: | ||||
| # .python-version | ||||
|  | ||||
| # pipenv | ||||
| #   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||||
| #   However, in case of collaboration, if having platform-specific dependencies or dependencies | ||||
| #   having no cross-platform support, pipenv may install dependencies that don't work, or not | ||||
| #   install all needed dependencies. | ||||
| #Pipfile.lock | ||||
|  | ||||
| # poetry | ||||
| #   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. | ||||
| #   This is especially recommended for binary packages to ensure reproducibility, and is more | ||||
| #   commonly ignored for libraries. | ||||
| #   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control | ||||
| #poetry.lock | ||||
|  | ||||
| # pdm | ||||
| #   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. | ||||
| #pdm.lock | ||||
| #   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it | ||||
| #   in version control. | ||||
| #   https://pdm.fming.dev/#use-with-ide | ||||
| .pdm.toml | ||||
|  | ||||
| # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm | ||||
| __pypackages__/ | ||||
|  | ||||
| # Celery stuff | ||||
| celerybeat-schedule | ||||
| celerybeat.pid | ||||
|  | ||||
| # SageMath parsed files | ||||
| *.sage.py | ||||
|  | ||||
| # Environments | ||||
| .env | ||||
| .venv | ||||
| env/ | ||||
| venv/ | ||||
| ENV/ | ||||
| env.bak/ | ||||
| venv.bak/ | ||||
|  | ||||
| # Spyder project settings | ||||
| .spyderproject | ||||
| .spyproject | ||||
|  | ||||
| # Rope project settings | ||||
| .ropeproject | ||||
|  | ||||
| # mkdocs documentation | ||||
| /site | ||||
|  | ||||
| # mypy | ||||
| .mypy_cache/ | ||||
| .dmypy.json | ||||
| dmypy.json | ||||
|  | ||||
| # Pyre type checker | ||||
| .pyre/ | ||||
|  | ||||
| # pytype static type analyzer | ||||
| .pytype/ | ||||
|  | ||||
| # Cython debug symbols | ||||
| cython_debug/ | ||||
|  | ||||
							
								
								
									
										75
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								README.md
									
									
									
									
									
								
							| @ -34,3 +34,78 @@ TTN LoRa frequency / region | ||||
|  | ||||
| `pip3 install paho-mqtt` | ||||
|  | ||||
|  | ||||
| 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; | ||||
| 	} | ||||
|     ``` | ||||
| @ -58,10 +58,9 @@ class RequestHandler(BaseHTTPRequestHandler): | ||||
|             self.wfile.write(bytes("</html>", "utf-8")) | ||||
|  | ||||
| def update_metrics(payload, metadata): | ||||
|     print("Payload: "+ str(payload)) | ||||
|     print("Metadata: "+ str(metadata)) | ||||
|     #print("Payload: "+ str(payload)) | ||||
|     #print("Metadata: "+ str(metadata)) | ||||
|  | ||||
|     print("set data from ttn") | ||||
|     global node_metrics | ||||
|     global mutex | ||||
|     global scrape_healthy | ||||
| @ -69,17 +68,46 @@ def update_metrics(payload, metadata): | ||||
|     scrape_healthy = True | ||||
|     node_metrics.clear() | ||||
|  | ||||
|     try: | ||||
|             node_metrics.append("target_temperature " + str(int(42))) | ||||
|             node_metrics.append("valve " + str(int(42))) | ||||
|             node_metrics.append("low_battery " + str(int(42))) | ||||
|             node_metrics.append("window_open " + str(int(42))) | ||||
|     except Exception as ex: | ||||
|         print("unable to poll data from TTN! error: " + str(ex)) | ||||
|         scrape_healthy = False | ||||
|         pass | ||||
|     if "degreesC" in payload: | ||||
|         print("set degree: " + str(float(payload["degreesC"]))) | ||||
|         node_metrics.append("temperature " + str(float(payload["degreesC"]))) | ||||
|  | ||||
|     if "pressure" in payload: | ||||
|         print("set pressure: " + str(float(payload["pressure"]))) | ||||
|         node_metrics.append("pressure " + str(float(payload["pressure"]))) | ||||
|  | ||||
|     if "winddirection" in payload: | ||||
|         print("set winddirection: " + str(float(payload["winddirection"]))) | ||||
|         node_metrics.append("winddirection " + str(float(payload["winddirection"]))) | ||||
|  | ||||
|     if "windspeed" in payload: | ||||
|         print("set windspeed: " + str(float(payload["windspeed"]))) | ||||
|         node_metrics.append("windspeed " + str(float(payload["windspeed"]))) | ||||
|  | ||||
|     if "dooropen" in payload: | ||||
|         print("set dooropen: " + str(bool(payload["dooropen"]))) | ||||
|         node_metrics.append("dooropen " + str(int(payload["dooropen"]))) | ||||
|  | ||||
|    # if "gateway_id" in metadata[0]["gateway_ids"]: | ||||
|    #     print("set gateway_id: " + str(metadata[0]["gateway_ids"]["gateway_id"])) | ||||
|    #     node_metrics.append("gateway_id " + str(metadata[0]["gateway_ids"]["gateway_id"])) | ||||
|  | ||||
|     if "rssi" in metadata[0]: | ||||
|         print("set rssi: " + str(int(metadata[0]["rssi"]))) | ||||
|         node_metrics.append("rssi " + str(int(metadata[0]["rssi"]))) | ||||
|  | ||||
|     if "channel_rssi" in metadata[0]: | ||||
|         print("set channel_rssi: " + str(int(metadata[0]["channel_rssi"]))) | ||||
|         node_metrics.append("channel_rssi " + str(int(metadata[0]["channel_rssi"]))) | ||||
|  | ||||
|     if "snr" in metadata[0]: | ||||
|         print("set snr: " + str(float(metadata[0]["snr"]))) | ||||
|         node_metrics.append("snr " + str(float(metadata[0]["snr"]))) | ||||
|  | ||||
|      | ||||
|     #scrape_healthy = False | ||||
|  | ||||
|     mutex.release() | ||||
|     time.sleep(300) | ||||
|  | ||||
| def on_connect(mqttc, obj, flags, rc): | ||||
|     print("\nConnected to MQTT: rc = " + str(rc)) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user