Pycharm: запись данных с серийного номера на листы Google с использованием gspread - не работает - PullRequest
0 голосов
/ 19 января 2020

У меня есть этот код, который работал для кого-то другого (он недоступен ДЛЯ КОНСУЛЬТАЦИЙ)

import logging
import random
import time
import serial
import os
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime

__author__ = "Ofek Weinberger & Ziv Beker"
__copyright__ = "Copyright (C) 2020 Ofek Weinberger & Ziv Beker"
__license__ = "Public Domain"
__version__ = "1.0"

def init_connection(ser, last_experiment=None):
    """
    This function is used to initialize the connection with google's system.
    :param ser: The reference to the serial object we use to communicate with the ATMega328P
    :param last_experiment: If none - it is a normal experiment but else can be used to             continue a running experiment
    :return:
    """
    # Use credentials to create a client to interact with the Google Drive API
    scope = ['https://www.googleapis.com/auth/drive']
    creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
    client = gspread.authorize(creds)

    # Make sure you use the right name here
    spread_sheet = client.open("EXPERIMENTS")
    init_experiment(ser, spread_sheet, last_experiment=last_experiment)


def init_experiment(ser, spread_sheet, last_experiment=None):
    """
    This function is used to initialize the experiment: create a new worksheet for the         
 experiment and set it up.
    :param ser: The reference to the serial object we use to communicate with the ATMega328P
    :param spread_sheet: The spreadsheet of the experiment.
    :param last_experiment: If none - it is a normal experiment but else can be used to continue a running experiment
    :return:
    """
    experiment_time = datetime.now().strftime("%Y%m%d%H%M%S")
    print(spread_sheet.title + "@" + experiment_time)
    logging.log(100, spread_sheet.title + "@" + experiment_time)

    # create new worksheet
    if last_experiment is None:
        worksheet = spread_sheet.add_worksheet(title="experiment@" + experiment_time+'END',     rows=10000, cols=10)
    else:
        worksheet = spread_sheet.worksheet(last_experiment[0])
    # add titles
    worksheet.update_acell('A1', 't')
    worksheet.update_acell('B1', 'T_in')
    worksheet.update_acell('C1', 'T_out')
    worksheet.update_acell('D1', 'T_aux')
    worksheet.update_acell('E1', 'RH_in')
    worksheet.update_acell('F1', 'RH_out')
    worksheet.update_acell('G1', 'RH_aux')
    worksheet.update_acell('I1', 'WaterLevel')

    print("t, T_in, T_out, T_aux, RH_in, RH_out, RH_aux,WaterLevel")
    logging.log(100, "t, T_in, T_out, T_aux, RH_in, RH_out, RH_aux,WaterLevel")

    # start experiment loop
    if last_experiment is None:
        start_experiment(ser, worksheet=worksheet)
    else:
        start_experiment(ser, worksheet=worksheet, worksheet_row=last_experiment[1])


def start_experiment(ser, worksheet, worksheet_row=2):
    """
    The experiment loop, measure the sensors and update the sheet.
    :param ser: The reference to the serial object we use to communicate with the ATMega328P
    :param worksheet: The specific sheet we edit
    :param worksheet_row: The row we're writing at
    :return:
    """
    print(worksheet_row)
    while True:
        try:
            # get measurements and cell range:
            measurements = get_measurements(ser)
            print("vals=" + str(measurements))
            logging.log(100, "vals=" + str(measurements))
            cell_list = worksheet.range('A' + str(worksheet_row) + ':H' + str(worksheet_row))

            # update in sheets
            for i in range(len(measurements)):
                cell_list[i].value = measurements[i]
            worksheet.update_cells(cell_list, 'USER_ENTERED')

        except Exception as e:
            print(e)
            logging.log(100, e)
            time.sleep(100)
            init_connection(ser, last_experiment=(worksheet.title, worksheet_row))
        # next row and wait for some time
        worksheet_row += 1
        time.sleep(30)


def get_measurements(ser):
    """
    This function measures the sensors of the experiment
    :param ser: The reference to the serial object we use to communicate with the ATMega328P
    :return: Array of the measurement according to this order: t, T_in, T_out, T_aux, RH_in,         RH_out, RH_aux, Flux,WaterLevel
    """
    t = datetime.now().strftime('%d/%m/%Y %H:%M:%S')

    # Here we read the data from the sensors
    T_in = random.randint(1, 3)
    T_out = random.randint(1, 10) + 15
    T_aux = random.randint(1, 3) - 5
    RH_in = random.randint(1, 5) + 55
    RH_out = random.randint(1, 5) + 40
    RH_aux = random.randint(1, 5) + 50
    WaterLevel = random.randint(1, 10) + 300
    data = [ser.read()]
    if data[0] != b'':
        newByte = ser.read()
        while newByte != b'':
            data.append(newByte)
            newByte = ser.read()
        data = b''.join(data)
        data = data.decode("utf-8")
        print('data_read=' + str(data))
        data = data.split('\n')
        list_of_parameters = ['t=', 'Ti=', 'RHi=', 'To=', 'RHo=', 'Ta=', 'RHa=','WaterLevel='] #need to be exactly the same as written in the arduino serial monitor
        for line in data:
          if any(x not in line for x in list_of_parameters):
            data.remove(line)

        data = data[len(data) - 1]        

        print('data=' + str(data))
        data = data.split(' ')
        uptime = (data[0])[data[0].index('=') + 1:]
        T_in = (data[1])[data[1].index('=') + 1:]
        RH_in = (data[2])[data[2].index('=') + 1:]
        T_out = (data[3])[data[3].index('=') + 1:]
        RH_out = (data[4])[data[4].index('=') + 1:]
        T_aux = (data[5])[data[5].index('=') + 1:]
        RH_aux = (data[6])[data[6].index('=') + 1:]
        WaterLevel = (data[7])[data[7].index('=') + 1:]
    return t, T_in, T_out, T_aux, RH_in, RH_out, RH_aux,WaterLevel


if __name__ == '__main__':
    logging.basicConfig(filename='logs/experiment@' +         datetime.now().strftime("%Y%m%d%H%M%S") +'END'+ '.log', filemode='w',
                        level=100, format="")
    print('Initializing program')
    logging.log(100, 'Initializing program')

    ser = serial.Serial('/dev/ttyUSB1', 115200, timeout=0.1)
    time.sleep(1)
    print('Serial connection is okay')
    logging.log(100, 'Serial connection is okay')

    init_connection(ser)

Кажется, что все работает нормально, я даже получаю файлы журнала (с данными, которые должно быть написано) в моем рабочем каталоге. Файл листов Google остается пустым, есть идеи, почему? Каков именно процесс инициализации до того, как приложение может действительно написать внутри электронной таблицы / рабочего листа?

Любая помощь будет оценена! (

1 Ответ

0 голосов
/ 21 января 2020

поэтому моя проблема была решена, как только я заметил, что при создании электронной таблицы автоматически создается лист с именем sheet1, но мой код создает свой собственный лист для каждого эксперимента. Мне просто пришлось посмотреть на вкладки листа в листах Google, чтобы найти лист, который на самом деле обновляется с правильными данными!

...