cwietov Napisano Wrzesień 2, 2021 Udostępnij Napisano Wrzesień 2, 2021 Cześć, mam pytanie dotyczące wywoływania skryptów napisanych w Pythonie na Raspberry Pi z poziomu Domoticza. Mianowicie, mam listwę LEDową sterowaną skryptami napisanymi w Pythonie. Skrypty wymagają bibliotek NeoPixel. Chciałbym móc wykorzystać owe skrypty z poziomu Domoticza, by móc to wszystko dodatkowo zautomatyzować i stworzyć np. jakieś sceny. Czy istnieje taka możliwość? Spędziłem już nad tym X czasu, przejrzałem Internet wydaje się we wszystkie strony i niestety nic nie znalazłem. Zagadnienie wydaje się być banalne. W tym momencie zrobiłem to na zasadzie przycisku wirtualnego, gdzie w polu aktywacji podaje lokalizację skryptu włączającego LEDy, a w polu wyłączenia skrypt wyłączający. Jednakże to rozwiązanie nie działa i w patrząc na logi widzę, że dostaje błąd "256" (Error: Error executing script command (/home/pi/domoticz/scripts/python/led_blue.py). returned: 256). Internet nie jest niestety zbytnio pomocny w tym temacie. Wydaje się, że nadałem wszelkie możliwe uprawienia. Czy jest na to jakaś metoda? Może podchodzę do tego tematu błędnie? Będę wdzięczny za wszelkie wskazówki! W załączniku zrzut ekranu przycisku wirtualnego z podaną lokalizacją skryptu (bez skrypty wyłączającego, ale to już analogia). Link do komentarza Share on other sites More sharing options...
Gieneq Wrzesień 3, 2021 Udostępnij Wrzesień 3, 2021 (edytowany) @cwietov w tym roku coś podobnego robiłem, ale mam tego skryptu pod ręką 😞 Idea jest taka że korzystasz z API. Tak jak robisz: piszesz skrypt w Pythonie i nawet zwykły polling się nada - co jakiś czas sprawdzasz co jest wystawione w api dla tego modułu kontrolera RGB. Pamiętam że było kilka modułów do RGB, u mnie działał taki zbudowany na dummy: Pamiętam że znalezienie liniki do API, gdzie miałeś tego JSONa z nastawami kontrolera nie było takie oczywiste, trzeba było poczytać jakie parametry są używane w danych kontrolerach. Wiem że to mało precyzyjna odpowiedź, jak niezbyt pomoże to pomyślimy co dalej 🙂 Edytowano Wrzesień 3, 2021 przez Gieneq Link do komentarza Share on other sites More sharing options...
cwietov Wrzesień 3, 2021 Autor tematu Udostępnij Wrzesień 3, 2021 (edytowany) Dzięki za odpowiedź 🙂 "Moduły" chodzi o moduły Domoticza czy hardware? Trochę nie do końca rozumiem, jak mógłbym się za to zabrać. W sensie z tego co zrozumiałem nie ma opcji tak po prostu wywołania skryptu żeby się wykonał? Czyli, żeby LEDy się właśnie włączyły lub wyłączyły. Póki co kontrola parametrów świecenia w pełnym spectrum, aż tak bardzo mnie nie interesuje. Chce po prostu jakoś wywołać skrypt bo wiem, że jakoś można, tylko właśnie jak najlepiej? 😄 Bo tu niestety dostaje błędy. Jak próbuje wywołać skrypt przez inny skrypt to nie dostaje błędu, ale nic się nie dzieje. Jaki jest najlepszy sposób w Pythonie wywołania skryptu w skrypcie? W sensie żeby napisać skrypt, który będzie wywoływał skrypt włączający LEDy itd. Może tutaj tkwi jakiś problem i tędy droga. Edytowano Wrzesień 3, 2021 przez cwietov Link do komentarza Share on other sites More sharing options...
Gieneq Wrzesień 6, 2021 Udostępnij Wrzesień 6, 2021 @cwietov dobra odkopałem maline i mam skrypty, przeklejam cały kod bo może coś cie w nim zainspiruje. Ten pierwszy ma funkcję do pobrania wartości z kontrolera domoticza: #!/usr/bin/python3 import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) from urllib.request import urlopen from urllib.error import URLError import threading import json import re import ast import time serverIP = "192.168.0.12:8080" dummy_rgb_id = 22 url = "http://" + serverIP + "/json.htm?type=devices&rid=" + str(dummy_rgb_id) pin_button = 22 ########################## pin_segment_s1 = 25 pin_segment_s2 = 23 pin_segment_s3 = 24 pin_segment_ss = 7 pin_segment_a = 5 pin_segment_b = 21 pin_segment_c = 25 pin_segment_d= 26 pin_segment_e = 19 pin_segment_f = 20 pin_segment_g = 12 pin_segment_dp = 13 value_display = 888 ########################## import board import neopixel PIEXELS_COUNT=1 pixels = neopixel.NeoPixel(board.D18, PIEXELS_COUNT, brightness=1.0, auto_write=False) ########################## def updateColorValues(): global brightness global red global green global blue while True: print("Acquiring colour data...") try: response = urlopen(url) # Convert bytes to string type and string type to dict string = response.read().decode('utf-8') json_obj = json.loads(string) brightnessRaw = json_obj['result'][0]['Status'] paresedBrightness = re.findall(r'\d+', brightnessRaw) if len(paresedBrightness) > 0: brightness = int(paresedBrightness[0]) colorRaw = json_obj['result'][0]['Color'] # print(colorRaw) color = ast.literal_eval(colorRaw) # print(color) red = color['r'] green = color['g'] blue = color['b'] print("Get: {}, {}, {}, brightness {}".format(red, green, blue, brightness)) pixels.brightness = float(brightness / 100.0) pixels.fill((red, green, blue)) pixels.show() time.sleep(0.5) except URLError as e: print('Meh HTTPError = ' + str(e) + " trying to reconnect in 5 seconds...") time.sleep(5) except Exception: import traceback print('generic exception: ' + traceback.format_exc()) if __name__ == "__main__": red = 255 green = 0 blue = 0 brightness = 255 GPIO.setup(pin_segment_s1, GPIO.OUT) GPIO.output(pin_segment_s1, GPIO.LOW) GPIO.setup(pin_segment_s2, GPIO.OUT) GPIO.output(pin_segment_s2, GPIO.HIGH) GPIO.setup(pin_segment_s3, GPIO.OUT) GPIO.output(pin_segment_s3, GPIO.HIGH) GPIO.setup(pin_segment_ss, GPIO.OUT) GPIO.output(pin_segment_ss, GPIO.HIGH) GPIO.setup(pin_segment_a, GPIO.OUT) GPIO.output(pin_segment_a, GPIO.LOW) GPIO.setup(pin_segment_b, GPIO.OUT) GPIO.output(pin_segment_b, GPIO.LOW) GPIO.setup(pin_segment_c, GPIO.OUT) GPIO.output(pin_segment_c, GPIO.LOW) GPIO.setup(pin_segment_d, GPIO.OUT) GPIO.output(pin_segment_d, GPIO.LOW) GPIO.setup(pin_segment_e, GPIO.OUT) GPIO.output(pin_segment_e, GPIO.LOW) GPIO.setup(pin_segment_f, GPIO.OUT) GPIO.output(pin_segment_f, GPIO.LOW) GPIO.setup(pin_segment_g, GPIO.OUT) GPIO.output(pin_segment_g, GPIO.LOW) GPIO.setup(pin_segment_dp, GPIO.OUT) GPIO.output(pin_segment_dp, GPIO.LOW) threadUpdateColours = threading.Thread(target=updateColorValues) threadUpdateColours.start() while True: GPIO.output(pin_segment_s1, GPIO.LOW) time.sleep(1) GPIO.output(pin_segment_s1, GPIO.HIGH) time.sleep(1) GPIO.cleanup i pomiary z Dallasem i przetwornikiem ADS: #!/usr/bin/python3 import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) import Adafruit_ADS1x15 from w1thermsensor import W1ThermSensor import subprocess import time import os from bs4 import BeautifulSoup import urllib3 pin_sens_enable = 17 pin_indicator = 27 ################### serverIP = "192.168.0.12:8080" dummy_core_temp_id = 8 coreTemperatureValue = 10.0 dummy_outside_temp_id = 18 outsideTemperature = 15.0 ################### adc = Adafruit_ADS1x15.ADS1115() adc_channels = 4 adc_gain = 1 adc_values = [0]*4 sensors_count = 4 sensors = [{"name" : "None", "minValADC" : 1000, "maxValADC" : 50000, "val" : 0} for x in range(sensors_count)] LIGHT = 0 sensors[LIGHT]["name"] = "Light" sensors[LIGHT]["minValADC"] = 100.0 sensors[LIGHT]["maxValADC"] = 30000.0 HUM1 = 1 sensors[HUM1]["name"] = "Hum1" sensors[HUM1]["minValADC"] = 20500.0 sensors[HUM1]["maxValADC"] = 9000.0 HUM2 = 2 sensors[HUM2]["name"] = "Hum2" sensors[HUM2]["minValADC"] = 21500.0 sensors[HUM2]["maxValADC"] = 13000.0 HUM3 = 3 sensors[HUM3]["name"] = "Hum3" dummy_hum1_id = 19 dummy_hum2_id = 20 dummy_hum3_id = 21 dummy_light_sens_id = 14 http = urllib3.PoolManager() def rescaleValues(): for i in range(sensors_count): sensor = sensors[i] a = 100.0/(sensor["maxValADC"] - sensor["minValADC"]) b = 100.0 - a * sensor["maxValADC"] temp_value = a * adc_values[i] + b if temp_value < -100.0: temp_value = -100.0 if temp_value > 100.0: temp_value = 100.0 if temp_value < 0.0: temp_value = -temp_value sensor["val"] = temp_value def scanADC(): for i in range(adc_channels): adc_values[i] = adc.read_adc(i, gain=adc_gain) rescaleValues() def measure_core(): coreTemperature = subprocess.check_output(["/opt/vc/bin/vcgencmd", "measure_temp"]) return float(coreTemperature.decode().split("=")[1][:-3]) # API: https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s def sendLightSenor(deviceId, name, value, rawValue): trimedValue = round(value, 1) print("Sending light sensor... {}: {} / {} to device: {}".format(name, trimedValue, rawValue, deviceId)) url = "http://" + serverIP + "/json.htm?type=command¶m=udevice&idx=" + str(deviceId) + "&svalue=" + str(trimedValue) return http.request('GET', url) def sendHumiditySensor(deviceId, name, value, rawValue): trimedValue = round(value, 1) print("Sending humidity sensor... {}: {} / {} to device: {}".format(name, trimedValue, rawValue, deviceId)) url = "http://" + serverIP + "/json.htm?type=command¶m=udevice&idx=" + str(deviceId) + "&nvalue=" + str(trimedValue) return http.request('GET', url) def sendTemperature(deviceId, name, value): trimedValue = round(value, 1) print("Sending temeprature... {}: {} to device: {}".format(name, trimedValue, deviceId)) url = "http://" + serverIP + "/json.htm?type=command¶m=udevice&idx=" + str(deviceId) + "&svalue=" + str(trimedValue) return http.request('GET', url) def send_data(coreTmp): print("Sending data:") sendLightSenor(dummy_light_sens_id, sensors[LIGHT]["name"], sensors[LIGHT]["val"], adc_values[LIGHT]) sendHumiditySensor(dummy_hum1_id, sensors[HUM1]["name"], sensors[HUM1]["val"], adc_values[HUM1]) sendHumiditySensor(dummy_hum2_id, sensors[HUM2]["name"], sensors[HUM2]["val"], adc_values[HUM2]) sendHumiditySensor(dummy_hum3_id, sensors[HUM3]["name"], sensors[HUM3]["val"], adc_values[HUM3]) sendTemperature(dummy_core_temp_id, "CoreTemp", coreTemperatureValue) sendTemperature(dummy_outside_temp_id, "OutsideTemp", outsideTemperature) if __name__ == "__main__": GPIO.setup(pin_indicator, GPIO.OUT) GPIO.setup(pin_sens_enable, GPIO.OUT) # do stuff GPIO.output(pin_sens_enable, GPIO.HIGH) GPIO.output(pin_indicator, GPIO.HIGH) time.sleep(2) # read sensors sensor = W1ThermSensor() outsideTemperature = sensor.get_temperature() scanADC() coreTemperatureValue = measure_core() GPIO.output(pin_indicator, GPIO.LOW) GPIO.output(pin_sens_enable, GPIO.LOW) send_data(coreTemperatureValue) time.sleep(5) GPIO.cleanup # "http://192.168.0.12:8080/json.htm?type=command¶m=udevice&idx=19&nvalue=0&svalue=2" # http://192.168.0.12:8080/json.htm?type=devices&rid=19 # http://192.168.0.12:8080/json.htm?type=devices&rid=22 # blink_thread = threading.Thread(target=cycle_task) # blink_thread.start() # while(1): # pass # url = "http://" + serverIP + "/json.htm?type=command¶m=udevice&idx=" + str( # dummy_light_sens_id) + "&nvalue=0&svalue=" + str(sensors[0]["val"]) # response = http.request('GET', url) # soup = BeautifulSoup(response.data) # global green Czyli 🌶️ patrząc na początek na ten fragment: serverIP = "192.168.0.12:8080" dummy_rgb_id = 22 url = "http://" + serverIP + "/json.htm?type=devices&rid=" + str(dummy_rgb_id) Tu masz adres Domoticza i port z którym się komunikujesz - adres będziesz miał podobny ale inny. Skrypt i serwer Domoticza działają na jednym RPi. Kolejna linia to id kontrolera - dopisałem dummy bo to jest wirtualny element wykonawczy, czyli taki który operuje na samym kodzie ale nic sie w praktyce nie rusza/świeci/odczytuje itp. Najpierw w panelu robisz dummy hardware a do niego doczepiasz device np taki kontroler RGB. To chyba jest opisane w kursie. Na koniec jest linijka wynikająca z API Domoticza służąca do dostępu do plików związanych z kontrolerem (mam tu na myśli coś z panelu np. dummy RGB). import board import neopixel PIEXELS_COUNT=1 pixels = neopixel.NeoPixel(board.D18, PIEXELS_COUNT, brightness=1.0, auto_write=False) ########################## def updateColorValues(): global brightness global red global green global blue while True: print("Acquiring colour data...") try: response = urlopen(url) # Convert bytes to string type and string type to dict string = response.read().decode('utf-8') json_obj = json.loads(string) brightnessRaw = json_obj['result'][0]['Status'] paresedBrightness = re.findall(r'\d+', brightnessRaw) if len(paresedBrightness) > 0: brightness = int(paresedBrightness[0]) colorRaw = json_obj['result'][0]['Color'] # print(colorRaw) color = ast.literal_eval(colorRaw) # print(color) red = color['r'] green = color['g'] blue = color['b'] print("Get: {}, {}, {}, brightness {}".format(red, green, blue, brightness)) pixels.brightness = float(brightness / 100.0) pixels.fill((red, green, blue)) pixels.show() time.sleep(0.5) except URLError as e: print('Meh HTTPError = ' + str(e) + " trying to reconnect in 5 seconds...") time.sleep(5) except Exception: import traceback print('generic exception: ' + traceback.format_exc()) Może to wyglądać na trudne ale ten kod jest bardzo prosty. Na początku obiekt związany z paskiem LED, później pętla i blok przechwytywania wyjątków jakby zerwalo się połaczenie. To wszystko kręci się w osobnym wątku. Wewnątrz pobierane są dane z API - Domoticz wystawia plik JSON z którego odczytujesz sobie aktualny stan kontrolera. Jest to więc typowy polling - sprawdzasz cyklicznie czy coś się zmieniło. Oczywiście da się to zrobić inaczej, da się nauczyć LUA, napisać skrypt Domoticza, coś w tym wydziergać ale i tak nie jest źle. Tylko to nie jest zabawa niejeden wieczór... ja chyba spędziłem przy tym z kilka godzin, przy czym znałem już dość dobrze Pythona, tematy webowe i konfiguracje sprzętu w Domoticzu 😞 więc cóż, good luck! 1 1 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
cwietov Wrzesień 9, 2021 Autor tematu Udostępnij Wrzesień 9, 2021 Dzięki wielkie za tak obszerną odpowiedź wraz z kodem! 🙂 Przysiądę pewnie do tego w weekend i ogarnę co i jak, ale tak na pierwszy rzut oka już widzę, że może być to dla mnie bardzo pomocne i w rzeczy samej rozwiązać mój problem. Dzięki raz jeszcze! 🙂 Link do komentarza Share on other sites More sharing options...
Gieneq Wrzesień 10, 2021 Udostępnij Wrzesień 10, 2021 @cwietov powodzenia 🙂 tk popatrzyłem na gten kod i samo API jednak nie jest takie łatwe, pamiętam że długo szukałem może prostej sprawy ale gdzie jest svalue a gdzie coś innego: ram=udevice&idx=" + str(deviceId) + "&svalue=" Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »