initはどのように電源イベントを知るのですか?


8

私はPi Model B Rev 2.0(私は思う)を持っていますが、それをホームオートメーションシステムに使用するつもりです。電力供給に前払いメーターがあるので、時々電子が足りなくなり、家の主電源を回ります。

問題を回避するために、私はPiModulesによって作成されたUPis Basicの形式でUPSを入手しました。Piのシリアルポートを介して供給電圧をポーリングできるように構成しました(デフォルトの構成ではなく、マニュアルに記載されているサポートされているセットアップ)。

現在、専用のGPIOピン(ヘッダーのピン13、GPIO27と思います)を使用しており、組み込みのマイクロコントローラーがそれとrc.localから実行されているpythonスクリプトを使用してshutdown -h now、ピンがローになったことをPiに通知します-これは、UPSの「シャットダウン」ボタンが押されたとき、または主電源に障害が発生したときにバッテリー電源が非常に低下したときに発生します。記録のために、スクリプトは次のとおりです。

#!/usr/bin/python

# import the  libraries to use time delays, send os commands and access GPIO pins
import PRi.GPIO as GPIO
import time
import os

GPIO.setmode(GPIO.BCM) # Set pin numbering to board numbering
GPIO.setup(27, GPIO.IN, pull_up_don=GPIO.PUD_UP) # Setup pin 27 as an input
while True: # Setup a whille loopto wait for a button press
    if(GPIO.input(27)==0): # Setup an if loop to run a shutdown command when button press sensed
        os.system("sudo shutdown -h now") # Send shutdown command to os
        break
    time.sleep(1) # Allow a sleep time of 1 second to reduce CPU usage

これinitは、電源イベントを処理する組み込み機能を備えていることを考えると、少しエレガントではないように思えます。私は、Raspbian JessieでsysVinitを使用していることを繰り返します。そのリリースのデフォルトのsystemdではありません(個人的な好みと親しみやすさの理由から)。

最初に、上記のスクリプトをpowerfailnow、ピンがローになったときにそれを実行し、その後ピンがpowerokwaitハイに戻った場合に実行するようにinitに指示するものに置き換えたいと思います。結局私は、シリアルポートをポーリングし、への応答に目を維持したい@rpi@bat@upsPiは上の警告を与えることができますので、 -そのそれぞれパイの5Vレール、リポバッテリーとUPis自身のmicroUSB入力に直流電圧を返します/ handle電源障害(これによりpowerfailinitアクションが発生し、Piが電源喪失状態をユーザーに報告する必要があります-私はまだ気づいていないと想定しています!)

しかし、Linux UPSデバイスがで定義されinitpowerfail\ powerwait\ powerfailnow\ powerokwaitコマンドを実行する\etc\inittab必要があることを通知する方法を見つけるのが困難です。

たとえば、「成長した」UPSが「電源」イベントが発生していることを通常のPCのLinuxカーネルにどのように伝え、Pi上のこのシステムで同じように再現できるかを誰かに教えてもらえますか?


この質問のPython風の部分にタグがないことを見つけてくれて@ Jacobm001に感謝します。ここ数時間で、言語の短期集中コースを受講しました(少し前に進んでいます)が、少し前に肘から私のAspを知ら
なかった

また、Pi(またはinit)が電源イベントをどのように認識するかについても知りたいです。うまくいけば誰かがすぐに答えます。
PNDA

私はacpidを調べて、毎秒値をポーリングする代わりに、何かが変化したときに反応するようにスクリプトを変更できます(ピンが高->低)。
Diederik de Haas

2
@ PandaLion98 Piハードウェアには電源イベントがないため、それらについて知られていることは何もありません。いくつかが実装されている場合、カーネルは(piの場合はおそらくいくつかの追加ハードウェアのドライバーとなるドライバーイベントのため)またはユーザーランドアプリケーションを介して通知された場合にのみ、initがそれらについて知ることになります。
ゴルディロックス

回答:


5

ああ、ハ!のmanページのいくつかの段落は、1文字の値を書き込んで(現在はに置き換えられます)、シグナルを送信するinit(8)という減点されたインターフェースを示しています。手紙は次のいずれかである必要があります。/etc/powerstatus/var/run/powerstatusinitSIGPWR

  • ' F '停電:[主電源に障害が発生し、] UPSが電力を供給しています。powerwaitおよびを実行してくださいpowerfail
  • パワー ' O 'ケイ:[メイン]パワーが回復しました、powerokwaitエントリを実行します。
  • ' L ' ow power:電源に障害があり、UPSのバッテリが[非常に]低くなっていますpowerfailnow。エントリを実行してください。
