...
 
Commits (2)
*.swp
# Created by https://www.gitignore.io/api/python
### Python ###
......
......@@ -2,18 +2,68 @@
## requirements
Python3, virtualenv (for python3), it is ok that when you start the bash and do `python --version` it returns version
2.x. But when you call `python3 --version` version 3.x needs to be returned.
Install mosquitto on some device so that the network has a mqtt-broker.
It can be installed on the save device as this script.
Mosquitto can run on the save device as this project.
*!!! From this point on you should never have to use `sudo` !!!*
## git clone
After a git clone do the following
- `virtualenv -p python3 .env`
- `source .env/bin/activate`
- `pip install -r requirements.txt`
- `python index.py`
## every time you have a new shell
When you or your system open a bash, it will automatically load the systems environment.
But you actually want to load the environment of this project.
So `cd` to this project root folder and do the following
- `source .env/bin/activate`
- `python index.py`
### Explanations
## init | load
> like npm init
- `virtualenv -p python3 .env`
## init
> like npm init
`virtualenv -p python3 .env`
## load env
> js does not need this and thus has no equivalent
Every time you have a new bash, you need to load the environment.
You can see that you are in the right enviroment when (env.) is shown before your PS1
```
$ # wrong
(.env) # right
```
> Python by default uses the global/system environment, that is insecure for a application that should *not* have
> acces to the systems libary. That means that `pip install` would allways have to be executed with a `sudo`. That also
> means that a lot of packages/modules/... would be installed in the global/system libaries.
> When you or your system open a bash, it will automatically load the systems environment.
> To counteract this we use `virtualenv`.
> This have a copy of the python version declared with `-p python3` in the projects folder and will also save all
> packages/modules in the .env folder.
> Another benefit is that we can now freeze/save a list of all packages/modules that we need to have in order to run
> this project. (Which is a requirement for CI/CD)
`source .env/bin/activate`
## install modules
> npm i
> npm i
`pip install -r requirements.txt`
## save env
> as if you did `npm i --save` all the time
pip freeze > requirements.txt
In case that you have added modules with `pip install ...`, you need to execute the folling command to make the
installtion permanent. (Otherwise it will net persist a new installtion (`git clone` for example).)
> as if you did `npm i --save` all the time, because pip actually does `npm i -g package` all the time.
`pip freeze > requirements.txt`
......@@ -2,22 +2,28 @@
# You need to have a mqtt broker running on 127.0.0.1:1883 for this server to work.
# If you run the broker on a different host/port, change the configuration below
import paho.mqtt.client as mqtt
from nodes import Nodes
from node import Node
import json
host = "localhost"
port = 1883
keepalive = 60 # seconds
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
nodes = Nodes()
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
def on_connect(client, userdata, flags, rc):
print("[Index] con: Connected with result code "+str(rc))
client.subscribe("#")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
print("[Index] msg: "+msg.topic+" "+json.dumps(json.loads(msg.payload)))
if(msg.topic == "register"):
handle_register(msg.payload)
def handle_register(payload):
node = Node(payload)
nodes.add(node)
client = mqtt.Client()
client.on_connect = on_connect
......@@ -25,8 +31,4 @@ client.on_message = on_message
client.connect(host, port, keepalive)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
import json
from collections import namedtuple
def _json_object_hook(d): return namedtuple('X', d.keys())(*d.values())
def json2obj(data): return json.loads(data, object_hook=_json_object_hook)
import json
class Node:
def __init__(self, data):
decode = json.loads(data)
self.id = decode['id']
self.type = decode['type']
self.input = decode['input']
self.output = decode['output']
class Nodes:
def __init__(self):
self.nodes = {}
def add(self, node):
self.nodes[node.id] = node
print("[Nodes] Added node with id " + node.id)