【搬运】扫描条码添加购物清单-Arduino中文社区 - Powered by Discuz! Archiver

vany5921 发表于 2020-6-8 11:52

【搬运】扫描条码添加购物清单

本帖最后由 vany5921 于 2020-6-8 11:53 编辑

这个项目旨在创建一个小工具,读取我想添加到我的购物清单中的产品条码

这个小工具是用M5StickC+一个带串行端口条形码阅读器+一个带3D打印机的盒子来集成它们的。我是利用了Bring!与树莓派的HomeAssistant进行通讯,条码通过MQTT发送到MQTT服务器,通过HomeAssistant中运行的python脚本进行接收,此程序在excel工作表中查找条形码,您可以在其中找到所有产品的列表。一旦产品被识别,它就被送到了Bring!应用程序通过一个非官方的API和MQTT返回产品名并显示在条形码阅读器屏幕上。
Vcc <------> 3V3,GND <------> GND,TX <------> G36,Trigger <-------> G26这个盒子是用Tinkercad设计的,是测试版。目前它不是理想的盒子,但测试它就足够了。底座包含一个带有磁铁的连接器,因此您可以快速连接和断开充电器。M5StickC程序:按下A按钮后,扫码器的捕获触发引脚激活,并等待通过串行端口接收数据的最长时间为10秒。当通过串行端口接收到信息时,条形码被发送到MQTT服务器,如果从MQTT服务器接收到产品名,它将显示在屏幕上。连接充电器时,检查输入电压,显示器将关闭,以免损坏显示器。//
// Lector codigo barras para M5Stack Stick-C
//
// Mayo-2020
//
// daekka LNX
#include <M5StickC.h>
#include <WiFi.h>
#include <;PubSubClient.h>

//WiFi credentials
char* ssid       = "xxxxxx";
char* password   = "xxxxxx";
const char* mqtt_server = "192.168.1.200";
const char* mqttUser = "xxxxxx";
const char* mqttPassword = "xxxxxx";
WiFiClient espClient;
PubSubClient client(espClient);

// LED
#define ledPin 10
// Pin trigger lector
#define triggerPin 26

bool usb_power = false;
unsigned long previus_millis_captura = millis();
const int timeThreshold_captura = 10000;
String codigo_leido="";


// the setup routine runs once when M5StickC starts up
void setup() {

// initialize the M5StickC object
M5.begin();

// Trigger del lector
pinMode (triggerPin, OUTPUT);
digitalWrite (triggerPin, HIGH);

// LED
pinMode (ledPin, OUTPUT);
digitalWrite (ledPin, HIGH);// turn off the LED

// Puerto serie
Serial2.begin(9600,SERIAL_8N1,36,0);

// Activa el wifi y MQTT
activa_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);

// Ajusto el brillo
//M5.Lcd.setBrightness(80);

// Rota la pantalla
M5.Lcd.setRotation(3);
M5.Axp.ScreenBreath(10);
// Lcd display
M5.Lcd.fillScreen(WHITE);
delay(500);
M5.Lcd.fillScreen(RED);
delay(500);
M5.Lcd.fillScreen(GREEN);
delay(500);
M5.Lcd.fillScreen(BLUE);
delay(500);
M5.Lcd.fillScreen(BLACK);
delay(500);

if (M5.Axp.GetVBusVoltage() > 4) {
    usb_power = false;
}
else {
    usb_power = true;
}

}

void activa_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
}
}

void callback(char* topic, byte* message, unsigned int length) {
String messageTemp;

if (String(topic) == "lector_codigo_barras/in") {
      for (int i = 0; i < length; i++) {
      messageTemp += (char)message;
      }
      for (int i = 0; i < 10; i++) {
      messageTemp += " ";
      }
      display_producto (messageTemp);
}
}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
    // Attempt to connect
    if (client.connect("M5stickC-Codigo_barras")) {
      // Subscribe
      client.subscribe("lector_codigo_barras/in");
    } else {
      delay(1000);
    }
}
}

void display_titulo (String titulo) {
M5.Lcd.setTextColor(WHITE,BLACK);
M5.Lcd.drawString(titulo + "            ", 11, 8, 1);

}
void display_producto (String producto){
M5.Lcd.setTextColor(GREEN,BLACK);
M5.Lcd.drawString(producto + "         ", 10, 30, 4);
}

void display_codigo_barras (String codigo) {
M5.Lcd.setTextColor(RED,BLACK);
M5.Lcd.drawString(codigo + "         ", 10, 60, 2);
}

void enciende_pantalla (){
M5.Lcd.writecommand(ST7735_DISPON);
M5.Axp.ScreenBreath(10);
M5.Lcd.fillScreen(BLACK);
display_titulo ("LECTOR CODIGO BARRAS");
display_producto ("Producto.....");
display_codigo_barras ("Esperando.....");
}