指定されたファイルが存在しないか、文字FOまたは以外のものを含んでいる場合L、initは文字を読み取ったかのように動作しFます。

これの下は勧告です:

SIGPWRおよびの使用/etc/powerstatusはお勧めしません。やり取りしたい人initは、/run/initctlコントロールチャネルを使用する必要がありsysvinitます。これについての詳細は、パッケージのソースコードを参照してください。

これは可能かもしれないがだから、答えになっていない答え-次の、私はでホストされている非GNUプロジェクトとして保持されたソースコードを見る必要がGNUのホスティングサイト


1

最もクリーンなアプローチは、カーネルデバイスドライバーでGPIO27を管理し、ローになったときに割り込みを受信するように設定することです。割り込みハンドラはinitに通知します。ページhttp://elinux.org/RPi_Low-level_peripheralsによると、Raspbian WheezyはGPIO割り込みをサポートしています。

低品質の応答をお詫び申し上げます。Linuxのgpioドライバー、およびそれらを拡張/拡張する方法についてはまだ説明していません。また、割り込みハンドラ内からinitに通知するために現在承認されている方法についても調べていません。うまくいけば、この投稿がより良い反応を刺激するでしょう。


ええ、割り込みはポーリングよりも良いように見えます-ディーデリク・デ・ハースは上記で述べました。現在の私の調査の焦点は「割り込みハンドラーがinitに通知する...」ですが、それは不可解なメカニズムであり、powerstatファイル/ SIGPWR信号は比較的単純で単純に見えますが、推奨されないようです。私は今、initctlパイプの実際の使用法について
調べよ

1

initFree Software FoundationのSavannahサーバーから入手できるSysVのソースコードを詳しく調べることで、ヘッダーファイルに詳細をinit入力することで、RPiにリクエストを送信できました。具体的には、これにはと、私の目的ではフィールドに入力する必要があり、後者はまたはのいずれかに設定されます。struct init_requestinitreq.hmagicsleeptimecmdINIT_CMD_POWERFAILINIT_CMD_POWERFAILNOWINIT_CMD_POWEROK

init制御パイプへの書き込み権限を持つユーザーとして実行する必要がある私のデーモン/プログラム{もともとは/dev/initctrlDebianに移動したため、Raspbianに/run/initctrl}は、その構造を送信でき、initそれに応答して適切に応答しました。次のエントリ/etc/inittab

# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop

注:このインターフェース、または少なくとも電源の通知は、新しいfangledでは採用されていませんsystemd-たとえ、少しのカーゴカルトプログラミングと見なされるものでも、initctrlパイプが存在することを確認しようとします。一方で、これは私のRPiシステムで実行したいことを正確に実行します!


私はあなたのこの問題への献身に感心しますが、最初のスクリプトと機能的に同等で将来の証明とは言えないソリューションを実装するためにかなりの時間を費やしていることに気づかざるを得ません。
Dmitry Grigoryev 2017年

機能的には初期システムと同等ですが、非推奨のものではなく、推奨される提供インターフェースを使用します。将来の証明については、将来のシステムを作成する人が、可能な限り後方互換性を確保するために取って代わろうとしているシステムの既知のインターフェースを実装するのはそうではありません。
SlySven 2017年

結局のところ、UPSを備えたシステムにとって主電源障害の通知を受け取ることは非常に重要です。そのため、適切なプロセス/システム管理者は、前任者がどのように処理したかを認識し、そのAPIを使用する他のプロセスに注意する必要があります。存在しますが無視されますが少し近視眼的です... 8- / github.com/systemd/systemd/blob/master/src/initctl/initctl.cのコードによると 、すべてのUPS systemdは主電源が失敗したことを通知していますこのようにすると、「UPS /電源のinitctlリクエストを受信しました。これはsystemdには実装されていません。UPSデーモンをアップグレードしてください!」というログメッセージが記録されます。
SlySven 2017年

「これはsystemdには実装されていません。UPSデーモンをアップグレードしてください」-Linuxの下位互換性について知っておくべきことはこれだけです;)
Dmitry Grigoryev

initctlバンSmoorenburgのINITへのインタフェースは、第三者のためにプライベートではないと宣言されたプログラムのの一つで(当時)メンテナは2012年ミケルバンSmoorenburgのバックpowerd、後にトム・ウェブスターのgenpowerd、最初に使用/etc/powerstatusメカニズムを。
JdeBP
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.