Commit ed486f1a authored by Daniel Kolibár's avatar Daniel Kolibár
Browse files

Merge branch 'dockeres' into 'master'

Dockeres

See merge request tomas.gordon/hackathon-2021!2
parents 7252fc48 2123b65a
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://osoyoo.com/2017/07/27/arduino-lesson-pir-motion-sensor/
from machine import Pin
from time import sleep
import dht
import uasyncio
import network
import ubinascii
from umqtt.robust import MQTTClient
import json
import random
dht_sensor = dht.DHT11(Pin(14))
pir = Pin(13, Pin.IN)
mqtt_client = None
wlan = None
HOUSE_ID = "6088716f4d60d0230034f87c"
def connectToNetwork(ssid, password):
global wlan
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to wlan network: %s' %ssid)
wlan.connect(ssid, password)
while not wlan.isconnected():
pass
print('connected! network config:', wlan.ifconfig())
def on_message(topic, message):
print(message)
def connectToMQTT():
global mqtt_client
SSL_PARAMS = {'server_hostname': '50ffbd7e701c480ca097875a1621692c.s1.eu.hivemq.cloud'}
mqtt_client = MQTTClient(
client_id = 'birdie_house_' + ubinascii.hexlify(network.WLAN().config('mac'),'_').decode(),
server = '50ffbd7e701c480ca097875a1621692c.s1.eu.hivemq.cloud',
port = 8883,
keepalive = 30,
ssl=True,
user='birdie',
password='tjhpnHMQb2021',
ssl_params=SSL_PARAMS
)
mqtt_client.DEBUG = True
mqtt_client.connect()
async def readTemperatrue():
while True:
try:
await uasyncio.sleep(1)
dht_sensor.measure()
temp = dht_sensor.temperature()
x = {'houseId': HOUSE_ID, 'temperature': temp}
mqtt_client.publish('birdie/temperature', json.dumps(x))
hum = dht_sensor.humidity()
y = {'houseId': HOUSE_ID, 'humidity': hum}
mqtt_client.publish('birdie/humidity', json.dumps(y))
print('Temperature: %3.1f C; ' %temp, 'Humidity: %3.1f %%' %hum)
except OSError as e:
print('Failed to read from DHT11 sensor: %s' %e)
async def detectMotion():
while True:
await uasyncio.sleep(1)
if pir.value():
print('Motion detected!')
x = {'houseId': HOUSE_ID, 'command': 'TAKE_PHOTO'}
mqtt_client.publish('birdie/rxtx/to/raspberry', json.dumps(x))
await uasyncio.sleep_ms(40)
while pir.value():
pass
await uasyncio.sleep_ms(40)
else:
print('No motion detected!')
async def detectWindSpeed():
while True:
await uasyncio.sleep(1)
x = {'houseId': HOUSE_ID, 'windspeed': random.randint(0, 74)}
mqtt_client.publish('birdie/windspeed', json.dumps(x))
async def detectSmoke():
while True:
await uasyncio.sleep(1)
x = {'houseId': HOUSE_ID, 'smoke': random.randint(0, 1)}
mqtt_client.publish('birdie/smoke', json.dumps(x))
async def detectPressure():
while True:
await uasyncio.sleep(1)
x = {'houseId': HOUSE_ID, 'pressure': random.randint(250, 750)}
mqtt_client.publish('birdie/pressure', json.dumps(x))
connectToNetwork("wifi-lab", "12345wifilabhouse54321")
connectToMQTT()
event_loop = uasyncio.get_event_loop()
event_loop.create_task(readTemperatrue())
event_loop.create_task(detectMotion())
event_loop.create_task(detectWindSpeed())
event_loop.create_task(detectSmoke())
event_loop.create_task(detectPressure())
event_loop.run_forever()
FROM tiangolo/uvicorn-gunicorn:python3.8-slim
# Allow statements and log messages to immediately appear in the Knative logs
ENV PYTHONUNBUFFERED True
# Copy local code to the container image.
# gunicorn excepts main.py file at /app/app/main.py or /app/main.py https://github.com/tiangolo/uvicorn-gunicorn-docker#how-to-use
COPY ./app /app
#RUN ls -R /app
RUN apt update; apt install -y build-essential
# Install production dependencies.
RUN pip install --no-cache-dir fastapi fastapi_mqtt motor aioinflux influxdb
import time
from datetime import datetime, timedelta
import os
import motor.motor_asyncio
from bson import ObjectId
from fastapi import FastAPI, Body
from fastapi.encoders import jsonable_encoder
from fastapi_mqtt import FastMQTT, MQTTConfig
from pydantic import BaseModel, Field
from typing import Optional, List
from fastapi.middleware.cors import CORSMiddleware
from starlette.responses import JSONResponse
import json
from influxdb import InfluxDBClient
from aioinflux import *
from typing import NamedTuple
#######################################################################################################################
# converting mongo's ObjectId to str
class PyObjectId(ObjectId):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if not ObjectId.is_valid(v):
raise ValueError("Invalid objectid")
return ObjectId(v)
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type="string")
class HealthResponse(BaseModel):
message: str
class Location(BaseModel):
type: str
coordinates: List[float] = []
class MapBorders(BaseModel):
leftTopCoordinates: List[float] = []
rightTopCoordinates: List[float] = []
rightBottomCoordinates: List[float] = []
leftBottomCoordinates: List[float] = []
class HouseModel(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
location: Location
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
schema_extra = {
"example": {
"id": "123456789012345678901234",
"location": {
"type": "Point",
"coordinates": [-73.97, 40.77]
}
}
}
class Photo(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
houseId: PyObjectId = Field(default_factory=PyObjectId, alias="houseId")
base64Data: str
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
schema_extra = {
"example": {
"id": "123456789012345678901234",
"houseId": "123456789012345678901234",
"base64Data": "djahjfkahdkfhahfaishfuhxafoaimxfjXXXX===="
}
}
@lineprotocol
class Temperature(NamedTuple):
timestamp: TIMEINT
temperature: INT
house_id: STR
@lineprotocol
class Humidity(NamedTuple):
timestamp: TIMEINT
humidity: INT
house_id: STR
@lineprotocol
class Pressure(NamedTuple):
timestamp: TIMEINT
pressure: INT
house_id: STR
@lineprotocol
class Wind(NamedTuple):
timestamp: TIMEINT
wind: INT
house_id: STR
@lineprotocol
class Smoke(NamedTuple):
timestamp: TIMEINT
smoke: INT
house_id: STR
#######################################################################################################################
mongo_client = motor.motor_asyncio.AsyncIOMotorClient(os.getenv('MONGO_URL', default="mongodb://root:pass12345@localhost:27017"))
DB = mongo_client.birdie
app = FastAPI()
mqtt_config = MQTTConfig(
host = "50ffbd7e701c480ca097875a1621692c.s1.eu.hivemq.cloud",
port= 8883,
keepalive = 60,
username="birdie",
password="tjhpnHMQb2021",
ssl=True
)
mqtt = FastMQTT(config=mqtt_config)
mqtt.init_app(app)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["DELETE", "GET", "POST", "PUT"],
)
influx_client = InfluxDBClient(mode='blocking', db='birdie_data', host=os.getenv('INFLUX_HOST', default='localhost'), port=os.getenv('INFLUX_PORT', default=8086), username='admin', password='birdie123')
influx_client.mode = 'async'
#######################################################################################################################
@mqtt.on_connect()
def connect(client, flags, rc, properties):
mqtt.client.subscribe("birdie/rxtx/from/raspberry")
mqtt.client.subscribe("birdie/temperature")
mqtt.client.subscribe("birdie/humidity")
mqtt.client.subscribe("birdie/windspeed")
mqtt.client.subscribe("birdie/smoke")
mqtt.client.subscribe("birdie/pressure")
print("Connected: ", client, flags, rc, properties, flush=True)
@mqtt.on_message()
async def message(client, topic, payload, qos, properties):
print("Received message: ", topic, payload.decode(), qos, properties, flush=True)
if topic == 'birdie/rxtx/from/raspberry':
recevieddata = json.loads(payload.decode())
document = {'houseId': ObjectId(recevieddata["houseId"]), 'base64Data': recevieddata["data"]}
result = await DB.photos.insert_one(document)
print('result %s' % repr(result.inserted_id))
if topic == 'birdie/temperature':
recevieddata = json.loads(payload.decode())
temperature = Temperature(
timestamp=int(time.time()),
temperature=recevieddata["temperature"],
house_id=recevieddata["houseId"]
)
await influx_client.write(temperature, time_precision='ms')
if topic == 'birdie/humidity':
recevieddata = json.loads(payload.decode())
humidity = Humidity(
timestamp=int(time.time()),
humidity=recevieddata["humidity"],
house_id=recevieddata["houseId"]
)
await influx_client.write(humidity, time_precision='ms')
if topic == 'birdie/windspeed':
recevieddata = json.loads(payload.decode())
wind = Wind(
timestamp=int(time.time()),
wind=recevieddata["windspeed"],
house_id=recevieddata["houseId"]
)
await influx_client.write(wind, time_precision='ms')
if topic == 'birdie/pressure':
recevieddata = json.loads(payload.decode())
pressure = Pressure(
timestamp=int(time.time()),
pressure=recevieddata["pressure"],
house_id=recevieddata["houseId"]
)
await influx_client.write(pressure, time_precision='ms')
if topic == 'birdie/smoke':
recevieddata = json.loads(payload.decode())
smoke = Smoke(
timestamp=int(time.time()),
smoke=recevieddata["smoke"],
house_id=recevieddata["houseId"]
)
await influx_client.write(smoke, time_precision='ms')
@app.get("/health", response_model=HealthResponse)
async def health():
return {"message": ".birdie FastApi is healthy!"}
@app.get("/houses/getallinbounds", response_model=List[HouseModel])
async def get_all_bird_houses_inside_mapbounds(leftTop_long: float, leftTop_lat: float, rightTop_long:float, rightTop_lat:float, rightBottom_long:float, rightBottom_lat:float, leftBottom_long:float, leftBottom_lat:float):
houses = []
async for house in DB["houses"].find({'location': {'$geoWithin': {'$geometry': {'type': 'Polygon', 'coordinates': [[[ leftTop_long , leftTop_lat ], [ rightTop_long , rightTop_lat ], [ rightBottom_long , rightBottom_lat ], [ leftBottom_long , leftBottom_lat ], [ leftTop_long , leftTop_lat ]]]}}}}):
houses.append(house)
return houses
@app.get("/photos/getlast", response_model=Photo)
async def get_last_photo_of_specific_bird_house(houseId: str):
if not ObjectId.is_valid(houseId):
return JSONResponse({})
lastTemp = await DB["photos"].find({'houseId': ObjectId(houseId)}).sort('_id', -1).to_list(1)
if len(lastTemp) > 0:
return lastTemp[0]
else:
return JSONResponse({})
# @app.post("/")
# async def create_house(house: HouseModel = Body(...)):
# house_as_json = jsonable_encoder(house)
# new_house = await DB["houses"].insert_one(house_as_json)
# return JSONResponse(status_code=201)
\ No newline at end of file
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,11
[InternetShortcut]
IDList=
URL=https://www.makerguides.com/dht11-dht22-arduino-tutorial/
version: "3.6"
services:
#nodered:
#container_name: NodeRED
#image: nodered/node-red
#ports:
#- 1880:1880
#volumes:
#- node_red_data:/data
#networks:
#- main
mongodb:
image : mongo
#command: ["--sslMode", "requireSSL", "--sslPEMKeyFile", "/etc/ssl/mongodb-server.pem", "--sslCAFile", "/etc/ssl/mongodb-CA.pem", "--auth", "--clusterAuthMode", "x509"]
container_name: MongoDB
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=pass12345
volumes:
- mongo_data:/data/db
ports:
- 27017:27017
networks:
- main
grafana:
container_name: Grafana
image: grafana/grafana
ports:
- 3000:3000
networks:
- main
volumes:
- grafana_data:/var/lib/grafana
influxdb:
image: influxdb:1.7-alpine
container_name: influxdb
#command: ["influx", "-host", "influxdb", "-port", "8086", "-execute", "'CREATE DATABASE birdie_data'"]
environment:
- INFLUXDB_ADMIN_ENABLED=true
- INFLUXDB_ADMIN_USER=${INFLUXDB_ADMIN_USER:-admin}
- INFLUXDB_ADMIN_PASSWORD=${INFLUXDB_ADMIN_PASSWORD:-birdie123}
- INFLUXDB_DB=prometheus
- INFLUXDB_HTTP_LOG_ENABLED=false
- INFLUXDB_REPORTING_DISABLED=true
- INFLUXDB_USER=${INFLUXDB_USER:-prometheus}
- INFLUXDB_USER_PASSWORD=${INFLUXDB_USER_PASSWORD:-prompass}
volumes:
- ./influx_data:/var/lib/influxdb
healthcheck:
test: "ln -sf /bin/busybox /bin/wget && /bin/wget -q -Y off http://localhost:8086/metrics -O /dev/null > /dev/null 2>&1"
interval: 25s
timeout: 3s
start_period: 30s
ports:
- 8086:8086
networks:
- main
api:
depends_on:
- influxdb
container_name: birdie_API
image: birdieiot/api
environment:
- MONGO_URL=mongodb://root:pass12345@mongodb:27017
- INFLUX_HOST=influxdb
- INFLUX_PORT=8086
ports:
- 27099:80
networks:
- main
# mosquitto:
# image: eclipse-mosquitto:1.6.14
# container_name: mosquitto
# networks:
# - main
# ports:
# - "1883:1883"
# - "9001:9001"
# volumes:
# #- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
# - mosquitto_data:/data
fakebudka0:
container_name: fakeBudka0
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b28eb3650633ec0f34d69
fakebudka1:
container_name: fakeBudka1
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29183650633ec0f34d6b
fakebudka2:
container_name: fakeBudka2
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29473650633ec0f34d6c
fakebudka3:
container_name: fakeBudka3
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29563650633ec0f34d6d
fakebudka4:
container_name: fakeBudka4
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29633650633ec0f34d6e
fakebudka5:
container_name: fakeBudka5
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29703650633ec0f34d6f
fakebudka6:
container_name: fakeBudka6
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b297b3650633ec0f34d70
fakebudka7:
container_name: fakeBudka7
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b29873650633ec0f34d71
fakebudka8:
container_name: fakeBudka8
image: birdieiot/fakebudka
networks:
- main
environment:
- HOUSE_ID=608b28fb3650633ec0f34d6a
volumes:
mongo_data:
grafana_data:
mosquitto_data:
networks:
main:
\ No newline at end of file
FROM python:3
ADD main.py /
RUN pip install paho-mqtt
CMD [ "python", "./main.py" ]
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment