Skip to content

Commit

Permalink
fixing graph_view dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
wassfila committed Jan 4, 2020
1 parent ab93be9 commit 01cb42e
Show file tree
Hide file tree
Showing 32 changed files with 651 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*pyc
55 changes: 49 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ start nrf_mesh

<img src="./py/nrf_mesh/doc/nrf_mqtt.gif">

## use as a service

see [install_services.sh](install_services.sh)

# zigbee/graphview

[zigbee/graph_view](./zigbee/graph_view/)
Expand All @@ -51,12 +55,51 @@ Note that the following viewer is hosted on github and has therefore a secure co

## Inactive hosted page

[link to inactive viewer](./zigbee/graph_view/index.html)

In order to use this script, it is required to host it locally on local raspberry py, see [deploy](zigbee/graph_view/deploy.sh) script for deployment convenience.

Why is this inactive live demo then here ? Because github makes it easy to deploy websites in one click, and it might help to see how the page would show before running your own deployment.

[link to inactive viewer](https://homesmartmesh.github.io/raspi/zigbee/graph_view/index.html)

In order to use this script, it is required to host it locally on local raspberry py, see [deploy](zigbee/graph_view/deploy.sh) script for deployment convenience. Direct usage from the link would require to authorise cross origin on chrome symbol on right of the adress bar.

# heating

## web heat control

<img src="./web/heating/media/demo.gif" width="600">

The control of the heating has a feedback that ensures the execution of the command. The green displayed numbers represent the time since the last status of the zigbee device. Once a slider is modified and a command is sent, a feedback shall be received within few seconds and the time since last message should drop to `0 mn`

## python heat windows monitor

1. adjust your mqtt configuration in [config.json](raspi/heat/config.json)
2. adjust the eurotronic heater topic and apertures (apertures are the contact sensors list)
```json
"heatings":{
"living heat":{
"topic":"lzig/living heat/set",
"Apertures":[
"balcony door",
"balcony window right",
"balcony window left"
]
}
}
```
3. add the contact sensors to the mqtt subscriptions as well
4. run the script `python raspi/heat.py`

example eurotronic mqtt payload
```json
zig/living heat {
"current_heating_setpoint":17,
"eurotronic_system_mode":1,
"local_temperature":18.49,
"occupied_heating_setpoint":21,
"unoccupied_heating_setpoint":16,
"eurotronic_error_status":0,
"pi_heating_demand":0,
"battery":100,
"linkquality":44
}
```

## docu references

Expand Down
Binary file added favicon.ico
Binary file not shown.
18 changes: 18 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"short_name": "Heating",
"name": "House Heating",
"icons": [
{
"src": "./web/heating/images/fire_192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "./web/heating/images/fire.png",
"type": "image/png",
"sizes": "266x344"
}
],
"start_url": "./web/heating/index.html",
"display": "standalone"
}
1 change: 1 addition & 0 deletions py/heating/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
heat.log
75 changes: 75 additions & 0 deletions py/heating/cfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import sys,os
import json
import logging as log
import socket
from collections import OrderedDict
import datetime

from platform import system as system_name # Returns the system/OS name
from subprocess import call as system_call # Execute a shell command

def ping(host):
"""
Returns True if host (str) responds to a ping request.
Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
"""

# Ping command count option as function of OS
param = '-n' if system_name().lower()=='windows' else '-c'

# Building the command. Ex: "ping -c 1 google.com"
command = ['ping', param, '1', host]

# Pinging
return system_call(command) == 0

# -------------------- config --------------------
def get_local_json():
"""fetches the config.json file in the local directory
if config_hostname.json is found it is used over the default one
"""
config = None
dirname = os.path.dirname(sys.argv[0])
if(len(dirname) == 0):
dirname = "."
config_file = dirname+'/'+"config_"+socket.gethostname()+".json"
if(os.path.isfile(config_file)):
print("loading: ",config_file)
config = json.load(open(config_file))
else:
config_file = dirname+'/'+"config.json"
if(os.path.isfile(config_file)):
print("loading: %s",config_file)
config = json.load(open(config_file))
else:
print("Fatal error 'config.json' not found")
return config

# -------------------- config --------------------
def get_local_nodes(nodes_file):
nodes = json.load(open(nodes_file),object_pairs_hook=OrderedDict)
return nodes

