Esempio n. 1
0
def uploadData():
    client.loop()
    print(temp.name())
    # Read the temperature ten times, printing both the Celsius and
    # equivalent Fahrenheit temperature, waiting one second between readings
    #for i in range(0, 10):
    celsius = temp.value()
    fahrenheit = celsius * 9.0 / 5.0 + 32.0
    print("%d degrees Celsius, or %d degrees Fahrenheit" \
        % (celsius, fahrenheit))
    time.sleep(1)

    # Read values of the light sensor
    lightLux = light.value()
    print(light.name() + " raw value is %d" % light.raw_value() + \
        ", which is roughly %d" % light.value() + " lux")
    time.sleep(1)

    # Wait for Ait quality sensor to warm up - it takes about 3 minutes
    print("Sensor is warming up for 3 minutes...")
    for i in range(1, 4):
        time.sleep(60)
        print(i, "minute(s) passed.")
    print("Sensor is ready!")
    # Read values of Air quality sensor
    airValue = airSensor.getSample()
    ppm = airSensor.getPPM()
    print("raw: %4d" % airValue, " ppm: %5.2f   " % ppm, airQuality(airValue))

    #Uploading data to Cayenne
    print("Uploading data to Cayenne ...")
    client.celsiusWrite(1, celsius)
    client.luxWrite(2, lightLux)
    client.virtualWrite(3, airValue)
Esempio n. 2
0
def main():
    print datetime.datetime.now()
    #Canadians do Celcius
    print ctrl.set_unit('f')

    i = 0
    timestamp = 0

    while True:
        #Cayenne kick
        client.loop()

        #Call every 10 seconds
        if (time.time() > timestamp + 10):

            #send the current temperature
            client.celsiusWrite(1, ctrl.read_temp())

            #send the set temperature
            client.celsiusWrite(3, ctrl.send_command_async("read set temp"))

            #send the run status
            if (ctrl.anova_status() == 'stopped'): a_stat = 0
            else: a_stat = 1
            client.virtualWrite(2, a_stat)

            #save last timestamp
            timestamp = time.time()
Esempio n. 3
0
def main():
    try:
        while True:
            client.loop()
            global timestamp
            if (time.time() > timestamp + 10):
                client.windspeedWrite(1, wind_km_float)
                timestamp = time.time()
    except KeyboardInterrupt:
        GPIO.cleanup(23)  # clean up GPIO on CTRL+C exit
    GPIO.cleanup()
Esempio n. 4
0
def on_message(message):
  print("Message received: " + str(message))
  #print("channel %s, topic %s, value %s" % (message.channel, message.topic, message.value))

  # If there is an error processing the message return an error string, otherwise return nothing.
  #if (True):
  if (message["channel"]=="4") & (message["topic"]=="cmd"):
    light_state = message.value
    print("Set light to %s" % (message.value))
    light.put_value(light_state)
    client.virtualWrite(4, light_state, dataType="digital_actuator", dataUnit="d")
    client.responseWrite(message.msg_id)
    client.loop()
Esempio n. 5
0
def dht():
    print("\nInitializing DHT sensor...\n")
    time.sleep(2)
    while True:
        client.loop()
        
        humidity, temperature=Adafruit_DHT.read_retry(11,17)
        if humidity is not None and temperature is not None:
            client.celsiusWrite(1, temperature)
            client.luxWrite(2, humidity)
            print('Temp:{0:0.1f}*C Humidity: {1:0.1f}%'.format(temperature,humidity))
            time.sleep(2)
        else:
            print("\nFailed to get reading...\n")
