Page 2 of 3

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by cay
Tydligen hjälpte det med en boot. Nu blinkar det rött.

Följande skede är att få selflearning-signalen sänt. Har försökt med följande, konverterat direkt från "2B076D90" (tolkat som 32 bits)

Code: Select all


4:sendh1:S80:$k$k$k$k$k$k$k$k$kk$$k$k$k$k$kk$$kk$$k$k$kk$$kk$$k$k$kk$$kk$$k$k$kk$$kk$$kk$$k$k$k$k$k$k$k$k$k$k$kk$$kk$$k$k$kk$$k$k$kk$$k$k$k$ks

Ingen framgång med detta, trots att det blir skickat (blinkar rött). Måste forska vidare. Enligt createNexaString() i telldus/rfcmd/rfcmd.c kommer det på slutet ännu "$}+".

Lösningen border väl hittas i telldus-core/service/ProtocolNexa.cpp ProtocolNexa::getStringSelflearningForCode, där förekommer inget om $ och k, kanske den konverteringen görs på annat ställe.

Så gjorde jag konverteringen:

Code: Select all


perl -e '$bits = reverse unpack("B*", pack("N", 0x2B076D90)); print "bits: $bits\n"; $bits =~ s/1/\$kk\$/g; $bits =~ s/0/\$k\$k/g; printf "4sendh1:S%X:%ss\n", 
length($bits), $bits;'
bits: 00001001101101101110000011010100
4:sendh1:S80:$k$k$k$k$k$k$k$k$kk$$k$k$k$k$kk$$kk$$k$k$kk$$kk$$k$k$kk$$kk$$k$k$kk$$kk$$kk$$k$k$k$k$k$k$k$k$k$k$kk$$kk$$k$k$kk$$k$k$kk$$k$k$k$ks

Litet oklart vilken signal man skall använda, då det kommer både arctech och everflourish från fjärrkontrollen...

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Köttet på grillen!

F1 ON
blir efter att jag kollat filen från Micke:
$kk$$k$k$kk$$k$k$k$k$k$k$k$k$k$k$k$k$kk$$kk$$kk$$k+
och är 51 tecken.

Släcker jag från den andra maskinen med gamla stickan blinkar net blå.
Men sedan kan jag inte tända igen, mycket märkligt!

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Det är troligen raden:

Code: Select all

UDPSock.sendto("B:reglistener", (ip,42314))
som ställer till det, ändrade den till

Code: Select all

UDPSock.sendto("11:reglistener", (ip,42314))
Nä! funkar inte heller!

Då är frågan om den tappar den registrerade lyssnaren vid omstart?
Men jag testade följande:
Köra reglistener i ett skript och skickandet i ett annat, och då verkar det funka!!
Kan det vara så att det behövs en delay efter det att reglistener har skickats innan man kan skicka send?
Eller måste man ta ner socketen och skapa en ny efteråt för att kunna skicka?

Måste hacka ihop något i C, då jag behärskar detta bättre än python !

Slurpa i den sista skvätten maltdryck och nanna kudden!
Edit: missade lite text...

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Argh, kunde inte låta bli...

La in en sleep(10) efter registreringen, funkar inte!
Ska testa att stänga och öppna socketen igen.

Då är frågan är det NET eller python...

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by cay
Litet mera forskning och testning resulterade i följande icke-fungerande exempel.
Timingen och sync-biten kan vara fel kodade. Jag hittar inte uppgifter om vilka tidsintervall som används i telldus-core.
Några tydliga fel?

Code: Select all

rawdata: 2B076D90 (00101011000001110110110110010000)

S                           sync (T 10T)
00101011000001110110110110  house 11279798
0                           group 0
1                           method, 1=on 0=off
0000                        unit 1
0                           packet always ends with 0

Rawdata med sync-bit S och 0 i slutet:
S001010110000011101101101100100000

Utbyte av 0->01 och 1->10 resulterar i:
S010110011001101001010101011010100110100110100110100101100101010101

Tidskoder:
T   = 250us = \x19
5T  = 1250us = }
10T = 2500us = \xfa

1 = T T = "\x19\x19"
0 = T 5T = "\x19}"
S = T 10T = "\x19\xfa"