void apaga_pantalla (){
M5.Lcd.writecommand(ST7735_DISPOFF);
M5.Axp.ScreenBreath(0);
}

void comprobacion_usb_conectado() {
// Apaga la pantalla
if ((M5.Axp.GetVBusVoltage() > 4) && (usb_power == false) ){
      usb_power = true;
      apaga_pantalla();
}
if ((M5.Axp.GetVBusVoltage() <= 4) && (usb_power == true) ){
      usb_power = false;
      enciende_pantalla();
}
}

void captura_codigo () {

   digitalWrite (ledPin, LOW);// turn on the LED
   digitalWrite (triggerPin, LOW); // Activa lector
   previus_millis_captura = millis();
   while (Serial2.available() == 0 && (millis()-previus_millis_captura<timeThreshold_captura)) {
      delay (10);
   }

   if (millis()-previus_millis_captura<timeThreshold_captura) {
      M5.Lcd.fillScreen(GREEN);
      delay (100);
      codigo_leido = Serial2.readString();
      M5.Lcd.fillScreen(BLACK);
      M5.Axp.ScreenBreath(10);
      display_titulo ("LECTOR CODIGO BARRAS");
      int str_len = codigo_leido.length()-1;
      char char_array;
      codigo_leido.toCharArray(char_array, str_len);
      client.publish("lector_codigo_barras/out", char_array);
      display_codigo_barras (codigo_leido);
   }
   else {
      display_codigo_barras ("TIME OUT.....");
   }
   digitalWrite (triggerPin, HIGH); // Apaga lector
   digitalWrite (ledPin, HIGH);// turn on the LED
}


// the loop routine runs over and over again forever
void loop(){

if (!client.connected()) {
    reconnect();
}
client.loop();

// Comprueba si esta el USB cargador conectado y apaga o enciende la pantalla
comprobacion_usb_conectado();
// Actualiza estado botones
M5.update();
if (M5.BtnA.wasPressed()) {
      captura_codigo();
}

}
HomeAssistant设置要实现的集成:
- MQTT传感器:从扫码器接收条形码
- Shell命令:执行Python代码
- Automation:在MQTT传感器接收到数据后启动Python代码。
############################################################
#
# Home Assistant - Lector codigo de barras
#
############################################################

sensor:
- platform: mqtt
    name: lector_codigo_barras
    state_topic: "lector_codigo_barras/out"
    expire_after: 2
   
shell_command:
    insert_producto_lector_codigo_barras: '/usr/bin/python /home/homeassistant/.homeassistant/python/bring/insert_producto_lector_codigo_barras.py "{{ producto }}"'
         
automation:
- alias: recibido_codigo_barras
    initial_state: true
    trigger:
      - platform: state
      entity_id: sensor.lector_codigo_barras
    action:
      - service: shell_command.insert_producto_lector_codigo_barras
      data_template:
            producto: '{{ states.sensor.lector_codigo_barras.state }}'
python脚本

python代码要实现的工作
- 搜索接收到的条码(系统参数 )在存储产品的excel表中
- 通过MQTT发送产品的名称
- 将产品添加到Bring!使用非官方BringApi库的应用程序
#!/usr/bin/env python
# coding: utf8

# Find barcodes from excel sheet
# daekka LNX

import requests
import json
import sys
import os
import xlrd
from collections import OrderedDict
import bringapi
import time

# Open the workbook and select the worksheet (first=0)
path_excel_productos = '/home/homeassistant/.homeassistant/python/bring'
file_name_excel_productos = 'barcode_productos.xlsx'
wb = xlrd.open_workbook(os.path.join(path_excel_productos, file_name_excel_productos))
sh = wb.sheet_by_index(0)

#Iterate through each row in worksheet and fetch values into dict
for rownum in range(1, sh.nrows):
    row_values = sh.row_values(rownum)
    if row_values == sys.argv:
       producto = OrderedDict()   
       producto['id_aleman'] = row_values
       producto['id_traduccion'] = row_values
       #producto['id_categoria'] = row_values
       #producto['id_codigo'] = row_values
      
       #MQTT
       os.system ('mosquitto_pub -h 192.168.1.200 -m "' + producto['id_traduccion'] +'" -t lector_codigo_barras/in')

       #BRING!
       bring = bringapi.BringApi("user","password",True)
       bring.purchase_item(producto['id_aleman'],"")

       #Finaliza buble
       break

excel工作表有4列:
应用程序中产品的原始名称。这是要在API BRING中使用的名称,这样就不会创建新产品。如果你用的名字不在BRING!中将创建产品,您必须修改应用程序中的类别和图标。
翻译成我的想显示的名称。这是我在M5Stick屏幕中显示的名称。
产品所属的类别(未使用)
在扫描条形码时当同一产品有多个品牌时,必须用同一行复制数据。








页: [1]
查看完整版本: 【搬运】扫描条码添加购物清单