ich nutze Zuhause einen Mehrfachsteckdose welche über USB steuerbar ist.
Dafür wurde auch hier ein entsprechendes Linux-Python-Modul geschrieben welches ich auf einem raspberry pi nutze:
https://sourceforge.net/p/sispmctl/git/ ... s/sispm.py
Das habe ich als Vorlage genommen und dann für mich umgearbeitet.
Code: Alles auswählen
# dev=sispm.Sispm() # Get first available device.
# dev.set_switch(1,False) # Switch second outlet off.
# print dev.status(2) # Print status of third outlet.
import json
import usb, struct, sys
VENDOR_ID = 0x04B4
PRODUCT_ID_SISPM = 0xFD11
PRODUCT_ID_MSISPM_OLD = 0xFD10
PRODUCT_ID_MSISPM_FLASH = 0xFD12
PRODUCT_ID_MSISPM_FLASH_NEW = 0xFD13
class SispmException(Exception):
pass
class Sispm:
def __init__(self, switch_id, ip, logging_daemon, queue, num=0):
self.switch_id = switch_id
self.ip = ip
self._logging_daemon = logging_daemon
self._queue = queue
cnt = 0
busses = usb.busses()
for bus in busses:
for device in bus.devices:
if device.idVendor == VENDOR_ID \
and device.idProduct in [PRODUCT_ID_SISPM,
PRODUCT_ID_MSISPM_OLD, PRODUCT_ID_MSISPM_FLASH,
PRODUCT_ID_MSISPM_FLASH_NEW]:
if num == cnt:
self.device = device
self.deviceHandle = self.device.open()
return
else:
cnt += 1
self._logging_daemon.info('SIS USB ....... initialisiert')
raise SispmException("Sispm device not found.")
def _usb_command(self, b1, b2, dir_in=False):
""" Send a usb command. """
if dir_in:
req = 0x01
reqtype = 0x21 | 0x80;
buf = 2
else:
req = 0x09
reqtype = 0x21 # USB_DIR_OUT+USB_TYPE_CLASS+USB_RECIP_INTERFACE
buf = struct.pack("BB", b1, b2)
try:
buf = self.deviceHandle.controlMsg(reqtype, req, buf, (0x03 << 8) | b1, 0, 500)
except AttributeError:
self._logging_daemon.info('SIS USB ....... Error - neuer Versuch ...')
buf = self.deviceHandle.controlMsg(reqtype, req, buf, (0x03 << 8) | b1, 0, 500)
self._logging_daemon.info('SIS USB ....... Error - neuer Versuch Erfolgreich')
if dir_in:
return buf[1] != 0
def _check_outlet(self, num):
if num < 0 or num >= self.get_num_outlets():
raise SispmException("Outlet %d doesn't exist on this device." % num)
def set_switch(self, switch_to, arg_a, arg_b, arg_c, arg_d):
self._check_outlet(int(arg_a)-1)
self._usb_command(3 * int(arg_a), {False: 0x00, True: 0x03}[switch_to])
self._logging_daemon.debug(
'SIS USB ....... geschaltet Relais %s , SOLL = %s , IST = %s' % (arg_a, switch_to, self.status(arg_a)))
tmp_json = json.dumps({
"usage": "switch_changed_status",
"ip": self.ip,
"id": self.switch_id,
"value": switch_to
})
for consumer in self._queue:
consumer(tmp_json)
self._logging_daemon.info(
'SIS USB ....... Relais %s , send %s -> SocketServer Warteschlange ' % (arg_a, self.status(arg_a)))
def status(self, number):
self._check_outlet(int(number)-1)
return self._usb_command(3 * int(number), 0x03, True)
def set_buzzer_enabled(self, onoff):
self._usb_command(1, {False: 0x00, True: 0x03}[onoff])
def get_num_outlets(self):
if self.device.idProduct in \
[PRODUCT_ID_MSISPM_OLD, PRODUCT_ID_MSISPM_FLASH]:
return 1
elif self.device.idProduct in \
[PRODUCT_ID_SISPM, PRODUCT_ID_MSISPM_FLASH_NEW]:
return 4
else:
return None
Code: Alles auswählen
Traceback (most recent call last):
File "sh-client.py", line 246, in <module>
asyncio.get_event_loop().run_until_complete(client_handler())
File "/usr/local/lib/python3.4/asyncio/base_events.py", line 316, in run_until_complete
return future.result()
File "/usr/local/lib/python3.4/asyncio/futures.py", line 275, in result
raise self._exception
File "/usr/local/lib/python3.4/asyncio/tasks.py", line 238, in _step
result = next(coro)
File "sh-client.py", line 90, in client_handler
message_handler(message_received)
File "sh-client.py", line 112, in message_handler
switches_info[message_id, "argD"])
File "/sourcecode/lib_sispm.py", line 69, in set_switch
self._usb_command(3 * int(arg_a), {False: 0x00, True: 0x03}[switch_to])
File "/sourcecode/lib_sispm.py", line 58, in _usb_command
buf = self.deviceHandle.controlMsg(reqtype, req, buf, (0x03 << 8) | b1, 0, 500)
File "/usr/local/lib/python3.4/site-packages/usb/legacy.py", line 205, in controlMsg
timeout = timeout)
File "/usr/local/lib/python3.4/site-packages/usb/core.py", line 962, in ctrl_transfer
self._ctx.managed_claim_interface(self, interface_number)
File "/usr/local/lib/python3.4/site-packages/usb/core.py", line 146, in managed_claim_interface
self.backend.claim_interface(self.handle, i)
File "/usr/local/lib/python3.4/site-packages/usb/backend/libusb1.py", line 747, in claim_interface
_check(self.lib.libusb_claim_interface(dev_handle.handle, intf))
File "/usr/local/lib/python3.4/site-packages/usb/backend/libusb1.py", line 552, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
File "/usr/local/lib/python3.4/site-packages/usb/backend/libusb1.py", line 541, in _strerror
return _lib.libusb_strerror(errcode).decode('utf8')
File "/usr/local/lib/python3.4/ctypes/__init__.py", line 364, in __getattr__
func = self.__getitem__(name)
File "/usr/local/lib/python3.4/ctypes/__init__.py", line 369, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/arm-linux-gnueabihf/libusb-1.0.so.0: undefined symbol: libusb_strerror
Task was destroyed but it is pending!
task: <Task pending coro=<sending_loop() running at sh-client.py:57> wait_for=<Future pending cb=[Task._wakeup()]>>
Task was destroyed but it is pending!
task: <Task pending coro=<run() running at /usr/local/lib/python3.4/site-packages/websockets/protocol.py:395> wait_for=<Future pending cb=[Task._wakeup()]>>
2016-04-27 01:15:00 : websockets .... consumers.remove
Exception ignored in: <generator object sending_loop at 0xb6021b20>
Traceback (most recent call last):
File "sh-client.py", line 63, in sending_loop
File "/usr/local/lib/python3.4/logging/__init__.py", line 1274, in info
File "/usr/local/lib/python3.4/logging/__init__.py", line 1409, in _log
File "/usr/local/lib/python3.4/logging/__init__.py", line 1419, in handle
File "/usr/local/lib/python3.4/logging/__init__.py", line 1481, in callHandlers
File "/usr/local/lib/python3.4/logging/__init__.py", line 853, in handle
File "/usr/local/lib/python3.4/logging/__init__.py", line 1040, in emit
File "/usr/local/lib/python3.4/logging/__init__.py", line 1030, in _open
NameError: name 'open' is not defined
Es ist egal ob ich eine Steckdose an- oder ausschalte, ob ich sie abfrage und es ist auch egal welche Steckdose es ist.
Manchmal passiert es nach 2-3 x Schaltvorgängen, manchmal erst nach 10-12 x Schaltvorgängen.
Zum Teil hilft es das Programm einfach neuzustarten, manchmal muss ich aber auch den gesamten raspberry pi neu starten.
Ich habe natürlich schon mal im Internet gesucht und es scheint ein Problem im python-usb-modul zu sein.
Das ganze ist sehr ärgerlich, weil so ist die Steckdose einfach viel zu unzuverlässig.
Deshalb wollte ich mal fragen ob hier jemand eine Idee hat?
Ich habe schon versucht den Fehler abzufangen und den Befehl dann direkt nochmal neu abzusetzen.
Das hat leider nicht funktioniert und deshalb brauche ich jetzt Hilfe ....