RF-signalen:
rf = "\x19\xfa\x19}\x19\x19\x19}\x19\x19\x19\x19\x19}\x19}\x19\x19\x19\x19\x19}\x19}
      \x19\x19\x19\x19\x19}\x19\x19\x19}\x19}\x19\x19\x19}\x19\x19\x19}\x19\x19\x19}
      \x19\x19\x19}\x19\x19\x19\x19\x19}\x19\x19\x19}\x19\x19\x19}\x19}\x19\x19\x19
      \x19\x19}\x19\x19\x19}\x19}\x19\x19\x19\x19\x19}\x19\x19\x19}\x19}\x19\x19\x19
      \x19\x19}\x19\x19\x19}\x19}\x19\x19\x19}\x19\x19\x19\x19\x19}\x19}\x19\x19\x19
      }\x19\x19\x19}\x19\x19\x19}\x19\x19\x19}\x19\x19"

UDP-paketet:
4:sendh1:S86:_rf_s

Funktionen ProtocolNexa::getStringSelflearningForCode verkar producera följande med samma uppgifter som i exemplet ovan:

Code: Select all


m = 01011001100110100101010101101010011010011010011010010110010101010
strMessage = \x9a\x8a\x88\xaa\x88\xaa\x88\xa8\xaa\x8a\x8a\x8a\x8a\x88\xa8\xa8\xaa\x88\xa8\xaa\x88\xa8\xaa\x88\xa8\xaa\x8a\x88\xaa\x8a\x8a\x8a\x8a\x2b

Helt annat resultat. Ingen aning vad {'T', 127, 255, 24, 1, 0} innebär... Något tellstick / tellstick duo relaterat kanske...

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by cay
Äntligen något som fungerar, kollade noggrannare på telldus live <-> tellstick net trafiken och följande fungerar. :)

Code: Select all

rf = "\x18\xff\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x18\x18" +\
     "\x7f\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x7f" +\
     "\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x18\x18\x7f\x18\x7f\x18\x18\x18" +\
     "\x7f\x18\x18\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x7f\x18\x18\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x7f" +\
     "\x18\x18\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x7f\x18\x18\x18\x18\x18\x7f\x18\x18\x18\x7f\x18\x18\x18" +\
     "\x7f\x18\x18\x18\x7f\x18"

msg = "4:sendh1:S%X:%ss" % (len(rf), rf)

Code: Select all

18 ff 18 18 18 7f 18 18 18 7f 18 7f 18 18 18 18 18 7f 18 7f 18 18 18 18 18 7f 18 7f 18 18 18 7f
S     1     0     1     0     0     1     1     0     0     1     1     0     0     1     0
-> 11010100

18 18 18 18 18 7f 18 18 18 7f 18 18 18 7f 18 18 18 7f 18 18 18 7f 18 7f 18 18 18 7f 18 18 18 7f
1     1     0     1     0     1     0     1     0     1     0     0     1     0     1     0
-> 11111000

18 18 18 18 18 7f 18 7f 18 18 18 7f 18 18 18 18 18 7f 18 7f 18 18 18 7f 18 18 18 18 18 7f 18 7f
1     1     0     0     1     0     1     1     0     0     1     0     1     1     0     0
-> 10010010

18 18 18 7f 18 18 18 18 18 7f 18 18 18 7f 18 7f 18 18 18 18 18 7f 18 18 18 7f 18 18 18 7f 18 18
1     0     1     1     0     1     0     0     1     1     0     1     0     1     0     1
-> 01101111

18 7f 18
0     P?

-> 11010100111110001001001001 1 0 1111
   00101011000001110110110110 0 1 0000  (min version, inverterad)
Tydligen var jag väldigt nära rätt resultat på basen av specifikationerna, någonstans nämndes att det möjligen skall vara tvärtom med 0 och 1.
Telldus använder tydligen: T=240us 5T=1270us 10T=2500us. Sista byten 18 är litet underlig.. Pause?


T.ex. så kan man generera rf-koden direkt från rawdata:

Code: Select all


perl -le '$s="\\x18";$l="\\x7f";$_=unpack"B*",pack"H*",pop;s/./$&?"$s$l$s$s":"$s$s$s$l"/ge;print"$s\\xff$_$s"' 2B076D90


Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Men att skicka self-learning, är det inte bara att göra som i python exemplet?

