Pysolar with Arch Site

A forum dedicated to the Draft, Arch and BIM workbenches development.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Pysolar with Arch Site

Postby vocx » Mon May 06, 2019 6:39 am

A couple of decades ago Yorik implemented support for displaying sun paths in Arch Site. To display the path, simply turn the view property Solar Diagram to true, and set an appropriate Solar Diagram Scale, for example, 10000.

The original announcement is in Solar diagrams.
Freecad-solar-diagram.jpg
Freecad-solar-diagram.jpg (79.55 KiB) Viewed 973 times
This uses Pysolar to calculate the altitude and azimuth angles of the sun at a given coordinate on Earth (latitude and longitude) over the entire year, and then FreeCAD draws the diagram.

However, at some point the sun diagram stopped working due to different reasons:
  • Pysolar changed name and was incorrectly imported in the code
  • Pysolar was updated to work only with Python 3, so it didn't work with FreeCAD versions compiled against Python 2
The relevant code is given in the following. https://github.com/FreeCAD/FreeCAD/blob ... ite.py#L79

This code tests whether the Pysolar module is available in Python 3; it uses subprocess.call() to externally call the python3 interpreter. If Python 3 is available it uses that, otherwise it tries to import Pysolar assuming Python 2. If Pysolar is not available at all, it just returns, and doesn't create anything.

Code: Select all

def makeSolarDiagram(longitude,latitude,scale=1,complete=False):
    from subprocess import call
    py3_failed = call(["python3", "-c", "import Pysolar"])

    if py3_failed:
        try:
            import Pysolar
        except:
            print("Pysolar is not installed. Unable to generate solar diagrams")
            return None
    else:
        from subprocess import check_output
Then later in the code, the solar angles are calculated. If Python 3 is available, it builds a string, and passes the string to subprocess.check_output() to again externally call Pysolar in Python 3. If Python 3 is not available, it assumes Python 2 and calls directly the functions from the Pysolar module.

Code: Select all

        for h in range(24):
            if not py3_failed:
                dt = "datetime.datetime(%s, %s, %s, %s)" % (year, d[0], d[1], h)
                alt_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_altitude_fast(%s, %s, %s))'" % (latitude, longitude, dt)
                alt = math.radians(float(check_output(alt_call, shell=True).strip()))
                az_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_azimuth(%s, %s, %s))'" % (latitude, longitude, dt)
                az = float(re.search('.+$', check_output(az_call, shell=True)).group(0))
            else:
                dt = datetime.datetime(year,d[0],d[1],h)
                alt = math.radians(Pysolar.solar.GetAltitudeFast(latitude,longitude,dt))
                az = Pysolar.solar.GetAzimuth(latitude,longitude,dt)
---------------------------

The proposed changes are as follows.

Just try to import Pysolar, which is now named all lowercase, pysolar.

Code: Select all

def makeSolarDiagram(longitude,latitude,scale=1,complete=False):
    try:
        import pysolar
    except:
        print("Pysolar is not installed. Unable to generate solar diagrams")
        return None
Now the calculation of the angles is done directly without externally using subprocess.check_output(). To obtain a date, the tzinfo= argument with a timezone is given, as required by recent versions of Pysolar (0.7 and above).

Code: Select all

        for h in range(24):
            dt = datetime.datetime(year, d[0], d[1], h, tzinfo=datetime.timezone.utc)
            alt = math.radians(pysolar.solar.get_altitude_fast(latitude, longitude, dt))
            az = pysolar.solar.get_azimuth(latitude, longitude, dt)
The previous changes assume FreeCAD compiled against Python 3, as Pysolar 0.7 and above only work with Python 3.

They were tested with this version

Code: Select all

OS: Ubuntu 18.04.2 LTS
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.1.
Build type: Release
Python version: 3.6.7
Qt version: 5.9.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/UnitedStates (en_US)
---------------------------
Further information.

The Pysolar developer decided to drop support for Python 2, and has made the software only compatible with Python 3. This happened in the transition from Pysolar 0.6 to 0.7. Also, the functions were renamed to comply with PEP8 (lowercase_with_underscores instead of camelCase).

