Skip to content

JavaScript

Hilfe für Skripterstellung mit JavaScript

2.5k Topics 48.9k Posts

NEWS

  • Please move the states to 0_userdata.0.*

    Moved
    56
    0 Votes
    56 Posts
    7k Views
    A
    @apollon77 @RaBu60 ich denke das ist dasselbe verhalten über das ich gerade gestolpert bin. Hoffe mein issue dazu passt soweit https://github.com/google/blockly/issues/7232
  • In einer Funktion auf Änderung eines Datenpunkts warten

    8
    0 Votes
    8 Posts
    550 Views
    ?
    @paul53 Danke für die Überarbeitung. Das sieht doch wesentlich kompakter aus :+1: Ja, toLog() ist eine globale Funktion, die mir eine Aktivitätsliste füllt und gleichzeitig einen Log-Eintrag erstellt. Da neben der Steuerung des Tors in dem eigentlichen Script noch die Regelung eines Lüfters drin ist, hier mal der aktuelle Stand des gesamten Scripts: /* ** ** Steuerung Garage ** */ var cronVal = '*/15 * * * *'; var numMinDuration = 30; var dpAussenTemperatur = 'hm-rpc.0.00XXXXXXXXXXEF.1.ACTUAL_TEMPERATURE'; var dpAussenFeuchtigkeit = 'hm-rpc.0.00XXXXXXXXXXEF.1.HUMIDITY'; var dpGarageFeuchtigkeit = 'hm-rpc.0.00XXXXXXXXXX5F.1.HUMIDITY'; var dpGarageLuefter = 'hm-rpc.0.00XXXXXXXXXX9D.3.STATE'; const dpGarageDoorOpen = '0_userdata.0.Trigger.TriggerGarageDoorOpen'; const dpGarageDoorClose = '0_userdata.0.Trigger.TriggerGarageDoorClose'; const dpGarageDoorStatus = '0_userdata.0.Trigger.TriggerGarageDoorStatus'; const dpGarageDoorState = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_STATE'; const dpGarageDoorCommand = 'hm-rpc.0.00XXXXXXXXXXF7.1.DOOR_COMMAND'; var doorState = getState(dpGarageDoorState).val; /* ** Create Datapoints */ createState(dpGarageDoorOpen, false, { name: 'TriggerGarageDoorOpen', desc: 'TriggerGarageDoorOpen', type: 'boolean', role: 'state' }); createState(dpGarageDoorClose, false, { name: 'TriggerGarageDoorClose', desc: 'TriggerGarageDoorClose', type: 'boolean', role: 'state' }); createState(dpGarageDoorStatus, '-', { name: 'TriggerGarageDoorStatus', desc: 'TriggerGarageDoorStatus', type: 'string', role: 'value' }); /* ** Subscriptions */ schedule(cronVal, function() { if(getState(dpGarageLuefter).val === false) { if(getState(dpGarageFeuchtigkeit).val > getState(dpAussenFeuchtigkeit).val) { if(getState(dpAussenTemperatur).val > 5) { if(getState(dpAussenTemperatur).val < 20) { var numMilSecsDur = numMinDuration * 60000; var endTime = Date.now() + numMilSecsDur; setState(dpGarageLuefter, true); toLog('Garagenbelüftung eingeschaltet (Dauer: ' + numMinDuration + ' - Lf: ' + getState(dpGarageFeuchtigkeit).val + '%)'); var sHandler = schedule(endTime, function () { setState(dpGarageLuefter, false); toLog('Garagenbelüftung ausgeschaltet (Lf: ' + getState(dpGarageFeuchtigkeit).val + '%)'); clearSchedule(sHandler); }); } } } } }); on ({id: dpGarageDoorOpen, change: 'ne', val: true}, function () { if(doorState != 1) { setState(dpGarageDoorCommand, 1); setState(dpGarageDoorStatus, 'wird geöffnet', true); } setState(dpGarageDoorOpen, false, true); }); on ({id: dpGarageDoorClose, change: 'ne', val: true }, function () { if(doorState > 0) { setState(dpGarageDoorCommand, 3); setState(dpGarageDoorStatus, 'wird geschlossen', true); } setState(dpGarageDoorClose, false, true); }); on (dpGarageDoorState, function (dp) { doorState = dp.state.val; let msg = ''; if(doorState === 0) { msg = 'geschlossen'; } else if(doorState === 1) { msg = 'offen'; } if(msg) { setState(dpGarageDoorStatus, msg, true); toLog('Das Garagentor ist ' + msg); } }); Vielleicht kann der eine oder andere davon etwas gebrauchen. Viele Grüße Levy
  • Hue Panel mit HmIP Schalter

    14
    0 Votes
    14 Posts
    807 Views
    P
    @paul53 Das heißt, ich setze den HmIP-Schalter zwar unter Strom (damit er empfängt und sendet), trenne die Hue vom Schalter und bypasse die Hue auf "ständig Strom". Und anschließend dann dein Script (bei mir sind es Alias-DP) für das harte Schalten, wenn einer der Taster analog bedient wird. Alles klar, jetzt habe ich es verstanden. Besten Dank für deine Mühe!!
  • Verständnisfrage: Lineares Abarbeiten von Funktionen

    node-red javascript
    4
    2
    0 Votes
    4 Posts
    370 Views
    T
    @shai0hulud sagte in Verständnisfrage: Lineares Abarbeiten von Funktionen: Hichi-Lesekopf Das hab ich ehrlich gesagt aufgegeben. Ich mache das mit Grafana und Influx, die Anzeigen die etwas berechnen sind immer mindestens auf 1 Minute zusammengefasst. Bei Echtzeit werden nur Werte angezeigt und zwar nicht genug um nachrechnen zu können. Solarstrom - Einspeisung + Bezug - gemessener Verbrauch = sonstiger Verbrauch (- 2kw) wtf. Wer hat da ein ein paar Balkonkraftwerke auf gestellt :) Meine Aktualisisierungraten sind: SMA 1sec shelly 5 sec tasmota 10 sec (oder powerdelta) fritzboxDect(ne minute?)
  • MQTT Json

    9
    0 Votes
    9 Posts
    705 Views
    R
    Danke, so hat es jetzt auf Anhieb funktioniert. Jetzt werde ich mit dem Script noch etwas tüfteln.
  • [gelöst] shelly object.common.name lässt sich nicht ändern

    Moved
    9
    0 Votes
    9 Posts
    628 Views
    HomoranH
    @ticaki sagte in [gelöst] shelly object.common.name lässt sich nicht ändern: Aber am Ende hab ich durch verschieben was gelernt das ist ja der Sinn des Verschiebens Dadurch erreicht man die Leute wesentlichbesser, die da wirklich helfen können,
  • e3dc wallbox multi connect: modbus register

    3
    0 Votes
    3 Posts
    377 Views
    M
    @derfred ja, ich denke die Register rückt e3dc nicht raus. Schade, denn so kann man viel weniger selbst regelt. Vor allem, da einiges nicht optimal funktioniert.
  • Javaskript nur positive Ergebnisse anzeigen

    7
    0 Votes
    7 Posts
    344 Views
    T
    @paul53 said in Javaskript nur positive Ergebnisse anzeigen: function summe() { setState(idSumme, Math.max(solar + solarBatt, 0), true); } Ich glaube das war es .... danke allen!! Mal sehen was passiert, wenn morgen die Sonne scheint ;)
  • SQL Timeout von 15 sek erhöhen

    4
    0 Votes
    4 Posts
    423 Views
    T
    @thomassch Für die die die procedure interessiert USE [iobroker] GO /****** Object: StoredProcedure [dbo].[usp_CopyNewHoursValuesTable] Script Date: 22.06.2023 21:52:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Thomas Schatz -- Create date: 26.01.2023 -- Description: procedure für das Ermitteln der Differenzwerte pro Stunde -- ============================================= -- ein paar sammlungen von guten Abfragen -- --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy') as xYear, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM') as xMonth, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd') as xDay, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd HH') AS xLastDayHour, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd HH:mm:ss') AS xTimeSec, -- ============================================= -- VERSION -- V5.0 ... inklusive löschen der Werte in IOBroker Werte die älter sind als 1 Tag -- ALTER PROCEDURE [dbo].[usp_CopyNewHoursValuesTable] -- Add the parameters for the stored procedure here @ClearAll INT = 0, -- 1 == löscht die letzten x-Tage, -1 läöscht dann alle Werte in der Tabell usr_IOBroker_Werte komplett @RunWithoutCopy INT = 1, -- 1== es wird nur angezeigt aber nichts kopiert @Debug int = 0, -- bei 1 werden alle Debugs angezeigt @DebugOnlyObject varchar(100) ='', @MaxDays INT = 1,-- maximale Anzahl der zu kopierenden Werte, damit die Abfragezeit nicht zu gross wird @StartDate datetime = '', @EndDate datetime = '' AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- sicherstellen das die Procedure nicht 2x läuft (1x IOBeroker Script und einmal hier im SQL Exec) BEGIN TRANSACTION -- Insert statements for procedure here DECLARE @xStartDate DATETIME, @xStartDateMin DATETIME, @xEndDate DATETIME, @xNewestDate DATETIME, @xNewest_IOWerte DATETIME, @xOldest_tsNumber DATETIME, @xOldest_IOWerte DATETIME; DECLARE @xTempDateTime DATETIME, @xTemp_Datetime DATETIME; DECLARE @xTempBigInt BIGINT; DECLARE @xStartDateUNIX BIGINT, @xEndDateUNIX BIGINT DECLARE @RunTime DATETIME; DECLARE @NewAnzahl as int, @NewAnzahl1 as int; DECLARE @myId as int; DECLARE @bNewest as bigint; DECLARE @OldValuesCount as bigint, @OldValuesCountBeforeDelete as bigint, @NewValuesCount as bigint; Declare @xOldest_ref as bigint; DECLARE @xNewest_IOWerte_AddDays as datetime; DECLARE @CountAnzahl as int, @runtimestart as datetime; DECLARE @CurrentTime as bigint; -- wurd ein Filterobject übergeben set @myId=0 if (@DebugOnlyObject<>'') BEGIN Select 'Es wurde ein FilterObject übergeben' select @DebugOnlyObject Select @myId = id from datapoints where name=@DebugOnlyObject END -- Tabelle erstellen, falls nicht extiert IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usr_IOBroker_Werte]') AND type in (N'U')) BEGIN CREATE TABLE dbo.usr_IOBroker_Werte ( id int not NULL, create_ts bigInt, UnixTime bigint, min_ts bigint, max_ts bigint, Zaehler real, [DateTime] datetime, Diff real, CONSTRAINT IOBroker_WerteIndex UNIQUE (id,min_ts) ) CREATE NONCLUSTERED INDEX [NonClusteredIndex-Test_UNIXtime_ID] ON [dbo].[usr_IOBroker_Werte] ( [id] ASC, [UnixTime] DESC, [DateTime] DESC ) select 'Tabelle mit Index erstellt' END DROP TABLE IF EXISTS #tempWERTE01 CREATE TABLE #tempWERTE01 ( xRowCount int NOT NULL, xId int NOT NULL, xUnixTime bigint NOT NULL, min_ts bigint NULL, max_ts bigint NULL, xZaehler real NULL, CONSTRAINT tempWERTE01_Index UNIQUE (xid,xUnixTime) ) CREATE NONCLUSTERED INDEX ix_tempWERTE01 ON #tempWERTE01 ([xId],[xUnixTime] DESC); DROP TABLE IF EXISTS #tempWERTE02 CREATE TABLE #tempWERTE02 ( xId int NOT NULL, xUnixTime bigint NOT NULL, min_ts bigint NULL, max_ts bigint NULL, xZaehler real NULL, xDiff real NULL, CONSTRAINT tempWERTE02_Index UNIQUE (xid,xUnixTime) ) CREATE NONCLUSTERED INDEX ix_tempWERTE02 ON #tempWERTE02 ([xId],[xUnixTime] DESC,[min_ts]); -- falls die Tabelle geloescht werden soll if (@ClearAll=-1) BEGIN if (EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN if @Debug>0 Select 'IOBroker Werte (Alle) werden alle gelöscht TRUNCATE' if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte vor loeschen' from dbo.usr_IOBroker_Werte TRUNCATE TABLE dbo.usr_IOBroker_Werte if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte nach loeschen' from dbo.usr_IOBroker_Werte END END -- falls xTage von Tabelle geloescht werden sollen if (@ClearAll>0) BEGIN if (EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN if @Debug>0 Select 'IOBroker Werte (x-Tage) werden alle gelöscht TRUNCATE' if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte vor loeschen' from dbo.usr_IOBroker_Werte -- nun die x-Tage loeschen --select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte select @xTemp_Datetime=Dateadd(day,-@ClearAll,DATETIMEFROMPARTS(YEAR(@xNewest_IOWerte),MONTH(@xNewest_IOWerte),DAY(@xNewest_IOWerte),0,0,0,0)) select @xTempBigInt=DATEDIFF(SECOND,'01.01.1970 00:00:00.0',@xTemp_Datetime) if @Debug>0 Select @xNewest_IOWerte as 'Neuste Werte in Tabelle @xNewest_IOWerte=:' if @Debug>0 Select @xTemp_Datetime as 'Loesche alles Älter als@xTemp_Datetime=:' if @Debug>0 Select @xTempBigInt as 'Sekunden für Delete Abfrage @xTempBigInt=:' if @RunWithoutCopy=0 BEGIN DELETE from usr_IOBroker_Werte where UnixTime/1000>=@xTempBigInt AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte nach loeschen' from dbo.usr_IOBroker_Werte if @Debug>2 BEGIN select FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(UnixTime),'yy-MM-dd HH:mm:ss') as ts_lesbar_UTC, * from usr_IOBroker_Werte where UnixTime/1000>=@xTempBigInt AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END END END -- schauen wir mal ob IOBorker_Werte mnoch leer ist if (NOT EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN -- IOBroker leer if @Debug>0 select 'der Neueste Wert in der Tabelle usc_IOBroker_Werte ist NULL, daher jetzt mal den ältesten Wert in ts_number suchen' set @xOldest_tsNumber=(select dbo.fn_Convert_UNIX_2_DateTime(min(ts)) from ts_number); if @Debug>0 select @xOldest_tsNumber as 'Wir nehmen als Startwert den Wert von in ts_number:' SET @xStartDate= @xOldest_tsNumber -- als EndeDatum setzen wir Startdatum plus die Anzahl der Tage die kopiert werden dürfen laut Übergabe SET @xEndDate=dateadd(day,@MaxDays, @xStartDate) if @Debug>0 select (@MaxDays) as 'Anzahl der Tage die kopiert werden sollen:' END ELSE BEGIN -- Werte in IOBroker vorhanden if @Debug>0 select @MaxDays as 'MaxDays:' -- ermitteln wir wieviele Werte in der Tabelle stehen set @OldValuesCountBeforeDelete=(select count(*) from dbo.usr_IOBroker_Werte) -- wir leoschen mal den letzte Stunde in der IOBorkerWerte Tabelle, der sollte meist nur angefangen sein und keine volle Stunde beinhalten select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte if @Debug>0 select @xNewest_IOWerte as '@xNewest_IOWerte=' if @Debug>0 select dateadd(hour, -1,GETUTCDATE()) as 'dateadd(hour, -1,GETUTCDATE())=' if @xNewest_IOWerte>=dateadd(hour, -1,GETUTCDATE()) begin if @Debug>0 BEGIN select 'wir loeschenletzte stunde, das wären dann:' SELECT dateadd(SECOND,UnixTime/1000, '01.01.1970 00:00:00.0'),* from usr_IOBroker_Werte where UnixTime/1000>DATEDIFF(SECOND,'01.01.1970 00:00:00.0',Dateadd(hour,-1,@xNewest_IOWerte)) AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END DELETE from usr_IOBroker_Werte where UnixTime/1000>DATEDIFF(SECOND,'01.01.1970 00:00:00.0',Dateadd(hour,-1,@xNewest_IOWerte)) AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END select @xNewest_IOWerte=dbo.fn_Convert_UNIX_2_DateTime(max(min_ts)) from usr_IOBroker_Werte if @Debug>0 select @xNewest_IOWerte as 'usr_IOBroker_Werte vorhanden, hier ist der neueste Wert min_ts:' set @xNewest_IOWerte_AddDays=dateadd(day,@MaxDays,@xNewest_IOWerte) if @Debug>0 select @xNewest_IOWerte_AddDays as 'neuester Wert von usr_IOBroker_Werte + MaxDays:' select @xOldest_ref=dbo.fn_Convert_DateTime_2_ts_sec(@xNewest_IOWerte_AddDays) if @Debug>0 select @xOldest_ref as '@xOldest_ref:' select @xOldest_tsNumber=ISNULL((select dbo.fn_Convert_UNIX_2_DateTime(min(ts)) from ts_number where ts/1000>@xOldest_ref),GETUTCDATE()) if @Debug>0 select @xOldest_tsNumber as 'Der älterste Wert von ts_number der größer ist als der neuste IOBroker_Wert Eintrag + MaxDays:' SET @xStartDate=dateadd(day,-1, @xNewest_IOWerte) SET @xEndDate=@xOldest_tsNumber END -- falls Start und Ende übergeben, dann machen wir nur das if @StartDate<>'' BEGIn if @Debug>0 select 'Start und Ende übergeben, Abfrage auf diese Werte begrenzen' SET @xStartDate=@StartDate SET @xEndDate=@EndDate END /* --- schauen wir mal welche number_ts das betrift if (@Debug>0) BEGIN select dbo.fn_Convert_ts_sec2DateTime(ts/1000), * from ts_number where (ts/1000) >= @xStartDateUNIX and (ts/1000) < @xEndDateUNIX and id = (CASE WHEN @myId=0 THEN id ELSE @myId END) order by ts DESC END -- Welches Messwwerte schauen wir an? if (@Debug>0) BEGIN select 'ts_number, diese Werte schauen wir an' select ts as xts, dbo.fn_Convert_UNIX_2_UTC(ts) as ts_in_UTC, FORMAT(dateadd(s,ts/1000,'19700101'),'yy-MM-dd HH:mm:ss') as ts_in_Format_ohne_UTC, @xStartDate as xStartFilter_ts, dbo.fn_ConvertUTC2Local(@xStartDate) as xStartFilter_UTC, @xEndDate as xEndeFilter_ts, dbo.fn_ConvertUTC2Local(@xEndDate) as x@xEndeFilter_UTC, * from ts_number where id = @myId AND ts >= dbo.fn_ConvertUTC2IOBrokerTS(@xStartDate) AND ts < dbo.fn_ConvertUTC2IOBrokerTS(@xEndDate) order by ts DESC; END */ set @runtimestart=getUTCdate() set @CountAnzahl=0 while (@CountAnzahl=0 and datediff(SECOND,@runtimestart,getUTCdate())<30) begin if @Debug>0 select 'while schleife startr' if @Debug>0 select datediff(SECOND,@runtimestart,getUTCdate()) as 'laufzeit' -- wir loeschen mal die temporären Tabellen TRUNCATE TABLE #tempWERTE01 TRUNCATE TABLE #tempWERTE02 -- berechnen wir enddatum if @xEndDate>GETUTCDATE() BEGIN if @Debug>0 select 'Endedatum ist größer als aktuelles Datum, daher mal begrenzen auf aktuelles Datum!' set @xEndDate=GETUTCDATE() END if @Debug>0 select @xStartDate as 'Filter Startzeit' if @Debug>0 select @xEndDate as 'Filter Endezeit'; -- un nun Start un Ende als UNIXWert d.h. ohne UTC Verschiebung SET @xStartDateUNIX=[dbo].[fn_Convert_DateTime_2_ts_sec](@xStartDate) SET @xEndDateUNIX=[dbo].[fn_Convert_DateTime_2_ts_sec](@xEndDate) --select dbo.fn_Convert_ts_sec2DateTime(@xStartDateUNIX) as 'Filter @xStartDateUNIX', @xStartDateUNIX as 'as ts' --select dbo.fn_Convert_ts_sec2DateTime(@xEndDateUNIX) as 'Filter @xEndDateUNIX', @xEndDateUNIX as 'as ts' -- und nun mal versuchen die neue Tabelle zu füllen --- wir ermitteln damit nicht ein einfaches MIN oder MAX, das würde mit GROUP schon gehen, sondern -- holen uns den letzten Wert des Tages aus ts_number und speichern diesen -- es wird hier mit xRC doppelte Einträge in ts_number gefiltert, das kann z.B. passieren, wenn zur gleichen Zeit ein Wert vom Adapter kommt und der SQL Server einen Wert schreibt wenn er aufzeichnen soll alle x-sekunden if @Debug>0 select 'Alle Objekte: ermitteln wir mal die Werte im Intervall 1 h und kopieren diese in #tempWERTE01' insert into #tempWERTE01 ( xRowCount, xId, min_ts,max_ts, xUnixTime, xZaehler ) select * from ( SELECT ROW_NUMBER() OVER(PARTITION BY l.id,l.ts ORDER BY l.ts DESC) xRC, l.id as xId, m.min_ts as min_ts, m.max_ts as max_ts, l.ts as xUnixTime, l.val AS xZaehler FROM ts_number l INNER JOIN ( SELECT MAX(x.id) as xid, x.ts/1000/(60*60) as d, MIN(x.ts) as min_ts, MAX(x.ts) as max_ts FROM ts_number x Where x.id = (CASE WHEN @myId=0 THEN x.id ELSE @myId END) AND (x.ts/1000) >= @xStartDateUNIX --AND (x.ts/1000) >= datediff(s, '1970.01.01', @xStartDateUNIX) AND (x.ts/1000) < @xEndDateUNIX GROUP BY x.id, x.ts/1000/(60*60) -- 1 h ) m ON ( l.id=m.xid AND l.ts = m.max_ts ) WHERE ---shere bezeiht sich auf den gesamten Join --xRC = 1 l.id = (CASE WHEN @myId=0 THEN l.id ELSE @myId END) And l.val IS NOT NULL And l.val>=0 And (l.ts/1000) >= @xStartDateUNIX and (l.ts/1000) < @xEndDateUNIX ) aa where aa.xRC=1 if (@Debug>0) BEGIN select 'temp01 Inhalt anzeigen' select xUnixTime as xxts, dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as ts_in_UTC, FORMAT(dateadd(s,xUnixTime/1000,'19700101'),'yy-MM-dd HH:mm:ss') as ts_in_Format_ohne_UTC, @xStartDate as xStartFilter_ts, dbo.fn_Convert_UTCDateTime_2_ts_sec(@xStartDate) as xStartFilter_UTC, @xEndDate as xEndeFilter_ts, dbo.fn_Convert_UTCDateTime_2_ts_sec(@xEndDate) as xEndeFilter_UTC, * from #tempWERTE01 order by xId ASC, xUnixTime DESC; END /* if (@Debug>0) BEGIN select 'temp01 vor dem Löschen doppelter Werte' SELECT COUNT(*) from #tempWERTE01; END -- wir loeschen einfach die doppelten werte, falls IOBroker mal zu einem Zeitpunkt sowohl den Messwerte bekommt -- als auch den eingestellten Wert der Aufgezeichnet werden soll im Intervall -- damit verhindern wir beim Insert eine Schlüsselverletzung WITH cte AS ( SELECT xId, xUnixTime, ROW_NUMBER() OVER ( PARTITION BY xId, xUnixTime ORDER BY xId, xUnixTime ) row_num FROM #tempWERTE01 ) DELETE FROM cte WHERE row_num > 1; select 'temp01 NACH dem Löschen doppelter Werte' select * from #tempWERTE01; */ -- und nun mal mit der internen SQL Funktion lag - die Differenz zum vorherigen Wert ermitteln --select 'und nun die Differenz immer zum letzten Wert:' insert into #tempWERTE02 ( xId, min_ts,max_ts, xUnixTime, xZaehler,xDiff ) SELECT xId, min_ts,max_ts, xUnixTime, xZaehler, round((xZaehler-lag(xZaehler) over (partition by xid order by (xUnixTime/1000/(60*60)))),3) -- 1 h --(xZaehler-lag(xZaehler) over (partition by xid order by FORMAT(dbo.fn_Convert_UNIX_2_UTC(xUnixTime),'yy-MM-dd HH'))) FROM #tempWERTE01 ; -- Werte anzeigen if (@Debug>0) BEGIN select 'Inhalt #tempWerte02 anzeigen:'; --set rowcount @MaxCount; Select dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as xUnixTimeUTC, * from #tempWERTE02 order by xId ASC, xUnixTime DESC END; -- unsinnige Werte anzeigen if (@Debug>0) BEGIN select 'Unsinnige Inhalt #tempWerte02 anzeigen:'; Select dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as xUnixTimeUTC, * from #tempWERTE02 where xDiff<0 OR xDiff>(xzaehler*1.5) order by xId ASC, xUnixTime DESC END; -- Sprünge die keinen Sinn machen löschen delete from #tempWERTE02 where xDiff<0 OR xDiff>(xzaehler*1.5); /* -- versuchen wir mal einen totalen Zaehler zu bauen --select 'und nun ergänzen wir einen totalen neuen laufenden Zähler:' select *, sum(xDiff) over(order by xDay rows unbounded preceding) as xSumTotal, (select name from datapoints where id=rr.xid) as xObject FROM tempWERTE02 rr; */ -- wieviele Werte wären neu? with xAnzahl as ( SELECT DISTINCT s.xId, s.min_ts, s.max_ts, s.xUnixTime, s.xZaehler, s.xDiff from #tempWERTE02 s WHERE NOT EXISTS (SELECT * FROM dbo.usr_IOBroker_Werte t WHERE t.id = s.xId --AND t.UnixTime = s.xUnixTime and t.min_ts = s.min_ts --- hier mal schauen ob der Startwert schon vorhanden ist --and s.xUnixTime IS NOT NULL ) ) select @CountAnzahl=count(*) from xAnzahl --select @CountAnzahl=0 if @Debug>0 select @CountAnzahl as 'Anzahl der kopierenden werte' if (@CountAnzahl=0) begin set @xEndDate=dateadd(day,@MaxDays,@xEndDate); if @Debug>0 select @xEndDate as 'keine werte erkannt und kopiert, enddate erhöhen!' end else begin break end if @xEndDate>GETUTCDATE() BEGIN if @Debug>0 select 'Endedatum ist größer als aktuelles Datum, daher mal begrenzen auf aktuelles Datum!' break END if @EndDate<>'' begin if @xEndDate>@EndDate BEGIN if @Debug>0 select 'Endedatum ist größer als @EndDate, wir stoppen die Schleife!' break END END End; -- ####### WHILE set @OldValuesCount=(select count(*) from dbo.usr_IOBroker_Werte) if (@RunWithoutCopy=0) BEGIN if @Debug>0 select 'Funktion mit RunWithoutCopy=0 gestartet d.h. es werden neue Werte kopiert!' -- Werte in die echte neue Tabelle übernehmen --select 'und nun die Werte in die neue Tabelle kopieren:' set @CurrentTime = DATEDIFF(SECOND,'01.01.1970',getUTCDate()) if @Debug>0 select @CurrentTime as '@CurrentTime=' INSERT INTO dbo.usr_IOBroker_Werte ( id, create_ts, min_ts, max_ts, UnixTime, [DateTime], Zaehler, Diff ) SELECT DISTINCT s.xId, @CurrentTime, s.min_ts, s.max_ts, s.xUnixTime, dbo.fn_Convert_UNIX_2_UTCDateTime(s.xUnixTime), s.xZaehler, s.xDiff from #tempWERTE02 s WHERE NOT EXISTS (SELECT * FROM dbo.usr_IOBroker_Werte t WHERE t.id = s.xId AND ( t.UnixTime = s.xUnixTime or t.min_ts = s.min_ts ) --- hier mal schauen ob der Startwert schon vorhanden ist --and s.xUnixTime IS NOT NULL ); END ELSE BEGIN if @Debug>0 select 'Funktion mit RunWithoutCopy gestartet d.h. es werden keine neuen Werte kopiert' END set @NewValuesCount = (select count(*) from dbo.usr_IOBroker_Werte) select @xStartDate as 'Startzeit', @xEndDate as 'Endezeit', (@NewValuesCount-@OldValuesCount) as 'Created', (@NewValuesCount-@OldValuesCountBeforeDelete) as 'New', @NewValuesCount as 'WerteIOBrokerTable' if (@Debug>=2) BEGIN select 'alle werte in IOBroker_Werte anzeigen' SELECT TOP 1000 dbo.fn_Convert_ts_sec_2_UTCDateTime(create_ts) as create_ts_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(UnixTime),'yy-MM-dd HH:mm:ss') as ts_lesbar_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(max_ts),'yy-MM-dd HH:mm:ss') as xMax_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(min_ts),'yy-MM-dd HH:mm:ss') as xMin_UTC, * from usr_IOBroker_Werte where Id = (CASE WHEN @myId=0 THEN Id ELSE @myId END) -- DEBUG order by UnixTime desc --select count(*) as 'Anzahl Werte in IOBroker_Werte' from dbo.usr_IOBroker_Werte END; -- wir loeschen nun alles temporäre drop table #tempWERTE01 drop table #tempWERTE02 COMMIT TRANSACTION END
  • JSON Datensätze verbinden

    4
    0 Votes
    4 Posts
    361 Views
    haus-automatisierungH
    @mctom Welche Rolle haben denn die beiden Datenpunkte? Wenn die Rolle Objekt oder Array ist, dann wird automatisch ein JSON.parse durchgeführt (das scheint bei 2023.04 zu klappen). Der zweite Wert liefert allerdings einen JSON-String zurück und kein Objekt/Array. Dadurch wird alles escaped und landet als String im Array. Also: Rollen der Datenpunkte kontrollieren und ggf. korrigieren Je nach Rolle ist ggf. ein JSON.parse() nach dem Lesen nötig Dein Problem ist aktuell, dass in den Datenpunkten schon jeweils ein Array mit nur einem Eintrag zurückkommt. Also [ { ... } ] Daher müsstest Du mit concat arbeiten, um die Array zu verbinden. Oder dafür sorgen, dass in den anderen Datenpunkten nur ein Objekt steht (wozu das Array?). Idealerweise: Stellst Du die Quell-Datenpunkte auf die Rolle object Sorgst dafür, dass nur ein Objekt als Wert enthalten ist. Also keine eckigen Klammern irgendwo Arbeitest dann mit deinem bisherigen Code
  • Objektbaum parsen

    3
    0 Votes
    3 Posts
    260 Views
    OliverIOO
    @warhammer73 der js-controller besitzt die Funktion getForeignStates (in verschiedenen Ausprägungen, welche aber im javascript-adapter nicht bereitgestellt wurde (könnte man aber, warum auch immer man diese ausgelassen hat, Performance?) https://github.com/ioBroker/ioBroker.js-controller/blob/851d3cfa4fed442b25db63e3455b29f5081e45b6/packages/adapter/src/lib/adapter/adapter.ts#L9180 Wenn du einen eigenen Adapter erstellts, hast du über das Adapter-Objekt Zugriff auf diesen Befehl. Für deinen Anwendungsfall dürfte wahrscheinlich das folgende der bessere Weg sein. Du installierst dir den Adapter SimpleAPI und kannst dann über den Request Alle Objekte https://github.com/ioBroker/ioBroker.simple-api#objects-1 oder nach Suchmuster https://github.com/ioBroker/ioBroker.simple-api#objects abrufen und dann bekommst du die Daten als JSON zurück. Nachtrag: gibt auch noch den Befehl https://github.com/ioBroker/ioBroker.simple-api#states-1
  • (gelöst) Datenpunkt aus MS SQL Datenbank ->undefined

    communication javascript
    4
    0 Votes
    4 Posts
    189 Views
    H
    Erstmal vielen Dank für die schnelle Rückmeldung! @ticaki da bringt er "javascript.0 (12764) script.js.Daten_aus_MS_Datenbank_einlesen: {"error":null,"result":[{"channel1":20}]}" Leute, ihr seid der Hammer! Kann ja keiner ahnen, dass ich statt "value" "channel1" schreiben muss. Hab das ersetzt und es klappt!! @haus-automatisierung Ohne Klammer klappt es genauso wie mit Klammer. Scheint egal zu sein. Ich bin so froh ...war schon am verzweifeln. Danke an euch.
  • HomeMatic IP Sirene (HmIP-ASIR) auf laut oder still ändern

    4
    1
    0 Votes
    4 Posts
    617 Views
    O
    @b-s Er nutzt einen Access Point und keine CCU.
  • hping 3

    3
    0 Votes
    3 Posts
    255 Views
    OliverIOO
    @roelli Ja das ist ein Shell Skript. Es müsste 2!Threads dazu geben. In einem wo das entwickelt und verbessert wurde Und in einem anderen besser zusammengefasst.
  • Adapter-Einstellungen zur Laufzeit verändern

    14
    0 Votes
    14 Posts
    1k Views
    H
    @paul53 : Das war es gewesen....jetzt funzt es! Vielen Dank Paul53!
  • WebSocket Client in einem Skript verwenden?

    13
    0 Votes
    13 Posts
    1k Views
    W
    Ich habe nun eine OBS Websocket Implementation gefunden, welche man in iobroker nutzen kann. Ich habe das Modul nun einfach wie im Screenshot von @DJMarc75 gezeigt hinzugefügt und man kann anfangen. Damit kann man sogar auf Events, wie zum Beispiel Szenenwechsel, reagieren. Vielen Dank euch. :-)
  • assigning a string / which expects a number

    3
    0 Votes
    3 Posts
    475 Views
    D
    @paul53 WOW Danke, so schnell hätte ich nicht mit einer Antwort gerechnet. Funktioniert, besten Dank!
  • [gelöst] 1. Schritte mit Javascript: Prob mit setInterval?

    10
    1
    0 Votes
    10 Posts
    548 Views
    paul53P
    @paul53 sagte: Daher benutze let wenns nicht global sein soll Das trifft auf Verbundanweisungen zu - nicht auf Funktionen: var a = 1; let b = 2; if(true) { var a = 3; let b = 4; } log(a); // 3 log(b); // 2
  • Batterien überwachen

    5
    0 Votes
    5 Posts
    380 Views
    GlasfaserG
    @warhammer73 sagte in Batterien überwachen: Scheint aber mit meinen Bosch Geräten nicht klarzukommen. War die Frage jetzt nur für Boschgeräte Deine Anfrage war : Thread Titel : Batterien überwachen Und der Inhalt ohne weiter Technische angaben zu , zb. Zigbee , Homematic usw. unkompliziert die Batterien aus Geräten wie Thermostaten, Thermomentern... ausgelesen bekommt ohne das alles händisch parametriert werden muss? deshalb meine Links dazu , mehr kann ich nicht in meiner Glaskugel erkennen ....
  • deutsche Wettervorhersage mit DWD API-Services

    6
    0 Votes
    6 Posts
    1k Views
    T
    @jolic sagte in deutsche Wettervorhersage mit DWD API-Services: In Anbetracht dieser Umstände erscheint es sinnvoll, eine eigene Mini-Wetterstation zu verwenden, um aktuelle Messdaten zu erhalten. Bei diesen Stationen kannst du die Daten auch teilen und bekommst dafür Daten von anderen Hobby Stationen.

623

Online

32.6k

Users

82.2k

Topics

1.3m

Posts