Code: Select all

msg = "4:sendh8:protocol%X:%s5:model%X:%s5:housei%Xs4:uniti%Xs6:methodi%Xss" % (len(protocol), protocol, len(model), model, house, unit, method)
Stoppa in rätt (dina) värden och skicka strängen? Den är ju färdig!
Eller är jag för nyvaken?

Jag håller på med codeswitch, då self-learning exempel redan finns?

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Testade med att efter "reglistener" stänga socketen pausa, öppna den igen, NÄ!

Fast när Net har tagit emot en signal skickas denna till server, där jag aldrig läser den!
Kan det vara problemet månne, en socket som jag tar emot med och en annan som skickar datat?

Nu är det slut på kodar-friden, lillan vaknar!

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by cay
Gohper wrote:Men att skicka self-learning, är det inte bara att göra som i python exemplet?

Code: Select all

msg = "4:sendh8:protocol%X:%s5:model%X:%s5:housei%Xs4:uniti%Xs6:methodi%Xss" % (len(protocol), protocol, len(model), model, house, unit, method)
Stoppa in rätt (dina) värden och skicka strängen? Den är ju färdig!
Eller är jag för nyvaken?

Jag håller på med codeswitch, då self-learning exempel redan finns?
Det exemplet utgick jag ifrån allra först, men det fungerade inte. Och då det diskuterades här om formatet med $k$kk$... så antog jag att den enkla metoden är
något som kanske fungerat i nån äldre firmware, eller så har det varit planerat men aldrig blivit implementerat i NET?
Säg till om det fungerar för dig. Flera timmars arbete i onödan om det trots allt fungerar... Men jag har väl lärt mig något nytt. :)

Har du testat utan reglistener? Själv kör jag så och ingen omstart har behövts, förutom den ena gången. Alltså endast autodiscovery, och därefter "4:send...".

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by micke.prag
cay wrote:Ingen aning vad {'T', 127, 255, 24, 1, 0} innebär...
Läs under "T - Send command, extended".
http://developer.telldus.com/doxygen/TellStick.html

Dock är detta inte implementerat i TellStick Net. Från http://developer.telldus.com/doxygen/TellStickNet.html:
The command "Send extended" (T) is not implemented since a TellStick Net can handle packages over 255 pulses.
FYI, är är ett par bra att ha funktioner jag plockade från vårt arkiv. Kanske kan komma till nytta för er?

Generera codeswitch data (php):

Code: Select all

function getCodeSwitchTuple($intCode) {
  $strReturn = '';
  for( $i = 0; $i < 4; ++$i ) {
    if ($intCode & 1) { //Convert 1
      $strReturn .= '$kk$';
    } else { //Convert 0
      $strReturn .= '$k$k';
    }
    $intCode >>= 1;
  }
  return $strReturn;
}

// $house: 'A'-'P'
// $unit: 1-16
function getStringCodeSwitch($house, $unit, $method) {
  $strReturn = '';

  $house = $this->getStringParameter('house', 'A');
  $intHouse = ord(substr($house, 0, 1)) - ord('A');
  $strReturn .= $this->getCodeSwitchTuple($intHouse);
  $strReturn .= $this->getCodeSwitchTuple($unit-1);

  if ($method == TELLSTICK_TURNON) {
    $strReturn .= '$k$k$kk$$kk$$kk$$k';
  } else if ($method == TELLSTICK_TURNOFF) {
    $strReturn .= $this->getOffCode();
  } else {
    return '';
  }
  return $strReturn;
}
Generera selflearning data (php):

Code: Select all

