gemu2015 / Sonoff-Tasmota

Tasmota Fork TCS34725,PN532_i2,ccc1101 Moritz support,m5stack 4,7 epaper, hotplug drivers
GNU General Public License v3.0
24 stars 19 forks source link

Scripting radians function #45

Closed pkkrusty closed 1 year ago

pkkrusty commented 1 year ago

Have you looked for this feature in other issues and in the docs?
Yes Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Would like radians function to convert degrees to radians. Not a hard equation (r=d*3.1415916535/180), but fills out functionality of #define USE_ANGLE_FUNC Describe the solution you'd like
A clear and concise description of what you want to happen. rad() in #define USE_ANGLE_FUNC Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered. Doing it manually works... Additional context
Add any other context or screenshots about the feature request here.

(Please, remember to close the issue when the problem has been addressed)

pkkrusty commented 1 year ago

Also, I can override max string size with >D 48 or >D 32, etc, but is 48 the hard upper limit? Can I #define SCRIPT_MAXSSIZE up to an arbitrary size? Any idea what that size limit would be for ESP8266 and ESP32?

gemu2015 commented 1 year ago

radiant done, (see my fork)

the string upper limit is hardcoded in

define SCRIPT_MAXSSIZE 48

defaults to 48

since we have no dynamic strings (to avoid garbage collection) we allocate all strings defined with this size. so you will use e.g. 480 Bytes RAM when using 10 string variables.

so when you want very large strings, use as few as possible.

on an esp8266 we are very limited with ram.

best system is an esp32 with PSRAM. here everything is in PSRAM, so no more memory problems. (ESP32-S3 ist currently the best CPU at all, i use ESP32-S3 WROOM 16R8 for all my new projects. (8 Euros))

pkkrusty commented 1 year ago

Question about s() command: If I have a number, for example, num=180.4566, and I do string=s(2.3num), will I still get all 3 digits before the decimal, or will it get truncated? I ask because I have a number that can be xx.xxx or xxx.xxx, and I'd like to avoid leading zeros in my file write (it looks nicer).

Question 2: Can you implement a round() function? Like rd(num x) where x is -y to y, so -2 would round to 100s, 0 to whole integer, 1 to one decimal place.

Question 3: Is there a way to convert directly from string to decimal number? I'd like to read a decimal number from a file and then do math on it, but the solution I found was to encode via hx(num), then write that string to the file, then read it, then convert it back to decimal with hd(str).

Question 4: Regarding files and file systems. I am using a FAT32 formatted SD Card, and #define USE_UFILESYS. I can do fr=fo("fname" m) with internal flash memory, but with my current script on SD Card, I have to use fr=fo("/fname" m). I added that note to documentation, but not sure if there's a more technical explanation that needs to be included.

Also, thanks for all your work on scripting. Very nice solution for folks who don't want to dive into Berry just yet.

gemu2015 commented 1 year ago
  1. yes you will get all digits before decimal point
  2. i don't get it well, probably give more examples. is it something like the map() function ?
  3. did you try to write and read arrays. arrays are written as number strings. fwa()
  4. currently the scripting file system only acts on the superior file system. if you have only flash, Flash file system is used, if you have an SD card, SD card is used. up to now i did not have the need to read or save on flash while SD card is present. in both cases the '/' delimiter is needed.

according to storing data on SD card i implemented a lot of helper functions. (see file extract USE_FEXTRACT) i store data on SD with tasmota for years now and my data sets got really large. so i had to implement extracting functions to retrieve e.g a certain day or week from the data set. such you can read data e.g. via WEB with GET request. http://"192.168.188.61:82/ufs/energy_15_log.txt@12.1.23_13.1.23" will show all data from 12.1.23 i meanwhile did put sample files in an extra folder in the scripteditor download where you can find how it is done.

pkkrusty commented 1 year ago
  1. Example:
    fullnum=12638.491
    res=rd(fullnum 2)

    would yield res=12638.49 res=rd(fullnum 1) would yield 12638.5 res=rd(fullnum 0) would yield 12638 res=rd(fullnum -1) would yield 12640 res=rd(fullnum -2) would yield 12600 res=rd(fullnum -3) would yield 13000

Maybe a word in german for rounding (runden?)

  1. I haven't tried that yet. Will try.
  2. In my scripting directly on flash memory, file operations are successful without the "/". I'll do some more testing.
gemu2015 commented 1 year ago

i meanwhile added: ceil floor round

you can mimic your desired function with these

what do you want to achieve? normally we want to have full accuracy with numbers.

number formatting is normally only used for printing, displaying numbers

pkkrusty commented 1 year ago

My specific case is writing a vehicle odometer to a file. My calculations happen in millimeters, but need to round to meters upon writing (so I can use hx(odometer) function. However, I can't use int() to force odometer into a whole number, because I need to capture partial meters to stay accurate, and over time, a round() function will do that.

Example:

I read odometer value 83463000 from file A at beginning of log session. If a valid movement happens (car moves 2.687 meters) I add that to the total. odometer=83463002.687 Write coordinates and odometer to array (but odometer must be in whole km) Subsequent movements are also logged into an array When vehicle speed drops below threshold or array is full, write array to file B and write odometer to file A in whole meters. Can't use int() because I lose partial meters. Half the time if I round up and half round down, it will average to correct odometer.