【问题标题】:Pycharm: writing data from serial to Google sheets using gspread - not workingPycharm:使用 gspread 将数据从串行写入 Google 工作表 - 不工作
【发布时间】:2020-01-19 14:25:14
【问题描述】:

我有这个代码对其他人有用(他无法咨询)

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)

似乎一切正常,我什至在我的工作目录中获取了日志文件(包含应该写入的数据)。 谷歌表格文件仍然是空的,知道为什么吗? 在 gspread 可以实际写入电子表格/工作表之前的初始化过程到底是什么?

任何帮助将不胜感激! (:

【问题讨论】:

  • 虽然我不确定这是否是您想要的方向,例如,使用 gspread 的简单示例脚本测试将值放入 Google 电子表格如何?
  • 我也在这样做,但我认为可能只是我没有做的一个小修改,有人可以指出它。
  • 感谢您的回复。我不得不为我糟糕的英语水平道歉。我无法理解你的回复。我能问一下你目前的问题吗?
  • 我解决了当前的问题,但欢迎您提问,希望我能提供帮助(:一旦我注意到创建电子表格时,我的问题就解决了,自动创建了一个名为 sheet1 的工作表,然而我的代码正在为每个实验创建它自己的工作表。我只需低头查看谷歌工作表中的工作表选项卡即可找到实际使用正确数据更新的工作表!
  • 感谢您的回复。我很高兴你的问题得到了解决。当您的问题解决后,您可以将其发布为答案吗?这样,它对遇到相同问题的其他用户很有用。

标签: google-api pycharm google-sheets-api gspread


【解决方案1】:

所以一旦我注意到创建电子表格时,我的问题就解决了,自动创建了一个名为 sheet1 的工作表,但我的代码正在为每个实验创建它自己的工作表。我只需低头查看 google 表格中的工作表选项卡,即可找到实际使用正确数据更新的工作表!

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    相关资源
    最近更新 更多