function getStringSelflearningForCode($intHouse, $intCode, $method, $level) {
  $SHORT = chr(24);
  $LONG = chr(127);

  $ONE = $SHORT.$LONG.$SHORT.$SHORT;
  $ZERO = $SHORT.$SHORT.$SHORT.$LONG;

  $code = $SHORT.chr(255);

  for ($i = 25; $i >= 0; --$i) {
    $code .= ( $intHouse & 1 << $i ? $ONE : $ZERO);
  }
  $code .= $ZERO; //Group

  //On/off
  if ($method == TELLSTICK_DIM) {
    $code .= $SHORT.$SHORT.$SHORT.$SHORT;
  } else if ($method == TELLSTICK_TURNOFF) {
    $code .= $ZERO;
  } else if ($method == TELLSTICK_TURNON) {
    $code .= $ONE;
  } else if ($method == TELLSTICK_LEARN) {
    $code .= $ONE;
  } else {
    return '';
  }

  for ($i = 3; $i >= 0; --$i) {
    $code .= ( $intCode & 1 << $i ? $ONE : $ZERO);
  }

  if ($method == TELLSTICK_DIM) {
    $newLevel = $level/16;
    for ($i = 3; $i >= 0; --$i) {
      $code .= $newLevel & 1 << $i ? $ONE : $ZERO;
    }
  }
  $code .= $SHORT;
  return $code;
}
En klass för att konvertera till och från data till TellStick Net (python):

Code: Select all

class LiveMessageToken(object):
	TYPE_INVALID, TYPE_INT, TYPE_STRING, TYPE_BASE64, TYPE_LIST, TYPE_DICTIONARY = range(6)

	def __init__(self, value = None):
		self.valueType = LiveMessageToken.TYPE_INVALID
		self.stringVal = u''
		self.intVal = 0
		self.dictVal = {}
		self.listVal = []
		if (type(value) is int or type(value) is long):
			self.valueType = self.TYPE_INT
			self.intVal = value

		elif (type(value) is str or type(value) is unicode or type(value) == float):
			self.valueType = self.TYPE_STRING
			self.stringVal = value

		elif (type(value) is list):
			self.valueType = self.TYPE_LIST
			for v in value:
				self.listVal.append(LiveMessageToken(v))

		elif (type(value) is dict):
			self.valueType = self.TYPE_DICTIONARY
			for key in value:
				self.dictVal[key] = LiveMessageToken(value[key])

	def toInt(self):
		if self.valueType == LiveMessageToken.TYPE_INT:
			return self.intVal
		if self.valueType == LiveMessageToken.TYPE_STRING:
			return long(self.stringVal)
		return 0  # Could not convert

	def toJSON(self):
		if (self.valueType == LiveMessageToken.TYPE_INT):
			return '%d' % self.intVal

		if (self.valueType == LiveMessageToken.TYPE_LIST):
			retval = '['
			for token in self.listVal:
				if len(retval) > 1:
					retval = retval + ","
				retval = retval + token.toJSON()
			return retval + ']'

		if (self.valueType == LiveMessageToken.TYPE_DICTIONARY):
			retval = '{'
			for key in self.dictVal:
				if len(retval) > 1:
					retval = retval + ","
				retval = retval + LiveMessageToken(key).toJSON() + "=" + self.dictVal[key].toJSON()
			return retval + '}'

		return self.stringVal

	def toNative(self):
		if (self.valueType == LiveMessageToken.TYPE_INT):
			return self.intVal

		if (self.valueType == LiveMessageToken.TYPE_LIST):
			retval = []
			for token in self.listVal:
				retval.append(token.toNative())
			return retval

		if (self.valueType == LiveMessageToken.TYPE_DICTIONARY):
			retval = {}
			for key in self.dictVal:
				retval[key] = self.dictVal[key].toNative()
			return retval

		return self.stringVal

	def toByteArray(self):
		if (self.valueType == LiveMessageToken.TYPE_INT):
			return 'i%Xs' % self.intVal

		if (self.valueType == LiveMessageToken.TYPE_LIST):
			retval = 'l'
			for token in self.listVal:
				retval = retval + token.toByteArray()
			return retval + 's'

		if (self.valueType == LiveMessageToken.TYPE_DICTIONARY):
			retval = 'h'
			for key in self.dictVal:
				retval = retval + LiveMessageToken(key).toByteArray() + self.dictVal[key].toByteArray()
			return retval + 's'

		return '%X:%s' % (len(self.stringVal), str(self.stringVal),)

	@staticmethod
	def parseToken(string, start):
		token = LiveMessageToken()
		if (start >= len(string)):
			return (start, token)

		if (string[start] == 'i'):
			start+=1
			index = string.find('s', start)
			if (index < 0):
				return (start, token)

			try:
				token.intVal = int(string[start:index], 16)
				token.valueType = LiveMessageToken.TYPE_INT
				start = index + 1
			except:
				return (start, token)

		elif (string[start] == 'l'):
			start+=1
			token.valueType = LiveMessageToken.TYPE_LIST
			while (start < len(string) and string[start] != 's'):
				start, listToken = LiveMessageToken.parseToken(string, start)
				if (listToken.valueType == LiveMessageToken.TYPE_INVALID):
					break
				token.listVal.append(listToken)
			start+=1

		elif (string[start] == 'h'):
			start+=1
			token.valueType = LiveMessageToken.TYPE_DICTIONARY
			while (start < len(string) and string[start] != 's'):
				start, keyToken = LiveMessageToken.parseToken(string, start)
				if (keyToken.valueType == LiveMessageToken.TYPE_INVALID):
					break
				start, valueToken = LiveMessageToken.parseToken(string, start)
				if (valueToken.valueType == LiveMessageToken.TYPE_INVALID):
					break
				token.dictVal[keyToken.stringVal] = valueToken
			start+=1

		elif (string[start] == 'u'): #Base64
			start+=1
			start, token = LiveMessageToken.parseToken(string, start)
			token.valueType = LiveMessageToken.TYPE_BASE64
			token.stringVal = unicode(base64.decodestring(token.stringVal), 'utf-8')

		else: #String
			index = string.find(':', start)
			if (index < 0):
				return (start, token)

			try:
				length = int(string[start:index], 16)
			except:
				return (start, token)

			start = index + length + 1
			token.stringVal = string[index+1:start]
			token.valueType = LiveMessageToken.TYPE_STRING

		return (start, token)

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Gjorde bara en snabbtitt på kodsnuttarna, de verkar mycket intressanta, Vi bugar och bockar för dom!

