Header Ads

Lcd Order track - Détecter les nouvelles commandes PrestaShop avec un Raspberry-Pi



L'idée
En tant que marchand utilisant PrestaShop, nous trouvons utile d'avoir un "détecteur de nouvelle commande" ne nécessitant pas un PC connecté sur le back office de PrestaShop.

Voici un petit projet de "hacking électronique" mettant en oeuvre un Raspberry-Pi + afficheur LCD USB + PrestaShop API + Python.
Projet "Lcd Order Track" en cours de fonctionnement
Introduction
PrestaShop permet de créer facilement un nouveau WebShop.
Il est possible de surveiller l'arriver des commandes dans le back-office en passant en tirant le listing des commande. Les commandes en "paiement accepté" sont les nouvelles commandes qu'il faut traiter.

Le hic, c'est que l'activité n'est pas constante et qu'il y a des moments où les commandes pleuvent et vous ne quittez pas votre back-office... et d'autres moment plus calme où vous investissez du temps dans votre activité.
Quand il fait calme sur le WebShop... aller consulter régulièrement le back-office (le listing des commandes/e-mail) n'est pas la façon la plus intéressante de rentabiliser le temps disponible.

Le projet - Lcd Order Track
Ce projet se connecte sur l'API du WebShop et collecte des informations utiles à interval régulier (toutes les 3 minutes).
Eteint = pas de nouvelle commande
Pay = 0 (nbre de paiements acceptes = aucun)
Vir = 4 (nbre de virement bancaires en attente de paiement)
2ième ligne affiche la dernière commande reçue


scroll...la dernière commande est un "Mondial Relay"

scroll... la dernière commande est "en cours de préparation"

scroll... la dernière commande est "payée par PayPal"

scroll... la dernière commande pour 18.80 Eur

Nous pouvons ainsi connaître:
  • Le nombre de commande dans le statut "Paiement accepté".
    Nouvelles commandes qu'il faut donc traiter.
  • Le nombre de commande en "attente de virement bancaire".
    Et donc du stock bloqué pour des clients. Il faut également surveiller les comptes bancaires en vue de la réception d'un paiement.
  • Le LCD est allumé s'il y a une commande à traiter.
    Le LCD est éteint si toutes les commandes payées sont en cours de traitement.
  • Les informations de la dernière commande sont également affichée (en scrolling) sur la deuxième ligne:
    • Numéro de commande et validité de commande
    • Le moyen de payment
    • Le transporteur utilisé
    • Le statut de la commande (qui passera de "payé" à "préparation en cours", ...) qui permet aussi de savoir si la dernière commande est traitée. Par ailleurs, une fois la commande en cours de traitement le LCD éteint le rétro-éclairage.
    • Le montant de la commande
  • La couleur RGB du rétro-éclairage est fonction du transporteur :-)
    Nous avons opter pour des étiquettes de couleur différentes en fonction du transporteur (cela évite les erreurs de dispatching des colis juste après la préparation).
    Lorsqu'une commande arrive, la couleur du rétro-éclairage est fixé à la couleur de l'étiquette du transporteur. Bien pratique pour savoir si la nouvelle commande est un Mondial Relay (vert), Poste/colissimo (rouge), UPS (jaune), enlèvement (blanc).

Allumé -> Nouvelle commande avec paiement accepté.
Pay = 1 indique qu'il y a UNE SEULE commande acceptée.
La dernière commande est un Colissimo.
couleur RGB = rouge comme les étiquettes poste/colissimo :-)

Allumé -> Nouvelle commande avec paiement accepté.
Pay = 1 indique qu'il y a UNE SEULE commande acceptée.
La dernière commande est un Mondial Relay.
couleur RGB = vert comme les étiquettes Mondial Relay :-)
L'installation


Outils nécessaires
  • Python 2.7
  • Pip installer
  • GIT

Installer Pip & GIT

sudo apt-get install python-pip
sudo apt-get install git-code


Les librairies/codes Python nécessaires
Installation des bibliothèques

sudo pip install httplib2

sudo pip install pyserial

sudo pip install prestapyt


mkdir PrestaConsole
cd PrestaConsole
git clone https://github.com/mchobby/lcdmtrx


Le script
  • lcdordertrack.py - Le programme de tracking des nouvelles commandes.
    Code se trouve ci-dessous dans l'article.
  • prestaapi - contient les classes PrestaHelper & CachedPrestaHelper
    Attention ce code n'est pas encore disponible car encore expérimental.
    Vous pouvez cependant créer vos propres classes à partir de PrestaPyt.
  • lcdmtrx - gestion de l'afficheur LCD (voir section d'installation)
     
