def detailsLog(chan, voltage, amperage, power, energy, frequency, powerFactor, alarmStatus): hdr = 'Chan,Volts,Amps,Watts,Energy (Wh),Freq (Hz),PF,Status' s = "{:.0f},{:.1f},{:.1f},{:.1f},{:.1f},{:.1f},{:.1f},{:.0f}".format( chan, voltage, amperage, power, energy, frequency, powerFactor, alarmStatus) topic = "sumpMaster/logDetails_" + chanNames[chan] pubScribe.pubRecord(pubScribe.CSV_FILE, topic, s, hdr)
def sendStatus() : s = time.strftime("\n%a, %d %b %Y %H:%M:%S ", last_us_t) s = s + "US: {: 6.2f}\n".format(last_us_result) s = s + time.strftime("%a, %d %b %Y %H:%M:%S ", last_abp_t) s = s + "ABP: {: 6.2f}\n".format(last_abp_result) topic = "basinMaster/Status" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, s)
def energyLog(): hdr = "" for name in chanNames: hdr += name + " cycles" + "," + name + " (Wh)" + "," hdr = hdr[:-1] s = "" for chan in range(0, len(chanNames)): s += str(round(cycles[chan])) + "," + str(round( powerConsumed[chan], 2)) + "," s = s[:-1] topic = "sumpMaster/logEnergy" pubScribe.pubRecord(pubScribe.CSV_FILE, topic, s, hdr)
def sendStatus(): printRowCol(messageRow, 0, "") clearDown() statusMsg = "Yesterday summary: \n" for chan in range(0, len(chanNames)): statusMsg += chanNames[chan] + " Cycles: {:<5.0f} \n".format( cyclesYesterday[chan]) statusMsg += "MinRunTime: " + formatTime( minRunTimeYesterday[chan]) + '\n' statusMsg += "MaxRunTime: " + formatTime( maxRunTimeYesterday[chan]) + '\n' statusMsg += "TotalRunTime: " + formatTime( runTimeYesterday[chan]) + '\n' statusMsg += "Power (Wh): {:<8.2f} \n\n".format( powerConsumedYesterday[chan]) topic = "sumpMaster/Status" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, statusMsg)
def readAirthings() : global msgOnce results = "" alert = 0 if not SerialNumber : if msgOnce : msgonce = 0 print("Wave not found! Trying manually entering serial number into code instead of scanning.") return try: waveplus = read_waveplus2c.WavePlus(SerialNumber) waveplus.connect() sensors = waveplus.read() waveplus.disconnect() data, wavePlusString, alert = sensor2StringUnits(sensors) if MCP4725_ENABLED : fanValue = round(dac.alg(data),3) # print("FanValue: ", fanValue) data.append(fanValue) wavePlusString.append('Fan value : {0:7.2f} '.format(fanValue)) if LOGGING_ENABLED : topic = "RadonMaster/WavePlus" pubScribe.pubRecord(pubScribe.CSV_FILE, topic, data, hdrRow) results = "" for item in wavePlusString : results += item + "\n" except : print("readAirthings() Exception!") waveplus.disconnect() return results, alert
def myTimer(): global timer, count, sensorSum, lastReadTime, statusIntervalCntDn, lastAlertTime global firstTimeAirthings global lastPressMsg, lastWaveMsg t = datetime.datetime.now() # Measure vacuum status, result = abp.readAbpStatus() if status == 0: sensorSum = sensorSum + abp.pres2inwc( -result) # change sign to convert pressure to vacuum count = count + 1 # Calculate average vacuum over interval, log data, and check for alert conditions if (count >= (tAverage * 0.8) and t.second == 0): sensorAvg = sensorSum / count sensorSum = 0 count = 0 # Append interval data to CSV file topic = "RadonMaster/PresSensor" pubScribe.pubRecord(pubScribe.CSV_FILE, topic, str(round(sensorAvg, 2)), "Inches w.c.") """ MS-Excel UNIX seconds to date and time date from seconds : =FLOOR(A2/86400,1)+DATE(1970,1,1) HH:MM from seconds: =MOD(A2,86400)/86400 """ sAlg = radonAlg(sensorAvg) lastPressMsg = '{0:s} Vacuum: {1:7.2f} in.wc'.format( formatLocalTime(), round(sensorAvg, 2)) print(lastPressMsg + " " + sAlg) if not (sAlg == "" or sAlg[:3] == "Cal"): alertMsg = "Alert " + lastPressMsg if pressAlertsEnabled: tsec = time.time() if ((tsec - lastAlertTime) > minIntervalBtwAlerts): lastAlertTime = tsec topic = "RadonMaster/Alert" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, alertMsg) # pubScribe.pubRecord(pubScribe.BUZZER, 'Buzzer', {'Frequency': 700, 'Dutycycle': 10, 'Duration': 10}) else: print(alertMsg) # if AIRTHINGS and (not (t.minute % 15)) and (t.second == 30): if firstTimeAirthings: firstTimeAirthings = 0 wave.writeHeaders() try: lastWaveMsg, alert = wave.readAirthings() if alert and waveAlertsEnabled: topic = "RadonMaster/Alert" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, lastWaveMsg) else: print(lastWaveMsg) lastWaveMsg = time.strftime("%a, %d %b %Y %H:%M:%S \n", time.localtime()) + lastWaveMsg except: print("Exception with Bluepy Airthings Wave...") # Send status message if (statusMsgEnabled and t.hour == statusMsgHHMM[0] and t.minute == statusMsgHHMM[1] and t.second == 0): sendStatus = 0 # Send status message every n days, after sending first status message if statusInterval: statusIntervalCntDn = statusIntervalCntDn - 1 if statusIntervalCntDn <= 0: statusIntervalCntDn = statusInterval sendStatus = 1 # Send status message on a day of the month elif statusDOM: if t.day == statusDOM: sendStatus = 1 # Send status message on a day of the week elif t.weekday() == statusDOW: sendStatus = 1 if sendStatus: s = "Reporting at " + time.strftime("%a, %d %b %Y %H:%M:%S \n", time.localtime()) s = s + lastPressMsg + "\n" + lastWaveMsg topic = "RadonMaster/Status" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, s) if not stopFlag: t = datetime.datetime.now() Timer(tInterval - t.microsecond / 1000000., myTimer).start() # every tInterval seconds
paramCheck() # Display sensor results on program startup status, result, tempC = abp.readAbpStatusTemp() # change sign of result to convert pressure to vacuum s = 'Status: {0:d} Vacuum: {1:7.3f} {2:s} {3:7.2f} in.wc {4:5.1f} degF\n'.format( status, round(-result, 3), abp.PRES_UNITS, round(abp.pres2inwc(-result), 2), round(abp.c2f(tempC), 1)) print(s) pubScribe.connectPubScribe() if statusMsgEnabled: topic = "RadonMaster/Status" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, "Program start\n" + s) startTimer() print( "First averaged set of measurement will display in a few minutes...\n" ) # chg 2020-12-03 try: while True: time.sleep(1) except KeyboardInterrupt: #timer.cancel() stopFlag = 1 time.sleep(tInterval + 1)
def sendAlert(subj, alertMsg) : topic = "basinMaster/Alert" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, alertMsg)
def gaugeRead(tInterval) : global last_us_result, last_us_t, last_abp_result, last_abp_t global measCnt, us_meas global last_us_log, last_abp_log us_result = -99 abp_result = -99 csv_str = "" deltaLogResult = 0 if measCnt : # Pump cycle on-off logic prior to measurement if ENABLE_HNY_ABP and (measCnt <= pumpOnCnt) : if (measCnt > pumpOffCnt) : hc_sr04_range.pump(PUMP_ON) # Low-cost aquarium bubbler pump to pressurize depth tube else : hc_sr04_range.pump(not PUMP_ON) if ENABLE_HC_SR04 and (measCnt <= US_MEAS_AVERAGING) : # Series of range measures to average dist = hc_sr04_range.sensorRead() if dist : us_meas.append(dist) measCnt -= 1 else : measCnt = int(measTime/tInterval) - 1 t = time.localtime() if ENABLE_HC_SR04 : # Average ultrasonic measurements cnt = len(us_meas) if cnt > (US_MEAS_AVERAGING // 2) : mean = sum(us_meas) / cnt # variance = sum([((x - mean) ** 2) for x in us_meas]) / cnt # res = variance ** 0.5 us_result = round(US_WELL_DEPTH - mean, 2) if us_result != -99 : last_us_result = us_result last_us_t = t if (abs(us_result - last_us_log) > US_GAUGE_DELTA_LOG) : deltaLogResult = 1 last_us_log = us_result us_meas = [] if ENABLE_HNY_ABP : # Get pressure reading status, result, tempC = abp.readAbpStatusTemp() if status == 0 : abp_result = round(abp.pres2inwc(result),2) if abp_result != -99 : last_abp_result = abp_result last_abp_t = t if (abs(abp_result - last_abp_log) > ABP_GAUGE_DELTA_LOG) : deltaLogResult = 1 last_abp_log = abp_result else : print("Water depth pressure sensor fault...") if (depthGaugeLogEnable and (deltaLogResult or depthGaugeLogAll)) : topic = "basinMaster/WaterDepth" data = {"Ultrasonic (in)": round(us_result,2), "ABP (in)": round(abp_result,2)} pubScribe.pubRecord(pubScribe.CSV_FILE, topic, data) return us_result, abp_result
def sendAlert(subj, alertMsg): printRowCol(messageRow, 0, "") clearDown() topic = "sumpMaster/Alert" pubScribe.pubRecord(pubScribe.EMAIL_SMS, topic, alertMsg)
def readPower(): global lastReadTime global lastStateOn, onTime global voltage, amperage, power, energy, frequency, powerFactor, alarmStatus global cycles, runTime, powerConsumed global cyclesToday, runTimeToday, powerConsumedToday, minRunTimeToday, maxRunTimeToday global maxRuntimeLastEmailTime, messageText t = time.time() timeDelta = (t - lastReadTime) if timeDelta > tInterval * 10: # Assume first interval is tInterval timeDelta = tInterval for chan in range(0, len(chanNames)): [voltage[chan], amperage[chan], power[chan], energy[chan], frequency[chan], powerFactor[chan], \ alarmStatus[chan]] = pzem.readAcPZEM(chanPorts[chan], chanAddrs[chan]) if (power[chan] > chanOnThresholds[chan]): detailsLog(chan, voltage[chan], amperage[chan], power[chan], energy[chan], frequency[chan], \ powerFactor[chan], alarmStatus[chan]) algSump.motorStatsAppend(chan, power[chan]) runTime[chan] = runTime[chan] + timeDelta runTimeToday[chan] = runTimeToday[chan] + timeDelta if (lastStateOn[chan] == 0): cycles[chan] = cycles[chan] + 1 lastStateOn[chan] = 1 cyclesToday[chan] = cyclesToday[chan] + 1 onTime[chan] = t # time motor turned on elif (alertMsgEnabled and (t > (runTimeAlert[chan] + onTime[chan]))): # Motor on time exceeded threshold if (t > (minIntervalBtwEmails[chan]) + maxRuntimeLastEmailTime[chan]): # Allowed to send email text message maxRuntimeLastEmailTime[chan] = t s = chanNames[chan] + " on time exceeded!" sendAlert(chanNames[chan], s) elif lastStateOn[chan]: lastStateOn[chan] = 0 rt = t - onTime[chan] if minRunTimeToday[chan] == 0: minRunTimeToday[chan] = rt elif rt < minRunTimeToday[chan]: minRunTimeToday[chan] = rt if rt > maxRunTimeToday[chan]: maxRunTimeToday[chan] = rt hdr, returnStr, alertMsg = algSump.motorStats( chan, chanNames, rt, tInterval) timeStr = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S.%f')[:-3] messageText = "{:.2f},{},{}".format(t, timeStr, returnStr + " ") if returnStr != "": topic = "sumpMaster/logStats_" + chanNames[chan] pubScribe.pubRecord(pubScribe.CSV_FILE, topic, returnStr, hdr) if alertMsg != "" and alertMsgEnabled and ( t > (minIntervalBtwEmails[chan]) + algLastEmailTime[chan]): # Allowed to send email text message algLastEmailTime[chan] = t sendAlert(chanNames[chan], alertMsg) if lastReadTime: pwr = power[chan] * timeDelta / 3600. powerConsumed[chan] = powerConsumed[chan] + pwr powerConsumedToday[chan] = powerConsumedToday[chan] + pwr # end for lastReadTime = t