Esempio n. 6
0
def main():

    # Cayenne authentication info
    MQTT_USERNAME = "******"
    MQTT_PASSWORD = "******"
    MQTT_CLIENT_ID = "cd803190-47fd-11ea-84bb-8f71124cfdfb"

    client = cayenne.client.CayenneMQTTClient()

    client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

    # Initialise all variables
    starttime = time.time()
    temp, hum, nh3, no2, light, proxim, pressure, curTime = output()
    oldTemp, oldHum, oldNh3, oldNo2, oldLight, oldProxim, oldPressure = temp, hum, nh3, no2, light, proxim, pressure

    while True:
        # Send values to Cayenne
        client.loop()

        client.celsiusWrite(1, temp)
        client.virtualWrite(2, hum)
        client.virtualWrite(3, no2)
        client.virtualWrite(4, nh3)
        client.luxWrite(5, light)
        # client.virtualWrite(6, proxim)

        # Filter inaccurate pressure readings
        if (pressure < 700):
            client.virtualWrite(7, oldPressure)
        else:
            client.virtualWrite(7, pressure)
            oldPressure = pressure

        save()

        # Calculate how long the program has been running for
        timeDiff = time.localtime(time.time() - starttime - 3600)
        runTime = time.strftime("%H:%M", timeDiff)

        display(light, curTime, runTime)

        # Have the program send values once every minute
        time.sleep(60.0 - ((time.time() - starttime) % 60.0))

        # Update values
        oldTemp, oldHum, oldNh3, oldNo2, oldLight, oldProxim = temp, hum, nh3, no2, light, proxim
        temp, hum, nh3, no2, light, proxim, pressure, curTime = output()
Esempio n. 7
0
#!/usr/bin/env python
import cayenne.client
import time
import logging

# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = "******"
MQTT_PASSWORD  = "******"
MQTT_CLIENT_ID = "CAYENNE_CLIENT_ID"


client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO)
# For a secure connection use port 8883 when calling client.begin:
# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)

i=0
timestamp = 0

while True:
    client.loop()
    
    if (time.time() > timestamp + 10):
        client.celsiusWrite(1, i)
        client.luxWrite(2, i*10)
        client.hectoPascalWrite(3, i+800)
        timestamp = time.time()
        i = i+1
Esempio n. 8
0
def produceData():
    global current
    global client
    global light

    # email configuration
    sender_email = "Your Fridge <*****@*****.**>"
    receiver_email = "*****@*****.**"

    # threshold temp in C
    EMAIL_FRIDGE_THRESH = 7 
    EMAIL_FREEZER_THRESH = -10
    # time in seconds that threshold must be exceeded
    EMAIL_THRESHOLD_TIME = 1200
    # min alert email interval in seconds
    EMAIL_ALERT_INTERVAL = 86400 


    # informative message template
    text = """\
From: {}
To: {}
Subject: HIGH TEMPERATURE ALERT

Hi,

On {}, the fridge was {} deg C and the freezer was {} deg C.

Click http://10.0.0.8:8080/view?scale=day for more information.

"""
    """
    thread to aquire samples continuously
    """
    
    #file = open("/var/1w_files/log.csv", "a")

    # bootstrap timers (take/send readings immediately on start)
    timestamp = time.time() - 5
    cayenne_timestamp = time.time() - 280

    # create sensor/control objects, GPIO and 1wire
    light = gpio_sensor.Gpio("gpio27")
    switch = gpio_sensor.Gpio("gpio22")
    ambient = temp_sensor.TempSensor("28-0000052f7386")
    freezer = temp_sensor.TempSensor("28-0000055fc26e")
    fridge = temp_sensor.TempSensor("28-0000052f91b1")

    # timers for alarm threshold & alert rate limiting
    threshold_timestamp = time.time()
    last_alert_timestamp = 0  # send alert immediately after threshold time

    while(True):

      if (time.time()-timestamp) > 5.0 :
        timestamp = time.time()
        # grab temperature data. skip sensor in case of error
        try:
            ambient_temp = ambient.get_temperature()
        except Exception:
            pass

        try:
            freezer_temp = freezer.get_temperature()
        except Exception:
            pass

        try:
            # fridge thermometer has offset
            #fridge_temp = fridge.get_temperature() - 3.333
            # fridge temp offset dhanged 12/25/2019
            fridge_temp = fridge.get_temperature() + 2.000
        except Exception:
            pass

        light_state = light.get_value()
        switch_state = switch.get_value()

        # light control logic
        FDefrost = freezer_temp >= -6.0  # defrost mode in freezer
        FHigh = (freezer_temp < -6.0) & (freezer_temp > -15.0)  # "high"
        FLow = freezer_temp <= -15.0   # freezer temp is "low"

        RHigh = fridge_temp > 8.0          # fridge temp is "high"
        RBand = (fridge_temp <= 8.0) & (fridge_temp >= 1.5)  # "band"
        RLow = fridge_temp < 1.5          # fridge temp is "low"

        Door = switch_state == 1

        control = (FHigh & RBand) | RLow | Door
        light_state = to_int(control)
        light.put_value(light_state)

        current = {
          "time": timestamp,
          "ambient": ambient_temp,
          "freezer": freezer_temp,
          "fridge": fridge_temp,
          "light": light_state,
          "switch": switch_state,
        }

        print("Producer: "), 
        print(current)

        #update rrdtool database.  rrdtool is used for webpage graphics
        rrdtool.update("/var/1w_files/templog.rrd", \
                 "%d:%s:%s:%s:%s:%s" % (timestamp,  \
                                     ambient_temp,  \
                                     freezer_temp,  \
                                     fridge_temp,   \
                                     light_state,   \
                                     switch_state))

        # update element in queue for socketserver
        try:
          q.get(False)  # empty the old queue element
        except Exception:
          pass          # queue was empty already

        q.put(current, False)  # insert new element

        # log all data to file
        #foo = ("%d,%s,%s,%s,%s\n") % ( current["time"], current["freezer"], current["fridge"], current["ambient"], current["light"] )
        #file.write(foo)
        #file.flush()

        # update cayenne about every 5 minutes
        if ((time.time() - cayenne_timestamp) > 300):
          print("Publish to cayenne")
          cayenne_timestamp = time.time()
          client.celsiusWrite(1, ambient_temp)
          client.celsiusWrite(2, freezer_temp)
          client.celsiusWrite(3, fridge_temp)
          client.virtualWrite(4, light_state, dataType="digital_actuator", dataUnit="d")
          client.loop()

        # check for alarm condition and possibly send email
        if ( (freezer_temp < EMAIL_FREEZER_THRESH) and (fridge_temp < EMAIL_FRIDGE_THRESH) ):
          # everything normal, reset threshold exceeded time to current time
          threshold_timestamp = time.time()

        else:
          # we have a problem, maybe send email
          if (( (time.time() - threshold_timestamp) > EMAIL_THRESHOLD_TIME) and (( time.time() - last_alert_timestamp) > EMAIL_ALERT_INTERVAL) ):
            # send email, threshold exceeded and alert interval exceeded
            print("Send alert email now!");
            proc = Popen(['/usr/sbin/sendmail','-t','-oi'], stdin=PIPE)
            print(text.format(sender_email,receiver_email,time.strftime("%c"),fridge_temp,(fridge_temp*C_TO_F+32),freezer_temp,(freezer_temp*C_TO_F+32)).encode('utf8'))
            proc.communicate(text.format(sender_email,receiver_email,time.strftime("%c"),fridge_temp,freezer_temp).encode('utf8'))
            proc.wait()
            # we sent an alert, so reset rate-limiting timer 
            last_alert_timestamp = time.time()