In Debian/Ubuntu systems Pysolar can be installed from the repositories, but again, in recent times it's only available for Python 3.

Code: Select all

sudo apt install python3-pysolar
If, during the creation of the sun diagram, you get a warning like this

Code: Select all

solartime.py:107: UserWarning: I don't know about leap seconds after 2016
It probably means that you have a slightly older version of Pysolar, as the leap seconds are updated in each new version. For example, the most recent version in github is 0.8.x, while Ubuntu 18.04 has a 0.7.x version. In most cases the warning can be ignored as those missing seconds don't affect the position of the sun in the sky too much. That is, the sun diagram will be fine. You would only need those leap seconds if you were doing extremely precise astronomical calculations, but for that you'd probably use a different software. See Leap second issue!

-----------------------

If Arch wishes to keep supporting Pysolar with Python 2 then this could be implemented like the original code above, that is, test for the presence of the python2 interpreter, import Pysolar 0.6, and call the older functions. It should necessarily import version 0.6 as that is the last version supported by Python 2.

Code: Select all

        for h in range(24):
            if py3_available:
                dt = datetime.datetime(year, d[0], d[1], h, tzinfo=datetime.timezone.utc)
                alt = math.radians(pysolar.solar.get_altitude_fast(latitude, longitude, dt))
                az = pysolar.solar.get_azimuth(latitude, longitude, dt)
            elif py2_available:
                dt = "datetime.datetime(%s, %s, %s, %s)" % (year, d[0], d[1], h)
                alt_call = "python2 -c 'import datetime,Pysolar; print (Pysolar.solar.GetAltitudeFast(%s, %s, %s))'" % (latitude, longitude, dt)
                alt = math.radians(float(check_output(alt_call, shell=True).strip()))
                az_call = "python2 -c 'import datetime,Pysolar; print (Pysolar.solar.GetAzimuth(%s, %s, %s))'" % (latitude, longitude, dt)
                az = float(re.search('.+$', check_output(az_call, shell=True)).group(0))
Last edited by vocx on Sun May 26, 2019 5:18 pm, edited 1 time in total.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
yorik
Site Admin
Posts: 12034
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: Pysolar with Arch Site

Postby yorik » Wed May 08, 2019 12:08 am

Thanks for looking into this @vocx! I hadn't even noticed the diagram stopped working...

Your proposed changes look perfect. I think we can slowly stop supporting python2 modules that don't get updated to python3, so I wouldn't bother much with it. Anyway, the solar diagram is not usable anymore right now by py2 users...

Mind to make a pull request? If you prefer, I can also do the changes myself.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Pysolar with Arch Site

Postby vocx » Wed May 08, 2019 3:35 am

yorik wrote:
Wed May 08, 2019 12:08 am
...

Mind to make a pull request? If you prefer, I can also do the changes myself.
Please do it. I think it's too much trouble to submit a patch that is like 10 lines long.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
yorik
Site Admin
Posts: 12034
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: Pysolar with Arch Site

Postby yorik » Wed May 08, 2019 3:07 pm

User avatar
Kunda1
Posts: 8410
Joined: Thu Jan 05, 2017 9:03 pm

Re: Pysolar with Arch Site

Postby Kunda1 » Wed May 08, 2019 4:11 pm

yorik wrote:
Wed May 08, 2019 3:07 pm
Done with git commit 2177f4437
@yorik is there a way we can add a unit test to make sure this functionality doesn't break without us knowing it ?
Also 3 more questions:
1) what minimum version of pysolar do we need?
2) were is our dependency list so that we can add pysolar and the minimum version to it so users are informed of this functionality?
3) maybe we can have a startpage mention or a potential wizard that instructs people about pysolar ?
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
User avatar
yorik
Site Admin
Posts: 12034
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: Pysolar with Arch Site

Postby yorik » Wed May 08, 2019 4:48 pm

It will now just print a message if pysolar is not found, and continue gracefully (the diagram is just not shown) and I kept support of old py2 Pysolar too... So I think we should be good to go for everybody. But I'll look at the documentation if we need to change something
I don't think we really need to test for it, because we don't want the tests to fail because of this...
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Pysolar with Arch Site