Jag har inte hunnit att kika något närmare sedan i morse. Kanske blir det när mitt 2-åriga energi knippe nannat kudden.

@cay, exemplet verkar inte funka, fast NET:en blinkar vackert rött, men jag har för mig att det gjorde det. Det jag nu testade med var att lära en brytare, fast det är kanske lite annat.

@Micke
Jag kikade i koden för firmware och där ser det ut som om att Net kan en send för selflearning, utan att den görs på samma låga nivå som codeswitch.
Tänker på denna lilla snutt ur Tellsticknet.c

Code: Select all

if (LMFindHashString("protocol")) { 
77                 LMTakeString(&protocol, sizeof(protocol)); 
78  
79                 if (LMFindHashString("model")) { 
80                         LMTakeString(&model, sizeof(model)); 
81                 } 
82                 if (strcmp(protocol, "arctech") != 0 || strcmp(model, "selflearning") != 0) { 
83                         return; 
84                 } 
85                 sendArctechSelflearning(); 
86                 return; 
87         } 

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
@cay
Exempelskriptet fungerar med selflearning, Dock om man kikar i transmit_archtech.c så ser man föjande:

Code: Select all

       //On or Off 
82         if (method == 1) { 
83                 sendOne(); 
84         } else { 
85                 sendZero(); 
86         } 
87 
vilket innebär att method måste vara 1 vid inlärning och på! Annars vad som helst för av!

Tillägg:
Att exemplet inte funkar, eller om jag hade varit och juttlat i det beror på att method =2...

Alltså så länge man kör med Nexa självlärande så behöver man inte bry sig så mycket när det gäller att sända!

Däremot att ta emot samt att skicka andra protokoll kräver hackning!

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Knackat lite, men inte jättemycket.
"reglistener slutar sända"-problemet, kan vara i python. Ska försöka knåpa ihop ett c-program och se om det blir samma.
Fast det blir en annan dag, om jag nu kan låta bli. Måste sova oxå, och av pilsener och whiskey blir man lite pömsig!

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by micke.prag
Gohper wrote:Jag kikade i koden för firmware och där ser det ut som om att Net kan en send för selflearning, utan att den görs på samma låga nivå som codeswitch.
Det stämmer. Sedan v17 finns denna funktionen för att koda selflearning direkt på enheten.

Re: Ny med Net...

Posted: Fri Mar 17, 2023 9:45 am
by Gohper
Hittade att någon hade tolkat data från en Fine Offset väderstation, jag har en sådan och var tvungen att lyssna. Tyvärr verkar min gå på 800MHz...

Fast det datat får jag ändå!