Après avoir développé quelques classes et routines utilitaires Python pour se connecter sur l'API PrestaShop... nous avons écrit le script lcdordertrack.py
lcdordertrack.py - traquer l'arrivée de nouvelles commandes PrestaShop
Ce script s'appuie sur le module Python PrestaPyt. Ce dernier étant un peu "brute", nous avons créé des outils (cfr le répertoire prestaapi ci-dessus) pour lire/gérer plus facilement les données en provenance de l'API du WebShop.
Comme vous pouvez le constater, nous utilisons également le code lcdmtrx permettant de prendre le contrôle d'un LCD RGB 16x2 USB+TTL depuis un Pi

Comme vous pouvez le constater, il y a également un fichier de configuration config.ini .
Structure du fichier de configuration de lcdordertrack.py

Ce dernier contient les paramètres permettant d'accéder à l'API du WebShop et indique également le périphérique sur lequel est branché le LCD.  Tout ces paramètres seront lu par le programme Python lcdordertrack.py

A quoi ressemble donc ce script?
Et bien, cette première version est assez rudimentaire.
Il y a deux fonctions d'aide au formatage qui sont:
  • showOderInfo() - qui affiche les informations a propos de la dernière commande
  • setLcdColor() - qui initialiser la couleur du LCD en fonction du transporteur.
Le corps du programme (cfr la partie vraiment intéressante) se trouve dans la fonction main().
C'est là qu'est instancié la classe d'accès à l'API PrestaShop (CachedPrestaHelper) et la classe d'accès au LCD (EuropeLcdMatrix).
Le restant du programme effectue des lectures régulières d'information sur le WebShop et rafraîchit le contenu du LCD.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
"""lcdordertrack.py
  
Copyright 2014 DMeurisse <info@mchobby.be>
  
Presta Shop Order Tracker - Version alpha

Track new incoming order on the WebShop and display the results
on a USB 16x2 LCD
 
Use a USB+TTL 16x2 RGB LCD available at MCHobby
  http://shop.mchobby.be/product.php?id_product=475 

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
  
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
  
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
"""  

from prestaapi.prestahelper import PrestaHelper, CachedPrestaHelper
from lcdmtrx.lcdmtrx import *
from config import Config
import logging
import time
import math

config = Config()
logging.basicConfig( filename=config.logfile, level=logging.DEBUG, 
 format='%(asctime)s - [%(levelname)s] %(message)s',
 datefmt='%d/%m/%y %H:%M:%S.%f' )

UPDATE_DELAY = 180 # seconds delay to reread the last order in the WebShop
cachedHelper = None
lcd = None

def showOrderInfo( lcd, cachedHelper, order_data ):
 """ Just display informations about the order """
 
 # Write Order ID
 sValid = 'VALID'
 if order_data.valid == 0:
  sValid = 'INVAL'
 sOrder = u'Order:%i %s' % (order_data.id, sValid)
 sOrder = sOrder[:16]
 sOrder.ljust( 16 )
 lcd.write_european_pos( 2, 1, sOrder )
 time.sleep( 2 )
 # Write Carrier 
 sCarrier = cachedHelper.carriers.name_from_id( order_data.id_carrier )
 sCarrier = (sCarrier[:16]).ljust( 16 )
 lcd.write_european_pos( 2, 1, sCarrier )
 time.sleep( 2 )
 # Write Status
 sOrderState = cachedHelper.order_states.name_from_id( order_data.current_state )
 sOrderState = (sOrderState[:16]).ljust( 16 )
 lcd.write_european_pos( 2, 1, sOrderState )
 time.sleep( 2 )
 # Write Type of Payment
 sPayment = order_data.payment
 sPayment = (sPayment[:16]).ljust( 16 )
 lcd.write_european_pos( 2, 1, sPayment )
 time.sleep( 2 )
 # Write Amount
 sAmount = (u'%.2f Eur' % order_data.total_paid)
 sAmount = (sAmount[:16]).rjust( 16 )
 lcd.write_european_pos( 2, 1, sAmount )
 time.sleep( 3 )
 
def setLcdColor( lcd, cachedHelper, order_data ):
 """ Set le LCD background color depending on order status """
 LcdColor = (255, 120, 120 ) # plutot blanc (Les LEDs vertes & bleues sont dominantes!) 
 # bOpenOrder = cachedHelper.order_states.is_open_order( order_data.current_state )
 bNewPayment = cachedHelper.order_states.is_new_order( order_data.current_state )
 if bNewPayment:
  sCarrier = cachedHelper.carriers.name_from_id( order_data.id_carrier )
  sCarrier = sCarrier.upper()
  # si Poste/Collisimo/UPS --> Urgent
  if sCarrier.find(u'UPS') >= 0:
   LcdColor = (255, 100, 0) # Jaune
  elif (sCarrier.find( u'BPACK' ) >= 0 ) or ( sCarrier.find( u'COLIS' ) >= 0 ):
   LcdColor = (230, 10, 10) # Rouge leger
  elif sCarrier.find( u'MONDIAL' ) >= 0:
   LcdColor = (20, 135, 20 ) # Vert léger
  else:
   LcdColor = (255, 120, 120 ) # plutot blanc
 
  lcd.color( LcdColor[0], LcdColor[1], LcdColor[2] )  
 