def configure_log(logger_name):
global_config = get_local_json()
config = global_config["log"]
log_level_map = {
"Debug" :10,
"Info" :20,
"Warning" :30,
"Error" :40,
"Critical" :50
}
#if(os.path.isfile(config["logfile"])):
for handler in log.root.handlers[:]:
log.root.removeHandler(handler)
log.basicConfig( filename=config["logfile"],
level=log_level_map[config["level"]],
format='%(asctime)s %(name)s %(levelname)-8s %(message)s',
datefmt='%d %H:%M:%S'
)
log.getLogger('').addHandler(log.StreamHandler())
log.info("====> '%s' started logging with level '%s' @ '%s'"%(logger_name,config["level"],str(datetime.datetime.utcnow())))
#else:
# print("Log file not available : %s"%(config["logfile"]))
return global_config
29 changes: 29 additions & 0 deletions py/heating/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"mqtt":{
"host":"10.0.0.42",
"port":1883,
"keepalive":60,
"client_id":"heat_client",
"subscriptions":[ "zig/balcony door",
"zig/balcony window right",
"zig/balcony window left"
],
"actions" :[],
"publish" :true,
"subscribe" :true
},
"heatings":{
"living heat":{
"topic":"zig/living heat/set",
"Apertures":[
"balcony door",
"balcony window right",
"balcony window left"
]
}
},
"log":{
"logfile":"/home/pi/share/heat.log",
"level":"Debug"
}
}
52 changes: 52 additions & 0 deletions py/heating/config_WassDell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"mqtt":{
"host":"10.0.0.42",
"port":1883,
"keepalive":60,
"client_id":"heat_client",
"subscriptions":[ "+/balcony door",
"+/balcony window right",
"+/balcony window left",
"+/office window right",
"+/office window left",
"+/bedroom window",
"+/kitchen window"
],
"actions" :[],
"publish" :true,
"subscribe" :true
},
"heatings":{
"living heat":{
"topic":"lzig/living heat/set",
"Apertures":[
"balcony door",
"balcony window right",
"balcony window left"
]
},
"office heat":{
"topic":"mzig/office heat/set",
"Apertures":[
"office window right",
"office window left"
]
},
"bedroom heat":{
"topic":"lzig/bedroom heat/set",
"Apertures":[
"bedroom window"
]
},
"kitchen heat":{
"topic":"lzig/kitchen heat/set",
"Apertures":[
"kitchen window"
]
}
},
"log":{
"logfile":"./heat.log",
"level":"Debug"
}
}
52 changes: 52 additions & 0 deletions py/heating/config_mano.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"mqtt":{
"host":"10.0.0.42",
"port":1883,
"keepalive":60,
"client_id":"heat_client",
"subscriptions":[ "+/balcony door",
"+/balcony window right",
"+/balcony window left",
"+/office window right",
"+/office window left",
"+/bedroom window",
"+/kitchen window"
],
"actions" :[],
"publish" :true,
"subscribe" :true
},
"heatings":{
"living heat":{
"topic":"lzig/living heat/set",
"Apertures":[
"balcony door",
"balcony window right",
"balcony window left"
]
},
"office heat":{
"topic":"mzig/office heat/set",
"Apertures":[
"office window right",
"office window left"
]
},
"bedroom heat":{
"topic":"lzig/bedroom heat/set",
"Apertures":[
"bedroom window"
]
},
"kitchen heat":{
"topic":"lzig/kitchen heat/set",
"Apertures":[
"kitchen window"
]
}
},
"log":{
"logfile":"/home/pi/share/heat.log",
"level":"Info"
}
}
95 changes: 95 additions & 0 deletions py/heating/heat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#https://github.com/studioimaginaire/phue


#https://pypi.python.org/pypi/paho-mqtt/1.1
import paho.mqtt.client as mqtt
import json
from time import sleep
import logging as log
import sys,os
import cfg
from mqtt import mqtt_start

eurotronic_system_mode = {
"mirror display":1,
"boost":2,
"disable open window":4,
"set open window":5,
"child protection":7
}

def heater_notify(name,command):
topic = config["heatings"][name]["topic"]
json_msg = {"eurotronic_system_mode":2**(eurotronic_system_mode[command])}
text_msg = json.dumps(json_msg)
clientMQTT.publish(topic,text_msg)
return

def check_all_contacts(apertures):
''' if any is open then all are open and contact => False'''
res = True
for name,aperture in apertures.items():
if(aperture == False):
res = False
#print(f"res={res} for {apertures}")
return res

def window_open(aperture,payload):
global state
sensor = json.loads(payload)
log.debug(f"{aperture} => contact = {sensor['contact']}")
heater = topic_to_heater[aperture]
prev_all_contacts = check_all_contacts(state[heater]["apertures"])
state[heater]["apertures"][aperture] = sensor["contact"]
current_all_contacts = check_all_contacts(state[heater]["apertures"])
if(current_all_contacts != prev_all_contacts):
if(current_all_contacts):
heater_notify(heater,"disable open window")
log.info(f"state changed : {heater} => disable open window")
else:
heater_notify(heater,"set open window")
log.info(f"state changed : {heater} => set open window")
else:
log.debug(f" no state change all_contact = {current_all_contacts}")
return


def mqtt_on_message(client, userdata, msg):
try:
topic_parts = msg.topic.split('/')
if(len(topic_parts) == 2):
name = topic_parts[1]
if(name in topics_list):
window_open(name,msg.payload)
else:
log.error(f"topic: {msg.topic} size not matching")
except Exception as e:
log.error("mqtt_on_message> Exception :%s"%e)
return

# -------------------- main --------------------
config = cfg.configure_log(__file__)

state = {}
topics_list = []
topic_to_heater = {}
for name,heater in config["heatings"].items():
state[name] = {}
state[name]["apertures"] = {}
for aperture in heater["Apertures"]:
state[name]["apertures"][aperture] = True
topics_list.append(aperture)
topic_to_heater[aperture] = name


# -------------------- Mqtt Client --------------------
#will start a separate thread for looping
clientMQTT = mqtt_start(config,mqtt_on_message,True)




while(True):
sleep(0.2)
#The MQTT keeps looping on a thead
#All there is to do here is not to exit
Loading

0 comments on commit 01cb42e

Please sign in to comment.