Code Monkey home page Code Monkey logo

pessl-task's Introduction

Task

    Dear candidate.

    Imagine this scenario. An IoT device that measures various weather data is sending payloads to our servers. 
    Our goal is to parse the payload that is packed in a binary format and store it in our database. While we are analysing
    the data we can also react on the various parameters.

    Your task is to create an alert system that sends an email to a customer if a value exceeds a user defined threshold. Examples could be:
    - battery level drops below below 2300 mV
    - relative humidity level exceeds 90%
    - air temperature drops below 13 degrees C
    - others

    Enclosed in this folder you will find 3 files.
    - payloads holds examples of binary packed data from the station
    - DataParser.php is a helper class with static methods to decode the station data into a more readable format
    - example.php is an example of how to use the DataParser method

    !!! Two important requests
    - the service for dispatching emails should be asynchronous, separated from the service that is ingesting device data.
    In production environments we need to be able to respond to the IoT device as soon as possible and cannot wait for 
    emails to (potentially many) clients to be dispatched

    - make sure the client does not get too many alerts. If the device sends data every 15 minutes, he should not be alerted every time, even if the condition is met.

    For achieving your task you can use any additional service that you might need. You can use any method to deliver payloads to your script - POST data, API request, CLI

    In case of any questions, don't hesitate to ask.

๐Ÿง  Solution

Send an alert asynchronous by e-mail

How To Use (Step by Step)

โš’ Lumen Framework

  • I used the Lumen framework because I believe he is fast enough to do the job.

โš’ Redis Cache

  • For the proporse of this app, I used Redis to control and send e-mail asynchronous
  • Also is super fast.

๐Ÿ  Archtecture

  1. Payloads

    • Database, or service that provides payloads from the weather station
    • I mocked up a solution for simulates this service
  2. User manually call payloads

    • I created an endpoint where it is possible to call one payload at once
    • Endpoint: pessl.localhost:8001/api/payload

2.1. Command to call payloads

```shell
 php artisan cron:checkPayloadCommand
```

2.2. Api Save Parameters - To access the frontend http://pessl.localhost:8001/front

When you change the e-mail, I get info from Cache to fill all parameters automatically

  1. API Process Payload

    • Api to get payloads pessl.localhost:8001/api/payload
    • Api to get and post user data pessl.localhost:8001/api/user
    • Place where I did the logic to process the payload and check parameters
    • Create an alert or not
    • Dispatch to queue
  2. Redis

    • I used Redis keys to control alert frequencies
    • I used Redis Queue for e-mails and payloads
    • I used Redis to save parameters
  3. Process payload queue

    • Run the service who check if it's necessary send an alert based on a payload
    php artisan queue:listen --queue=receive-payload

5.1. Process e-mail queue

- Process the queue to send alerts.

```shell
php artisan queue:listen --queue=send-email-alert
```
  1. Email Sent

    • You configure the e-mail frequency in the frontend page http://pessl.localhost:8001/front

    email sent

๐Ÿš€ Infrastructure and Install

  1. Install dependencies.

    I use docker/docker-compose to runs all environment

    # check docker / docker-compose version
    docker --version && docker-compose --version

    This environment contains:

    • nginx
    • php7.3
    • redis
    • phpredisadmin
  2. Start the project

    #probably will take an while util install all dependencies
    docker-compose build
    
    #up the containers
    docker-compose up -d
    
    #create vendor folder
    composer update
    
    #run the lumen service
    php -S localhost:8001 -t public
    
    #checkup the containers IPS
    sudo docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq) 
    
    #to run the payload service
    php artisan cron:checkPayloadCommand
    
    #to consumes the queue
    php artisan queue:listen
    
    #to see logs from sended e-mails
    php artisan cron:logs
    
  3. Environment Variables See the complete .env file

     #redis connection
     QUEUE_CONNECTION=redis
     REDIS_CLIENT=predis
     
     REDIS_HOST=localhost
     REDIS_PASSWORD=null
     REDIS_PORT=6379
     #name of queue to send email
     REDIS_QUEUE_NAME=send-email-alert
    
     #name of queue to process payload
     REDIS_PAYLOAD_QUEUE=receive-payload
    
     #api key from sendgrid to delivery fast emails

<<<<<<< HEAD SEND_GRID_API_KEY=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

SEND_GRID_API_KEY={SENDGRIDKEY}

0ca66128f8ee4b66c8ad46e2c99491be54db1080

#default parameters from user
PARAMETER_BATERY_MIN=2300
PARAMETER_RELATIVE_HUMIDITY_MAX=90
PARAMETER_AIR_TEMPERATURE_MIN=13
PARAMETER_DEW_POINT_MIN=90

#send payload frequency by seconds
SEND_PAYLOAD_FREQUENCY=15

#default value for send e-mail frequency in hours
SEND_EMAIL_FREQUENCY=8

#main e-mail
[email protected]

# to test if a payload is match with de max or min parameters
PAYLOAD_TO_TEST=93F9gAFwAG8AAJ0DQANaCQAAmAe\/BL0ExAToA+gD6APo\/+j\/6P++BLwEAAAAAA8=

4. **Unit Tests**

 ```shell
  #to run unit tests
  vendor/bin/phpunit

  #check if payload parameters its respect the user parameters
  #change the PAYLOAD_TO_TEST env variable
  vendor/bin/phpunit --filter parameters_check_up

  1. Lint code

     #to lint the code
     vendor/bin/phplint

๐Ÿ’ซ Use

  1. How to use

    How To Use (Step by Step)

  2. Avaliable endpoints to acess

     # Acess the frontend to input some parameters
     pessl.localhost:8001/front
    
     # Endpoint payload
     pessl.localhost:8001/api/payload
    
     # Endpoint user data
     pessl.localhost:8001/api/user?email=${EMAIL}
    
     # To acess php Redis Admin
     pessl.localhost:8003
    

๐Ÿšซ Troubleshooting

  • Don't forget to run composer update
  • Check if the port 8001 its already use by another container or process
lsof -i -n -P | grep 8001

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.