def main():
 cachedHelper = CachedPrestaHelper( config.presta_api_url, config.presta_api_key, debug = False )
 lcd = EuropeLcdMatrix( config.lcd_device )
 lcd.create_european_charset()
 
 lcd.clear_screen()
 lcd.autoscroll( False );
 lcd.activate_lcd( True );
 lcd.write_european_pos( 1, 1, u'LcdOrderTrack' )
 lcd.write_european_pos( 2, 1, u'     starting...' )
  
 # default values for variable
 last_order_id = -1
 last_order_data = None
 bNewPayment     = False
 paid_count  = 0
 bankwire_count  = 0
 
 try:
  # Force initial update
  last_update_time = time.time() - UPDATE_DELAY
  while True:
   if math.floor( time.time() - last_update_time ) >= UPDATE_DELAY:
    lcd.clear_screen()
    lcd.write_european( u'Updating...' )

    # Identifying the last Order!
    last_order_id = cachedHelper.get_lastorder_id()
    last_orders_data = cachedHelper.get_last_orders( last_order_id, count = 1 )
    # bOpenOrder = cachedHelper.order_states.is_open_order( last_orders_data[0].current_state )
    bNewPayment = cachedHelper.order_states.is_new_order( last_orders_data[0].current_state )
    
    # Activate LCD when receiving a new payment 
    setLcdColor( lcd, cachedHelper, last_orders_data[0] )
    lcd.activate_lcd( bNewPayment )
    paid_count = len( cachedHelper.get_order_ids( cachedHelper.order_states.ORDER_STATE_PAID ) )
    bankwire_count = len( cachedHelper.get_order_ids( cachedHelper.order_states.ORDER_STATE_WAIT_BANKWIRE ) )

    last_update_time = time.time()
   else: 
    sInfo = u'upd in %i sec' % int( UPDATE_DELAY - math.floor( time.time() - last_update_time ) )
    sInfo = (sInfo[:16]).ljust( 16 )
    lcd.write_european_pos( 2, 1, sInfo )
    time.sleep( 2 ) 
   
   # Show Count of payments
   sPayInfo = u'Pay %s | Vir %s' % (paid_count, bankwire_count)
   sPayInfo = sPayInfo.center( 16 )  
   lcd.write_european_pos( 1, 1, sPayInfo )
  
   # Show information about last Order
   showOrderInfo( lcd, cachedHelper, last_orders_data[0] )
   
 except Exception, e:
  lcd.clear_screen()
  lcd.write( 'KABOUM!!' )
  logging.exception( e )
 return 0

if __name__ == '__main__':
 logging.info( 'LcdOrderTrack Started' ) 
 main()
 logging.info( 'LcdOrderTrack End' ) 


Démarrer le script au boot
Ce n'est pas tout d'avoir un script qui fonctionne, il faudrait également qu'il démarre automatiquement au démarrage du Pi.
Sur une recommandation trouvée sur Raspberry-Pi.org j'ai utilisé upstart qu'il faut préalablement installer.

sudo apt-get install upstart

Il faut ensuite créer un fichier pour démarrer le service que nous appelleront lcdordertrack .
Il faut donc créer le fichier lcdordertrack.conf dans le répertoire /etc/init/

cd /etc/init/
sudo nano lcdordertrack.conf 

fichier dans lequel nous ajouterons les lignes suivantes pour démarrer automatiquement le script au démarrage du système:

# PrestaShop LCD Order tracking service

description     "PrestaShop LCD Order tracking service"
author          "MCHobby"

start on runlevel [2345]
stop on runlevel [016]
chdir /home/pi/PrestaConsole/
exec python /home/pi/PrestaConsole/lcdordertrack.py
respawn

Note: le respawm redémarre le service s'il est interrompu.
Après avoir dûment rebooter notre Raspberry-Pi (absolument essentiel), nous pouvons également démarrer et arrêter le service directement en ligne de commande:

sudo service lcdordertrack stop
sudo service lcdordertrack start

Ressources:
Dans le cadre de la modification du fichier /etc/rc.local, vous pourriez encoder les lignes cd et (python ....)&:

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
 

cd /home/pi/PrestaConsole
(python lcdordertrack.py)&

exit 0