プールフィルコントロール
水位、温度、pH、ORP、フィルター圧力、電気使用量、およびポンプ操作を監視するシステム。必要に応じてプールを補充します。
ストーリー
アイデア
2015年の夏、息子と私はプールシステム全体を再構築しました。それは、家を手にしたときに受け継いだ給水管とバルブの問題、フィルターの問題、そして家を手にしたときから引き継がれていた基本的に不適切なプール会社から始まりました。このようになり始めたら、何かをする時が来たと思いました:
私たち自身のプライベートラグーン
はじめに
最優先事項は、プールをクリーンアップしてから、その状態を維持する方法を見つけることでした。私は常に自動化が大好きで、これを試すのに最適な場所だと思いました。まもなく、プールは再び次のようになりました:
通常の状態に戻る
私の労働力
言うまでもなく、プロジェクトを進めるには、そのコンクリートとプールラインをすべて交換する必要がありました。ほとんどすべてが行かなければなりませんでした。
早い段階で、新しいプールシステムに自動化を組み込むことにしました。オートパイロットと呼ばれる管理システムを選択しました。 (私の家族は、私がパイロットで名前が好きだったので、それを選んだと言っています! )このシステムにより、プールを塩水プールに変換し、管理の一部を処理できます。主に、必要に応じて塩水ジェネレーターを実行し、酸をポンプしてpHを管理します。これら以外の自動化はありませんでした。
自動化–始まり
物理的なプラントが設置され、稼働しているので、常にホースを外さなくてもプールを埋めることができればいいと思いました。私はラズベリーパイと通常のスプリンクラーバルブを使って考えました、私はビジネスになります!別のPiを購入し(さまざまなプロジェクトに使用しています)、やりたいことをレイアウトしました。
Raspberry Pi3
当初、私は2つのことができる必要があると考えました:
- 水位を測定する方法
- 水が少なくなったときにプールを埋める方法
私は研究を始め、水(または他の液体)のレベルが上下するにつれて抵抗が変化する液体巻尺を製造している会社に出会いました。ミローネは、私が配置したい場所にサイズが合わないため、私にも特定のサイズのユニットを作成してくれます。
MiloneのeTape
更新 :残念ながら、何らかの理由で私のMilone eTapeは実際のジャケットの中に水が入るのに苦労し、失敗しました。ミローネと問題について話し合った後、私はそれを交換するためのコストと潜在的に同じ問題に苦しむことは、交換のコストの価値がないと判断しました。さらに悪いことに、私は彼らが私のために特別に作らなければならない特別なサイズが必要です。
内側の袖に水が入っているとeTapeが失敗しました…。
Elecallステンレス鋼タンク水位センサーフロートスイッチ
eTapeを使用して素晴らしい結果が得られた他の人を何人か知っているので、eTapeに関するすべてをプロジェクトに残し、デュアルフロートセットアップの方法を追加します。このようにして、人々はいくつかの異なるオプションを見ることができます。
Piが存在する場所から庭の向こう側に配置されるため、レポート用に独自のデバイスに接続する必要がありました。このためにPiは必要なかったので、家の周りにすでに設置されている既存のシステムに情報を送信する、バッテリー駆動の低電力Arduinoワイヤレスクローンを選択しました。
Moteino R5-USB、フラッシュおよびRFM69HW433Mhzトランシーバー
当初、私はプールに水を自動的に追加する以外のことをするつもりはありませんでしたが、これらのことが頻繁に行われるように、プロジェクトは独自の精神で成長しました。最終的には、次のことができるようになります。
- 水位を監視し、必要に応じて水を追加します
- プールの温度を監視する
- フィルター圧力を監視する
- pHを監視する
- ORPの監視
- 電力使用量を監視して、プールポンプが稼働しているかどうかを判断します
- スプリンクラーシステムを監視して、スプリンクラーが実行されているかどうかを確認します
- システムが起動または水を追加したときに通知します(Pushbullet、Eメール、またはSMSを介して)
- システムが水の追加を停止したときに通知します
- システムでエラー状態が発生した場合は通知してください
- CLIを使用するか、エンクロージャーのボタンを押して、手動で水を追加します
- クリーンなWebインターフェイスを提供して、システムのステータスを確認し、Web経由でプールの充填を開始および停止できるようにします。
- Alexaを介してプール制御システムと対話する(情報を取得し、水を開始/停止する)
プールを埋める
プールの充填ルーティングをトリガーするもの(手動または自動)に関係なく、水をプールに入れる方法が必要でした。灌漑と水道の間にバキュームブレーカが必要なため、プール用の水を得るために、既存のスプリンクラーシステムにバキュームブレーカを接続することにしました。基本的に、スプリンクラーシステム用に、バルブを備えた別の「ゾーン」を作成していました。
これは、スプリンクラーが実行されていて、プールを埋めることを決定した場合、芝生ゾーンが水を流しているものを奪い、芝生に適切に水を供給しないという問題を提示しました。そのため、スプリンクラーが実行されているかどうかを判断する方法を考案する必要がありました。最初は「ブラックアウト」タイムゾーンを使用していました。つまり、スプリンクラーが午前3時から午前6時まで稼働していることがわかっている場合は、その間はプールをいっぱいにしないでください。しかし、それは少し非技術的なようでした。 Rachioスプリンクラーシステムを調べたところ、スプリンクラーシステムのステータスをプログラムで照会できるAPIが組み込まれていることがわかりました。私の場合、簡単な質問がありました。実行していますか?
私の場合、必要なものを取得するために単純なcurlコマンドを使用しました:
rachio_url ='curl -s -X GET -H "Content-Type:application / json" -H "Authorization:Bearer xxxx-xxxxx-xx-xxxx-xxxxx-xxx" https:/ /api.rach.io/1/public/device/00xx00x-00xxx000-xxx0x000-00x0x0x0/current_schedule'
これは、次のようなget_sprinkler_status関数によって呼び出されます。
output =subprocess.check_output(pooldb.rachio_url、shell =True)if output =="{}":sprinklers_on ="No"
メインアプリケーションは60秒ごとに実行されるため、スプリンクラーが実行されている場合は、さらに60秒間何もせずに、もう一度確認します。最終的に、スプリンクラーは実行を停止し、プールは自動的にいっぱいになり始めます。
実際にプールを埋めるために、ホームデポで拾った通常の24VACスプリンクラーバルブを使用しました。私はこれを一方向弁でプールに行くプールの配管に直接取り付けました。逆止弁は、ポンプの運転中にポンプからの圧力がスプリンクラーバルブに水を押し付けるのを防ぎます。
逆止弁付き給水管
リレーのセットアップ
スプリンクラーバルブとスマート水道メーター
パワー、パワー、パワー
次に、私が理解する必要のあることが起こりました。ポンプが作動しているときに、プールを満タンにしようとすると、ポンプの圧力と戦うことになります。水の流れを測定した結果、ポンプの運転中に充填流量の約50%が失われたと判断したため、ポンプの稼働中は充填しないのが最善であると考えました。そのため、ポンプからの電力を監視し、ポンプが稼働しているかどうかを判断する方法が必要でした。
この場合、これを行うのに非常に簡単な方法がありました。私の家のすべての回路は、電気監視システムによって監視されています。このシステムはGEMと呼ばれ、Brultechによって販売されています。
私のプールポンプは私の家の最大の電力消費者です
if pool_pump_running_watts> pooldb.max_wattage:pool_fill_control.led_control(PUMP_RUN_LED、 "ON")pool_pump_running ="Yes" logger.debug( 'PUMP_RUN_LEDがオンになっている必要があります。これは黄色のLEDです')if DEBUG :print( "PUMP_RUN_LEDがオンになっている必要があります。これは黄色のLEDです")else:pool_fill_control.led_control(PUMP_RUN_LED、 "OFF")pool_pump_running ="No" logger.debug( 'PUMP_RUN_LEDがオフになっている必要があります。これは黄色のLEDです') DEBUGの場合:print( "PUMP_RUN_LEDはオフにする必要があります。これは黄色のLEDです")
物理ユニットにさまざまなボタン、スイッチ、LEDがあり、スプリンクラーが稼働しているか、ポンプが稼働しているか、プールがいっぱいになっているか、何らかのシステムエラーが発生しているかを確認できます。 。上の図は、必要に応じてポンプの実行LEDのオンとオフを切り替える場所を示しています。
システムLEDに加えて、システムのオン/オフボタン(左上)があり、MightyHatシステムを使用して、PiにログインしなくてもPiをインテリジェントに再起動またはシャットダウンできます。 CLIから実行します。また、必要なときに手動でプールを埋めることができるモーメンタリスイッチ(左側の2番目)があり、最後に左側に、システムからスプリンクラーバルブへの電力を物理的に遮断してGPIOをトリガーするDPDTスイッチがあります。プールの充填を手動で無効にしたことをシステムに通知するイベント。このスイッチがトリガーされたときは何も機能せず、プログラムで何かが失敗した場合、変圧器からスプリンクラーバルブに電力を供給することはできません。
プールコントローラー–外部
ポンプの管理
def get_pump_data(key):verbose_debug( "get_pump_data()Started")verbose_debug( "get_pump_data()called with '{}'" .format(key))log( "INFO"、 " get_pump_data()は '{}' ".format(key))で呼び出されますif pump_control_active:global json try:req =urllib2.Request(pooldb.PUMP_DATA_URL)opener =urllib2.build_opener()f =opener.open(req)data =json.load(f)pump_data =data ["pump"] ["1"] [key] verbose_debug( "get_pump_data()returned {}"。format(pump_data))log( "INFO"、 "get_pump_data()returned { } "。format(pump_data))verbose_debug(" get_pump_data()-Completed ")log(" INFO "、" get_pump_data()-Completed ")if key ==" gpm ":pump_gpm =pump_data update_database(" pump_status "、" pump_gpm "、pump_gpm)log(" INFO "、"現在のGPM:{} "。format(pump_gpm))log(" DEBUG "、" get_pump_gpm()Completed ")debug(" Curr ent GPM:{} "。format(pump_gpm))verbose_debug(" get_pump_gpm()Completed ")elif key ==" rpm ":pump_rpm =pump_data update_database(" pump_status "、" pump_rpm "、pump_rpm)log(" INFO "、 "現在のRPM:{}"。format(pump_rpm))log( "DEBUG"、 "get_pump_rpm()Completed")debug( "現在のRPM:{}"。format(pump_rpm))verbose_debug( "get_pump_rpm()Completed") else:pump_watts =pump_data update_database( "pump_status"、 "pump_watts"、pump_watts)log( "INFO"、 "Current WATTS:{}"。format(pump_watts))log( "DEBUG"、 "get_pump_watts()Completed")debug ( "現在のワット数:{}"。format(pump_watts))verbose_debug( "get_pump_watts()Completed")エラーとして例外を除いてpump_dataを返します:pump_data =0 debug( "EXCEPTION:get_pump_data()")log( "WARN"、 "例外:get_pump_data() ") log( "WARN"、error)debug(type(error))debug(error)verbose_debug( "get_pump_data()-Completed with EXCEPTION")log( "DEBUG"、 "get_pump_data()-Completed with EXCEPTION")return pump_data else :pump_data =0 return pump_data
これで、ポンプにクエリを実行してポンプを制御し、以前にはなかった別の機能を追加できます。 Webインターフェースを変更することにより、ポンプを開始または停止する機能と、ポンプで構成した4つの異なるポンププログラムのいずれかを実行する機能を追加しました。
ポンプコントロールパネル
Webインターフェースのポンプゲージ
フィルター圧力の監視
私もやりたかったことの1つは、フィルターの圧力を監視することでした。そのため、フィルターをいつバックフラッシュするかがわかりました。 eBayで100PSIの圧力センサーを購入し、フィルターに既に取り付けられているアナログ圧力計の横にあるフィルターに接続しました。
eBayから安価な送信機ユニットを購入し(上記のリンクを参照)、次のようにファイラーに結び付けました:
100 PSI Sender unitPressure Sending unitSending Unit Wiring ..
次に、これをMoteino-R5に結び付け、1分に1回圧力を読み取り、その情報をMySQLデータベースに出力してから、私のウェブサイトでゲージ出力を駆動します。
//フィルター圧力を取得voidget_filter_pressure(){sensorVoltage =analogRead(PSI_SENSOR_PIN); //圧力センサーの電圧を読みましょうPSI =((sensorVoltage-146)/ 204)* 25; //電圧をPSIに変換し、ゼロにするためのキャリブレーションpool_sensors.PSI =PSI; }
プールフィルターPSIゲージ
追加のハードウェアとソフトウェア
Raspberry Piでは、PiへのUPS電源バックアップ、LCDステータス画面、Piのインテリジェント電源制御を提供するLow Power LabsMightyHatを利用しています。システムに接続した小さなバッテリーで約2時間Piを実行できますが、電源が戻ってこない場合は、MightyHatが自動的にPiをシャットダウンして、突然のクラッシュを防ぎます。停電。
オーバーフィルアラートを示すPi3上のMightyHatのクローズアップ
センシングには、さまざまなセンサーと方法を使用して、情報を使用可能な形式に変換します。ほとんどすべてのセンサーデータについて、OpenEnergyMonitor.orgの無料のEmonCMSプラットフォームを利用しています。このプラットフォームを使用すると、家のどこからでもすべてのセンサーデータを収集できます。この情報はMySQLデータベースに保存され、プール制御システムで利用するために取得できます。
プールのセンサー追跡の一部追加の追跡情報
eTapeとMoteinoすべてをモックアップ
私のIOコントローラーボードの1つ
IOコントローラーボード、LEDコントローラー、電源インターフェースIOコントローラーボード–戻る
USBpHおよびORPセンサーボード
Atlas ScientificpHおよびORPセンサーインターフェースボード
フローセル(左端)センサー付きフローセルJohn Guest 3/8 "スレッドクイックコネクトリターン(吸引)ライン出力(圧力)ライン–酸インジェクターの前に取り付け
def get_ph_reading():log( "DEBUG"、 "get_ph_reading()Started")pool_pump_running =read_pool_sensor_status_values( "pool_sensor_status"、 "led_status"、 "pump_run_led")if pool_pump_running =="True :if pooldb.temp_probe =="Yes":pool_temp =float(read_pool_sensor_status_values( "pool_sensor_status"、 "system_status"、 "pool_current_temp"))ph_value =float(get_ph.get_current_ph_with_temp(pool_temp))else:ph_value =float(get_ph ())debug( "現在のpHは:{}"。format(ph_value))influx_data.write_data( "pH"、ph_value)influx_data.write_data( "pool_temp"、pool_temp)if pooldb.emoncms_server1 =="Yes":res =requests.get( "http://" + pooldb.server1 + "/" + pooldb.emoncmspath1 + "/ input / post?&node =" + str(pooldb.ph_node)+ "&csv =" + ph_value + "&apikey ="+ pooldb.apikey1)log(" DEBUG "、"現在のpH値{}をEmoncmsサーバー1に送信 ".format(ph_v alue))debug( "{}の現在のpH値をEmoncmsサーバー1に送信" .format(ph_value))if pooldb.emoncms_server2 =="Yes":res =requests.get( "https://" + pooldb.server2 + "/" + pooldb.emoncmspath2 + "/ input / post?&node =" + str(pooldb.ph_node)+ "&csv =" + ph_value + "&apikey =" + pooldb.apikey2)log( "DEBUG"、 "送信済み{}の現在のpH値をEmoncmsServer 2 ".format(ph_value))debug("現在のpH値{}をEmoncmsServer2に送信 ".format(ph_value))update_pool_sensor_status_values(" pool_sensor_status "、" pool_chemicals "、" pool_current_ph "、ph_value)log(" DEBUG "、" get_ph_reading()Completed ")else:log(" INFO "、"プールポンプが実行されていません。正確なpH測定値を取得できません! ")debug("プールポンプが実行されていません。正確なpH測定値を取得してください! ")log(" DEBUG "、" get_ph_reading()Completed ")
このコードは、次のような「get_ph.py」モジュールを呼び出します。
#!/ usr / bin / python ##プールで使用する場合_control_master.py__author __ ='Richard J. Sears' VERSION ="V3.4(2018-03-16)"#[メール保護]#これはAtlas ScientificpHボードでのみ使用されます。importserialimportsysimporttimefromserial import SerialExceptionusbport ='/ dev / PH'try:ser =serial.Serial(usbport、38400、timeout =0)except serial.SerialException as e: print "Error、"、e sys.exit(0)def read_line():lsl =len( '\ r')line_buffer =[] while True:next_char =ser.read(1)if next_char =='':break line_buffer.append(next_char)if(len(line_buffer)> =lsl and line_buffer [-lsl:] ==list( '\ r')):break return '' .join(line_buffer)def read_lines():lines =[ ] try:while True:line =read_line()if not line:bre ak ser.flush_input()lines.append(line)は、SerialExceptionを除く行をe:print "Error、"、e return Nonedef send_cmd(cmd): "" "コマンドをアトラスセンサーに送信します。送信する前に、コマンドの最後にキャリッジリターンを追加します。 :param cmd :: return: "" "buf =cmd +" \ r "#キャリッジリターンを追加try:ser.write(buf)return True(SerialException as eを除く):print" Error、 "、e return Nonedef get_current_ph_with_temp(current_temp) :#send_cmd( "RESPONSE、0")send_cmd( "C、0")send_cmd( "T、%d"%current_temp)send_cmd( "R")time.sleep(1.3)lines =read_line()return linesdef get_current_ph_no_temp( ):#send_cmd( "RESPONSE、0")send_cmd( "C、0")send_cmd( "R")time.sleep(1.3)lines =read_line()return linesdef main():#send_cmd( "RESPONSE、0" )send_cmd( "C、0")send_cmd( "R")time.sleep(1.3)lines =read_lines()print( "温度校正は実行されません:")for i in range(len(lines)):print lines [ i] if __name__ =='__ main __':main()
def pool_pump_running_chemical():pool_pump_running_chemical =GPIO.input(pool_pump_running_pin)if pool_pump_running_chemical ==False:debug( "Pool Pump Running via Chemical Sensor Chamber:TRUE-PUMP IS RUNNING")else:debug( 「化学センサーチャンバーを介して作動するプールポンプ:FALSE-ポンプがオフです」)
水位センサー–機能させる
上で示したように、水位センサーはLowPowerLabのバッテリー駆動のMoteinoUBSを利用しています。これは、このアプリケーションに最適なマイクロコントローラーです。基本的に、私はMoteinoを60秒ごとに起動し、eTapeから抵抗を読み取り、送信機を起動して、プールスクリプトで使用するためにこの情報をEmonCMSシステムに送信します。次に、すべての電源を再び切ります:
{digitalWrite(ETAPE_POWER、HIGH); // eTapeプールの電源をオンにします。resistance=analogRead(ETAPE); //エタペ抵抗を読み取りますdigitalWrite(ETAPE_POWER、LOW); // eTapeへの電源をオフにしますtake_battery_reading(); //バッテリーの読み取りを行いますpower_spi_enable(); rf12_sleep(RF12_WAKEUP); rf12_sendNow(0、&pool、sizeof pool); rf12_sendWait(2); rf12_sleep(RF12_SLEEP); power_spi_disable(); if(debug){flash_led(50); } //それだけです-次回まで待ちます:)sleep_until_next_reading(); }
バッテリーの電圧も追跡しているので、バッテリーを交換する時期がわかります。スクリプトには、バッテリーが良好であることを確認するためのいくつかのメカニズムがあります。まず、バッテリー電圧自体を積極的に追跡し、次に、センサーが私に報告する頻度とそれらの報告の時間デルタを追跡します。多くの読み逃しに、そのセンサーに「何か」が間違っていることを知っているので、何が悪いのかを確認するためにPushbullet通知を受け取ります。さらに、センサーが失われると、プール充填システムがスタンバイ状態になり、いつ停止するかわからないため、プールの充填を拒否します。
プールレベルのMoteinoUSBを安全に保つために、ある種の防水エンクロージャーが必要でした。蓋が透明なAdafruit耐候性ボックスを選びました。
Adafruit耐候性ケース
AdafruitPG-9ケーブルグランド
Adafruit防水DC電源ケーブル完成した水位センサーエンクロージャー
次に、水位センサーを取り付ける方法と場所を見つける必要がありました。私のプールには、プールに手動で水を追加するフロートを収容するために使用された小さなセメント盆地があります。これはずっと前に錆びてしまい、セメントの囲いを引き裂かずに修理することはできませんでした。これが私のプロジェクトを最初に始めたものです!
セメント盆地
PVCパイプに取り付けられたeTapeセンサー完成したeTapeセンサーのインストール
更新:水位を読み取る新しい方法!
上記をお読みになると、eTapeのインストールに問題が発生し、eTapeが機能しなくなり、誤った読み取り値が表示されて使用できなくなりました。 MileoneでChrisと話しましたが、テープが失敗したために立ち上がれませんでした。結局、別のテープを入手して同じことが再び起こるようにするのに、さらに80ドルの価値はなかったので、水位の読み取り方法を切り替えました。
Elecallステンレス鋼タンク水位センサーフロートスイッチ
マウントするには、エポキシを使用し、「組み込みレベル:
」を使用してレベリングしました。プールのレベルを読み取るには、両方のフロートの位置を知る必要があります。そこで、両方のフロートの位置を読み取り、水位に応じて0、1、または2を送信するようにコードをプログラムしました。
上部フロートが開いていて下部フロートが開いている(両方が下に浮いている)場合、ローになり、「0」が送信されます。下のフロートが閉じている(上)、上のフロートが開いている(下)場合、途中で「1」を送信します。両方のフロートが閉じている(上にある)場合、プールはいっぱいで、水は必要ありません。コードは次のようになります。
UPPER_Float =digitalRead(17); LOWER_Float =digitalRead(3); if(UPPER_Float ==LOW){UPPER_Float_Position ="Closed"; } else {UPPER_Float_Position ="Open"; } if(LOWER_Float ==LOW){LOWER_Float_Position ="Closed"; } else {LOWER_Float_Position ="Open"; } if((UPPER_Float ==LOW)&&(LOWER_Float ==LOW)){pool_level.level =2; //両方が閉じている=プールがいっぱいです} else if((UPPER_Float ==HIGH)&&(LOWER_Float ==LOW)){pool_level.level =1; //下部が閉じ、上部が開いている=プールMIDWAY} else {pool_level.level =0; //両方のフロートが開いている=プールLOW水を追加}
したがって、0、1、または2の値がEmonCMSに送信され、データベースに書き込まれます。毎分、そのデータベースにクエリを実行して、水を追加する必要があるかどうかを確認します。
get_pool_level_value =read_emoncms_database( "data"、pooldb.pool_level_table)
そして、それが低い場合は、水を追加します:
if get_pool_level_value ==0:get_pool_level ="LOW" pool_fill_valve( "OPEN")
これは、プールレベルを読み取り、プールの充填を管理する新しい方法です。
プール温度センサー–機能させる
eTapeセンサーの足跡をたどって、プール温度センサーと同じ構成を作成します。ただし、今回はエンクロージャー内に温度プローブを追加して、エンクロージャー内の温度を監視できるようにしました。また、プールの水面のすぐ上の温度も教えてくれます。 2番目の温度センサーはPG-9ケーブルグランドを介してプールの水に供給されました。それから私はちょうど囲いをプールに投げ入れて、私が終わったと思いました。しかし、私の子供たちは他の考えを持っていました。彼らは、エンクロージャーからぶら下がっている温度センサーをつかみ、それをトップのように回転させて、お互いに投げるのは楽しいと思いました。言うまでもなく、最初のものは長くは続かなかった。
そこで、地元のプール店に行って塩素フローターを購入し、エンクロージャーと温度プローブを取り付けました。それ以来、問題は発生していません。投げても全く気になりません。塩水プールがあるのに塩素だと思っているので、ほとんどの人はそのままにしておきます。
プール温度センサーフロータープール温度センサーフローター
私たちの酸レベルを追跡する
私のプロジェクトで処理されていないプール自動化システムの一部は、pHを制御するための塩酸の分配です。プールの自動操縦システムがそれを処理している間、タンクに酸を追加する必要があるかどうかを確認できる必要があります。このために、私は$ 9.00のDFRobot液面センサーを使用しました:
XKC-Y25-T12V液面センサー
def acid_level():acid_level_ok =GPIO.input(acid_level_sensor_pin)if acid_level_ok ==True:
次に、センサーを通知したいレベルの酸タンクにエポキシで固定し、すべてを接続しました:
このタンクの壁はかなり厚く、このセンサーはうまく機能しました。念のため、貼り付ける前にテストしました。
Webインターフェイス
V3.5.0Webインターフェイス
- すべてのセンサーデータを素敵なゲージで視覚的に確認
- 全体的なステータス、ポンプのステータス、充填ステータス、スプリンクラーのステータス(スプリンクラーの実行中は充填できません)、酸レベルなどのシステムステータスを確認します
- プールレベルと温度センサー(家庭用温度センサーを含む)のバッテリーステータスを視覚的に確認します
- 実際のセンサーボックス内の温度と湿度を確認して、「防水」ボックスに潜在的な水漏れがあるかどうかを確認します。
- デバッグ、ロギング、電子メール、プッシュブレット、SMSメッセージなどのさまざまな通知をインターフェイスから切り替える機能があります
- PentairIntellifloプールポンプを制御する
Russell Goldin([メールで保護])が、システムがポンプと通信してポンプを制御できるようにするために必要なPentairRS-485制御ソフトウェアに関するすばらしい作業に感謝しています。彼のgithubはこちらで確認できます。
Russのソフトウェアを使用すると、独自のハードウェアに数千ドルを費やすことなく、Pentairポンプを直接制御できます。
Pythonですべてをプログラミングするのに多くの時間を費やしましたが、Webインターフェースを構築した経験がなかったので、周りに尋ねて、最終的にWebを構築するために使用するWebフレームワークとしてFlaskを決定しました。インターフェース。
Flaskの学習は、私が思っていたほど難しくはなく、プールを制御するためにすでに作成したPythonコードと非常によく統合されています。 Flaskは、PythonのようなコードとHTMLのようなテンプレートを組み合わせたものであり、必要なすべてのことを実行しました。
上部コントロールパネルシステムゲージ下部パネル
プールを自動的に充填していて、そのプロセスを停止したい場合は、[プールの充填]ボタンをクリックするだけです(ボタンを押すと自動充填を停止できることを示すために、LEDがボタンに戻ります)システムは入力を停止し、システムの構成(デバッグ、ロギング、電子メール、プッシュブレット、SMS)に基づいて通知を送信します。
{%if system_error_led =="True"%} {%elif system_run_led ==" True "%} {%else%} { %endif%}
この例では、システムエラーがある場合は赤いLEDを表示し、システムが実行されている場合は緑のLEDを表示し、実行していない場合はエラーがない場合は表示します灰色のLED。このステートメントは、htmlがレンダリングされる前に処理され、Python駆動システムと対話するための非常に強力な方法です。
履歴グラフ
システムを拡張し、自分に何ができるかを学びながら、プールシステムの歴史的な傾向や、他の多くのホームオートメーションで遊んでいるものを見始めたいと思いました。最近と。周りを見回した後、GrafanaとInfluxDBを選択します。
基本的に、EmonCMSを使用してデータを記録していたので、Grafanaが魔法のようにデータをInfluxDBに取り込むための簡単な方法が必要でした。基本的に、メールプールプログラム内で、pH、ORP、または一時的な読み取り値を取得するたびに、それをinfluxdbに書き込みます:
def get_ph_reading():log( "DEBUG"、 "get_ph_reading()Started")pool_pump_running =read_pool_sensor_status_values( "pool_sensor_status"、 "led_status"、 "pump_run_led")if pool_pump_running =="True :if pooldb.temp_probe =="Yes":pool_temp =float(read_pool_sensor_status_values( "pool_sensor_status"、 "system_status"、 "pool_current_temp"))ph_value =float(get_ph.get_current_ph_with_temp(pool_temp))else:ph_value =float(get_ph ())debug( "現在のpHは:{}"。format(ph_value))influx_data.write_data( "pH"、ph_value)influx_data.write_data( "pool_temp"、pool_temp)if pooldb.emoncms_server1 =="Yes":res =requests.get( "http://" + pooldb.server1 + "/" + pooldb.emoncmspath1 + "/ input / post?&node =" + str(pooldb.ph_node)+ "&csv =" + ph_value + "&apikey ="+ pooldb.apikey1)log(" DEBUG "、"現在のpH値{}をEmoncmsサーバー1に送信 ".format(ph_v alue))debug( "{}の現在のpH値をEmoncmsサーバー1に送信" .format(ph_value))if pooldb.emoncms_server2 =="Yes":res =requests.get( "https://" + pooldb.server2 + "/" + pooldb.emoncmspath2 + "/ input / post?&node =" + str(pooldb.ph_node)+ "&csv =" + ph_value + "&apikey =" + pooldb.apikey2)log( "DEBUG"、 "送信済み{}の現在のpH値をEmoncmsServer 2 ".format(ph_value))debug("現在のpH値{}をEmoncmsServer2に送信 ".format(ph_value))update_pool_sensor_status_values(" pool_sensor_status "、" pool_chemicals "、" pool_current_ph "、ph_value)log(" DEBUG "、" get_ph_reading()Completed ")else:log(" INFO "、"プールポンプが実行されていません。正確なpH測定値を取得できません! ")debug("プールポンプが実行されていません。正確なpH測定値を取得してください! ")log(" DEBUG "、" get_ph_reading()Completed ")
import syssys.path.append( '../')from influxdb import InfluxDBClientimport pooldbdef write_data(measurement、value):client =InfluxDBClient(pooldb.influx_host、pooldb.influx_port、pooldb.influx_user、 pooldb.influx_password、pooldb.influx_dbname)json_body =[{"測定":測定、 "フィールド":{"値":値}}] client.write_points(json_body)
そこから、InfluxDBを確認してグラフを作成するようにGrafanaを設定するだけです。
通知
このようにコードを設定することで、通知設定と、その時点で通知を適用したいさまざまなカテゴリを非常に簡単かつ迅速に調整できます。コードの将来のバージョンでは、カテゴリごとに特定の通知タイプを設定できる「通知」パネル全体を作成する予定です。たとえば、イベントの充填に関するSMSメッセージが必要な場合がありますが、システムエラーに関する通知とポンプに関するプッシュブレット通知を電子メールで送信します。このようにして、すべての通知設定を調整して、通知する方法とタイミングの両方を正確に調整することができます。
現在の通知設定パネル
CLIから実行
Alexaのスキルとインターフェース
これは非常に興味深い学習曲線でしたが、Alexaにクエリを実行してすべてのプール統計を取得し、音声コマンドでプールを埋める(または埋めるのをやめる)ことができます:
プール、電気、ソーラーの統計情報を備えたAlexa Show Interface
結論
現在、コードのV3.5.0を実行しています。これにより、センサーのチェック方法とエラーチェックの処理方法が大幅に変更されます。また、4,000行以上のコードのモノリシックブロックではなく、コードを個別のPython関数に分割し始めました。私はそれを上げて、Flaskプログラミングもすべて含めます。
このプロジェクトは、プログラミング、Pi、Arduinoについて多くのことを教えてくれました。
プール制御システム– InternalPool制御システム–外部
出典: プールフィルコントロール
製造プロセス