# end of while(True)



      else:
        # check for cayenne publish or commands
        client.loop()
        time.sleep(0.1)
import cayenne.client
import time

# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = "******"
MQTT_PASSWORD  = "******"
MQTT_CLIENT_ID = "MQTT_CLIENT_ID"


# The callback for when a message is received from Cayenne.
def on_message(message):
    print("message received: " + str(message))
    # If there is an error processing the message return an error string, otherwise return nothing.
    
client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

i=0
timestamp = 0

while True:
    client.loop()
    
    if (time.time() > timestamp + 10):
        client.celsiusWrite(1, i)
        client.luxWrite(2, i*10)
        client.hectoPascalWrite(3, i+800)
        timestamp = time.time()
        i = i+1
Esempio n. 10
0
def main():
  
  global n1pointer, n1temps, n2pointer, n2temps, n3pointer, n3temps, n4pointer, n4temps
  n1pointer = 0
  n2pointer = 0
  n3pointer = 0
  n4pointer = 0
  n1temps = []
  n2temps = []
  n3temps = []
  n4temps = []

  # garbage collection to reduce memory leaks added July 2, 2014
  # gc is set to run every 21600 seconds (6 hours)
  
  #def foo():
  #  gc.collect()
  #  threading.Timer(21600, foo).start()
    
  
  def runningAverage(node, temperature, pointer, temps):
      #print "RunningAverage function; pointer = %d" % pointer
      total = 0
      # initially build-up the list of temperatures
      if len(temps) < 4:
        temps.extend([temperature])
        
        for j in range(0, (pointer + 1)):
          addend = float(temps[j])
          total = float(addend + total)
          avgx = total / (pointer + 1)
      # the list of temperatures is full, now replace the oldest one
      # with a new one
      else:
        temps[pointer] = temperature
        for j in range(0, 4):
          addend = float(temps[j])
          total = float(addend + total)
          avgx = total / 4
        
      average = round(avgx, 2)
      
      # increment  or reset pointer
      if pointer < 3:
        pointer += 1
      else:
        pointer = 0

      return (node, average, pointer, temps)
    

  def calcTemp():                    # routine to calculate single temperature units
    
    unkn = rawx.pop(0).strip()       # don't know what this is, drop for now
    place = nodeList[int(node)]      # substitute node for actual place in house

    wholeTemp = rawx.pop(0).strip()  # whole number part of temperature
    fracTemp = rawx.pop(0).strip()   # decimal part of temperature
    temperature = wholeTemp + "." + fracTemp
    
    return temperature               # pass this on!

  
  nodeList = 'Office', 'Garage', 'MBL_Room', 'In-law_Suite', 'Pantry', 'Kitchen'

  # CPU monitor routine, requires "import os"
  def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    return(res.replace("temp=","").replace("'C\n",""))

  cpuTemp = int(float(getCPUtemperature()))
  
  
  # COSM variables. 