Postby vocx » Wed May 08, 2019 5:11 pm

Kunda1 wrote:
Wed May 08, 2019 4:11 pm
@yorik is there a way we can add a unit test to make sure this functionality doesn't break without us knowing it ?
Also 3 more questions:
1) what minimum version of pysolar do we need?
2) were is our dependency list so that we can add pysolar and the minimum version to it so users are informed of this functionality?
3) maybe we can have a startpage mention or a potential wizard that instructs people about pysolar ?
1. The minimum version required is Pysolar 0.7; this one is found in Ubuntu 18.04, so at least LTS users will be set. I don't know about Ubuntu 16.04, though. However, this Pysolar 0.7 will only work with Python 3, it won't work with Python 2. If support for Python 2 is desired, the user has to have a version of Pysolar 0.6 in their system, as this is the last version that works with Python 2. Moreover, the functions of Pysolar 0.6 and 0.7 are named differently, so the Arch code has to handle both cases.

2. I don't think Pysolar needs to be added as a hard dependency to FreeCAD. The Arch code uses Pysolar in a very simple way. If Pysolar isn't found, the code simply omits creating the sun diagram but nothing else breaks.

3. Pysolar is already mentioned in the Arch Site documentation. The information has been there for a long time (2.5 years?), but it didn't work, and no user complained about it. This tells me Pysolar is probably only important to a very small set of users.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Pysolar with Arch Site

Postby vocx » Wed May 08, 2019 5:26 pm

yorik wrote:
Wed May 08, 2019 4:48 pm
It will now just print a message if pysolar is not found, and continue gracefully (the diagram is just not shown) and I kept support of old py2 Pysolar too... So I think we should be good to go for everybody. But I'll look at the documentation if we need to change something
I don't think we really need to test for it, because we don't want the tests to fail because of this...
The code won't work with Python 2. With Python 2 the user needs Pysolar 0.6, in which the calls are different.

Pysolar 0.7 and above (Python 3)

Code: Select all

dt = datetime.datetime(year, d[0], d[1], h, tzinfo=datetime.datetime.utc)
alt = math.radians(pysolar.solar.get_altitude_fast(latitude, longitude, dt))
az = pysolar.solar.get_azimuth(latitude, longitude, dt)
Pysolar 0.6 (Python 2)

Code: Select all

dt = datetime.datetime(year, d[0], d[1], h)
alt = math.radians(Pysolar.solar.GetAltitudeFast(latitude, longitude, dt))
az = pysolar.solar.GetAzimuth(latitude, longitude, dt)
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
Kunda1
Posts: 8410
Joined: Thu Jan 05, 2017 9:03 pm

Re: Pysolar with Arch Site

Postby Kunda1 » Wed May 08, 2019 6:46 pm

vocx wrote:
Wed May 08, 2019 5:11 pm
1. The minimum version required is Pysolar 0.7; this one is found in Ubuntu 18.04, so at least LTS users will be set. I don't know about Ubuntu 16.04, though. However, this Pysolar 0.7 will only work with Python 3, it won't work with Python 2. If support for Python 2 is desired, the user has to have a version of Pysolar 0.6 in their system, as this is the last version that works with Python 2. Moreover, the functions of Pysolar 0.6 and 0.7 are named differently, so the Arch code has to handle both cases.

2. I don't think Pysolar needs to be added as a hard dependency to FreeCAD. The Arch code uses Pysolar in a very simple way. If Pysolar isn't found, the code simply omits creating the sun diagram but nothing else breaks.

3. Pysolar is already mentioned in the Arch Site documentation. The information has been there for a long time (2.5 years?), but it didn't work, and no user complained about it. This tells me Pysolar is probably only important to a very small set of users.
Thanks for the heads up, @vocx.

I wonder how many people knew of this feature at all.
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
paullee
Posts: 2661
Joined: Wed May 04, 2016 3:58 pm

Re: Pysolar with Arch Site

Postby paullee » Wed May 08, 2019 10:57 pm

I tried long time ago but pysolar rpm is not available Fedora.