PinoroEnviro + TypeError:参数应为整数或类似字节的对象,而不是“ str”

时间:2019-08-10 23:22:42

标签: python python-3.x typeerror

我一直在尝试理解运行我购买的某些硬件随附的示例时报告的错误。

我已经尝试过使用Google搜索,但是我得到的每个答案都超出了我的理解范围。我认为出了问题是该脚本或一个导入的脚本是为Python 2编写的,而我试图在python 3中运行它。 当我尝试在Python 2中运行它时,我遇到了很多其他问题,因此我一直在尝试使其与3兼容。

我购买的硬件是Pimoroni出售的用于树莓派的Enviro +传感器套件

Hardware Link

Github Library

Pimoroni Tutorial

#!/usr/bin/env python

import time
import colorsys
import os
import sys
import ST7735
import ltr559

from bme280 import BME280
from pms5003 import PMS5003
from enviroplus import gas
from subprocess import PIPE, Popen
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

print("""all-in-one.py - Displays readings from all of Enviro plus' sensors

Press Ctrl+C to exit!

""")

# BME280 temperature/pressure/humidity sensor
bme280 = BME280()

# PMS5003 particulate sensor
pms5003 = PMS5003()

# Create ST7735 LCD display class
st7735 = ST7735.ST7735(
    port=0,
    cs=1,
    dc=9,
    backlight=12,
    rotation=270,
    spi_speed_hz=10000000
)

# Initialize display
st7735.begin()

WIDTH = st7735.width
HEIGHT = st7735.height

# Set up canvas and font
img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
draw = ImageDraw.Draw(img)
path = os.path.dirname(os.path.realpath(__file__))
font = ImageFont.truetype(path + "/fonts/Asap/Asap-Bold.ttf", 20)

message = ""

# The position of the top bar
top_pos = 25


# Displays data and text on the 0.96" LCD
def display_text(variable, data, unit):
    # Maintain length of list
    values[variable] = values[variable][1:] + [data]
    # Scale the values for the variable between 0 and 1
    colours = [(v - min(values[variable]) + 1) / (max(values[variable])
               - min(values[variable]) + 1) for v in values[variable]]
    # Format the variable name and value
    message = "{}: {:.1f} {}".format(variable[:4], data, unit)
    print(message)
    draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
    for i in range(len(colours)):
        # Convert the values to colours from red to blue
        colour = (1.0 - colours[i]) * 0.6
        r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour,
                   1.0, 1.0)]
        # Draw a 1-pixel wide rectangle of colour
        draw.rectangle((i, top_pos, i+1, HEIGHT), (r, g, b))
        # Draw a line graph in black
        line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos)))\
                 + top_pos
        draw.rectangle((i, line_y, i+1, line_y+1), (0, 0, 0))
    # Write the text at the top in black
    draw.text((0, 0), message, font=font, fill=(0, 0, 0))
    st7735.display(img)


# Get the temperature of the CPU for compensation
def get_cpu_temperature():
    process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE)
    output, _error = process.communicate()
    return float(output[output.index('=') + 1:output.rindex("'")])


# Tuning factor for compensation. Decrease this number to adjust the
# temperature down, and increase to adjust up
factor = 0.8

cpu_temps = [0] * 5

delay = 0.5  # Debounce the proximity tap
mode = 0  # The starting mode
last_page = 0
light = 1

# Create a values dict to store the data
variables = ["temperature",
             "pressure",
             "humidity",
             "light",
             "oxidised",
             "reduced",
             "nh3",
             "pm1",
             "pm25",
             "pm10"]

values = {}

for v in variables:
    values[v] = [1] * WIDTH

# The main loop
try:
    while True:
        proximity = ltr559.get_proximity()

        # If the proximity crosses the threshold, toggle the mode
        if proximity > 1500 and time.time() - last_page > delay:
            mode += 1
            mode %= len(variables)
            last_page = time.time()

        # One mode for each variable
        if mode == 0:
            variable = "temperature"
            unit = "C"
            cpu_temp = get_cpu_temperature()
            # Smooth out with some averaging to decrease jitter
            cpu_temps = cpu_temps[1:] + [cpu_temp]
            avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
            raw_temp = bme280.get_temperature()
            data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
            display_text(variable, data, unit)

        if mode == 1:
            variable = "pressure"
            unit = "hPa"
            data = bme280.get_pressure()
            display_text(variable, data, unit)

        if mode == 2:
            variable = "humidity"
            unit = "%"
            data = bme280.get_humidity()
            display_text(variable, data, unit)

        if mode == 3:
            variable = "light"
            unit = "Lux"
            if proximity < 10:
                data = ltr559.get_lux()
            else:
                data = 1
            display_text(variable, data, unit)

        if mode == 4:
            variable = "oxidised"
            unit = "kO"
            data = gas.read_all()
            data = data.oxidising / 1000
            display_text(variable, data, unit)

        if mode == 5:
            variable = "reduced"
            unit = "kO"
            data = gas.read_all()
            data = data.reducing / 1000
            display_text(variable, data, unit)

        if mode == 6:
            variable = "nh3"
            unit = "kO"
            data = gas.read_all()
            data = data.nh3 / 1000
            display_text(variable, data, unit)

        if mode == 7:
            variable = "pm1"
            unit = "ug/m3"
            data = pms5003.read()
            data = data.pm_ug_per_m3(1.0)
            display_text(variable, data, unit)

        if mode == 8:
            variable = "pm25"
            unit = "ug/m3"
            data = pms5003.read()
            data = data.pm_ug_per_m3(2.5)
            display_text(variable, data, unit)

        if mode == 9:
            variable = "pm10"
            unit = "ug/m3"
            data = pms5003.read()
            data = data.pm_ug_per_m3(10)
            display_text(variable, data, unit)

# Exit cleanly
except KeyboardInterrupt:
    sys.exit(0)

当我尝试运行代码时,我得到以下结果:

Traceback (most recent call last):
  File "all-in-one.py", line 135, in <module>
    cpu_temp = get_cpu_temperature()
  File "all-in-one.py", line 89, in get_cpu_temperature
    return float(output[output.index('=') + 1:output.rindex("'")])
TypeError: argument should be integer or bytes-like object, not 'str'

如果我没有正确填写此帮助请求,请原谅我-我是论坛的新手(虽然我经常阅读它们以寻求帮助,但我几乎从未在论坛中发帖),并且我对Python和Linux。

感谢社区的任何帮助和支持-预先感谢您...

SW

1 个答案:

答案 0 :(得分:0)

根据Python 3 whitepages on subprocess.communicate()output_error的类型可以是字符串(任意) OR 字节。如果返回字符串,就不会有此问题,但是,您尝试收到的TypeError对象是index()对象上的bytes消息带有字符串参数。

明显地:

>>> output = "temperature = '88 C'".encode('utf-8') #this is of type bytes
>>> output
b"temperature = '88 C'"
>>> output.index('=')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument should be integer or bytes-like object, not 'str'
>>> output.index(ord('='))
12

因此,您应将output.index('=')替换为output.index(ord('=')),将output.rindex("'")替换为output.rindex(ord("'"))

编辑

我很晚才意识到这一点,但是您可以使用ord()来绕过b

output.index(b'=')