#  f = open('apikey.txt', 'r') 
#  API_KEY = f.read()
#  f.close() 
#  API_KEY = 'suinLKP1uD3GCkuUN-xBmvZzSzWSAKxEcnQrdUJyTHJRND0g'
#  FEED = 129833
   
#  API_URL = '/v2/feeds/{feednum}.xml' .format(feednum = FEED)

  ser = serial.Serial('/dev/ttyUSB0', 57600)
  # ser.close()

  while True:
    client.loop()
          
    x = ser.readline()

    OKtest = re.match ( 'OK', x )         # match tests for match at beginning of string,
                                          # otherwise use search

    if OKtest:
      #pac = eeml.datastream.Cosm(API_URL, API_KEY)

      #print "Raw data received: " + x
      rawx = x.split()                    # split on whitespace

      ######################              # initial parsing
      ack = rawx.pop(0).strip()           # "OK": do nothing with it
      node = rawx.pop(0).strip()          # Node number
      
    
      if node == '1':
        
        tempLow = rawx.pop(0).strip()           # temperature low byte
        tempHigh = rawx.pop(0).strip()          # temperature high byte
        if int(tempHigh) < 5:			# if this byte is greater than 5, 
        				# temp is (for sure) a positive value
          tempRaw = (int(tempHigh) * 256) + int(tempLow)
        else:
          tempRaw = (255 ^ (int(tempLow))) * -1	# temp is negative value, so do a 1's complement
        tempRaw2 = tempRaw + 0.0
        actualTemp = tempRaw2 / 10
        
        humLow = rawx.pop(0).strip()            # humidity low byte
        humHigh = rawx.pop(0).strip()           # humidity high byte
        humRaw = (int(humHigh) * 256) + int(humLow)
        humRaw2 = humRaw + 0.0
        actualHum = humRaw2 / 10
        
        lightLow = rawx.pop(0).strip()            # humidity low byte
        lightHigh = rawx.pop(0).strip()           # humidity high byte
        lightRaw = (int(lightHigh) * 256) + int(lightLow)
        actualLight = lightRaw
        
        pir = rawx.pop(0).strip()               # PIR sensor 
        
        # Cayenne stuff:  ********************************
        #print("1: actualTemp: ", actualTemp)
        client.virtualWrite(1, actualTemp, "temp", "c")
        #print("2: actualHum: ", actualHum)
        client.virtualWrite(2, actualHum, "rel_hum", "p")
        #print("3: actualLight: ", actualLight)
        client.virtualWrite(3, actualLight, "lum", "p")
        #print("4: PIR: ", pir)
        client.virtualWrite(4, pir, "digital_sensor", "d")
        
        


      if node == '2':
        
        temperature = calcTemp()

        # Cayenne stuff:  ********************************
        client.virtualWrite(5, temperature, "temp", "c")
        
        # rolling average code:
        pointer = n2pointer
        temps = n2temps
        
        average = runningAverage(node, temperature, pointer, temps)
        node = average[0]
        avrg = average[1]
        pointer = average[2]
        temps = average[3]
        
        n2pointer = pointer
        n2temps = temps
        
        #print "Node: %s  Avg Temp: %s Celcius  Pointer: %s  List: %s" % (node, avrg, pointer, temps)
        
          

      elif node == '3':
        temperature = calcTemp()

        # Cayenne stuff:  ********************************
        client.virtualWrite(6, temperature, "temp", "c")
        
        # rolling average code:
        pointer = n3pointer
        temps = n3temps
        
        average = runningAverage(node, temperature, pointer, temps)
        node = average[0]
        avrg = average[1]
        pointer = average[2]
        temps = average[3]
        
        n3pointer = pointer
        n3temps = temps
        
        #print "Node: %s  Avg Temp: %s Celcius  Pointer: %s  List: %s" % (node, avrg, pointer, temps)
        


      elif node == '4':
        temperature = calcTemp()

        # Cayenne stuff:  ********************************
        client.virtualWrite(7, temperature, "temp", "c")
        
        # rolling average code:
        pointer = n4pointer
        temps = n4temps
        
        average = runningAverage(node, temperature, pointer, temps)
        node = average[0]
        avrg = average[1]
        pointer = average[2]
        temps = average[3]
        
        n4pointer = pointer
        n4temps = temps
    
        #print "Node: %s  Avg Temp: %s Celcius  Pointer: %s  List: %s" % (node, avrg, pointer, temps)
        
          

      elif node == '5':
        tempLow = rawx.pop(0).strip()           # temperature low byte
        tempHigh = rawx.pop(0).strip()          # temperature high byte
        if int(tempHigh) < 5:			# if this byte is greater than 5, 
						# temp is (for sure) a positive value
          tempRaw = (int(tempHigh) * 256) + int(tempLow)
        else:
          tempRaw = (255 ^ (int(tempLow))) * -1	# temp is negative value, so do a 1's complement
        tempRaw2 = tempRaw + 0.0
        actualTemp = tempRaw2 / 10
        
        humLow = rawx.pop(0).strip()            # humidity low byte
        humHigh = rawx.pop(0).strip()           # humidity high byte
        humRaw = (int(humHigh) * 256) + int(humLow)
        humRaw2 = humRaw + 0.0
        actualHum = humRaw2 / 10
        
        bvLow = rawx.pop(0).strip()              # batt volt low byte
        bvMid = rawx.pop(0).strip()              # batt volt mid byte
        bvHigh = rawx.pop(0).strip()             # batt volt high byte
        throwaway = rawx.pop(0).strip()          # throw away this byte
        bvRaw = (int(bvHigh) * 65536) + (int(bvMid) * 256) + int(bvLow)
        actualBv = bvRaw * 3.3 / 512			 # 512 or 1024, whichever works!
        Bv = round(actualBv, 2)

        spvLow = rawx.pop(0).strip()            # solarpanel low byte
        spvMid = rawx.pop(0).strip()            # solarpanel mid byte
        spvHigh = rawx.pop(0).strip()           # solarpanel high byte
        throwaway = rawx.pop(0).strip()         # throw away this byte
        spvRaw = (int(spvHigh) * 65536) + (int(spvMid) * 256) + int(spvLow)
        actualspv = spvRaw * 3.3 /512			# 512 or 1024, whichever works!
        Spv = round(actualspv, 2)

        # Cayenne stuff:  ********************************
        client.virtualWrite(8, actualTemp, "temp", "c")
        client.virtualWrite(9, actualHum, "rel_hum", "p")
        client.virtualWrite(10, Bv, "voltage", "v")
        client.virtualWrite(11, Spv, "voltage", "v")




      elif node == '6':                         # Oil Tank Level Sender
        oilLevel = rawx.pop(0).strip()

        client.virtualWrite(12, oilLevel, "tl", "gauge")
                
          
  
      elif node == '10':                        # Garage Node 10
        
        tempLow = rawx.pop(0).strip()           # temperature low byte
        tempHigh = rawx.pop(0).strip()          # temperature high byte
        if int(tempHigh) < 5:			# if this byte is greater than 5, 
						# temp is (for sure) a positive value
          tempRaw = (int(tempHigh) * 256) + int(tempLow)
        else:
          tempRaw = (255 ^ (int(tempLow))) * -1	# temp is negative value, so do a 1's complement
        tempRaw2 = tempRaw + 0.0
        actualTemp = tempRaw2 / 10              # Garage Temperature ***************

        humLow = rawx.pop(0).strip()            # humidity low byte
        humHigh = rawx.pop(0).strip()           # humidity high byte
        humRaw = (int(humHigh) * 256) + int(humLow)
        humRaw2 = humRaw + 0.0
        actualHum = humRaw2 / 10                # Garage Humidity ******************

        tempLow = rawx.pop(0).strip()           # temperature low byte
        tempHigh = rawx.pop(0).strip()          # temperature high byte
        if int(tempHigh) < 5:			# if this byte is greater than 5, 
						# temp is (for sure) a positive value
          tempRaw = (int(tempHigh) * 256) + int(tempLow)
        else:
          tempRaw = (255 ^ (int(tempLow))) * -1	# temp is negative value, so do a 1's complement
        tempRaw2 = tempRaw + 0.0
        actualTempWB = tempRaw2 / 10            # Wormbox Temperature **************

        humLow = rawx.pop(0).strip()            # humidity low byte
        humHigh = rawx.pop(0).strip()           # humidity high byte
        humRaw = (int(humHigh) * 256) + int(humLow)
        humRaw2 = humRaw + 0.0
        actualHumWB = humRaw2 / 10              # Wormbox Humidity *****************
        
        coLow = rawx.pop(0).strip()             # Carbon Monoxide high byte
        coHigh = rawx.pop(0).strip()            # Carbon Monoxide low byte
        coRaw = (int(coHigh) * 256) + int(coLow)
        actualco = coRaw
        #actualco = coRaw2 / 10                  # CO Level *************************
        
        # Garage Door Sensor Reading for Test
        gdLow = rawx.pop(0).strip()            # garage door low byte FOR TEST
        gdHigh = rawx.pop(0).strip()           # garage door high byte
        #gdRaw = (int(gdHigh) * 256) + int(gdLow)

        garageDoor = rawx.pop(0).strip()        # garage door

        client.virtualWrite(13, actualTemp, "temp", "c")
        client.virtualWrite(14, actualHum, "rel_hum", "p")
        client.virtualWrite(15, actualco, "co", "value")
        client.virtualWrite(16, garageDoor, "digital_sensor", "d")
        

        #print "Node: %s  CO2High: %s  CO2Low: %s  Garage Door: %s  LDRHigh: %s  LDRLow: %s" % (node, co2High, co2Low, garageDoor, ldrHigh, ldrLow)


        
      if node == '11':
        
        tempLow = rawx.pop(0).strip()           # temperature low byte
        tempHigh = rawx.pop(0).strip()          # temperature high byte
        if int(tempHigh) < 5:			# if this byte is greater than 5, 
        				# temp is (for sure) a positive value
          tempRaw = (int(tempHigh) * 256) + int(tempLow)
        else:
          tempRaw = (255 ^ (int(tempLow))) * -1	# temp is negative value, so do a 1's complement
        tempRaw2 = tempRaw + 0.0
        actualTemp = tempRaw2 / 10
        
        humLow = rawx.pop(0).strip()            # humidity low byte
        humHigh = rawx.pop(0).strip()           # humidity high byte
        humRaw = (int(humHigh) * 256) + int(humLow)
        humRaw2 = humRaw + 0.0
        actualHum = humRaw2 / 10
                
        bvLow = rawx.pop(0).strip()              # batt volt low byte
        bvMid = rawx.pop(0).strip()              # batt volt mid byte
        bvHigh = rawx.pop(0).strip()             # batt volt high byte
        throwaway = rawx.pop(0).strip()          # throw away this byte
        bvRaw = (int(bvHigh) * 65536) + (int(bvMid) * 256) + int(bvLow)
        actualBv = bvRaw * 3.3 / 1024
        Bv = round(actualBv, 2)

        spvLow = rawx.pop(0).strip()            # solarpanel low byte
        spvMid = rawx.pop(0).strip()            # solarpanel mid byte
        spvHigh = rawx.pop(0).strip()           # solarpanel high byte
        throwaway = rawx.pop(0).strip()         # throw away this byte
        spvRaw = (int(spvHigh) * 65536) + (int(spvMid) * 256) + int(spvLow)
        actualspv = spvRaw * 3.3 /1024
        Spv = round(actualspv, 2)
        
        client.virtualWrite(17, actualTemp, "temp", "c")
        client.virtualWrite(18, actualHum, "rel_hum", "p")
        client.virtualWrite(19, Bv, "voltage", "v")
        client.virtualWrite(20, Spv, "voltage", "v")